JavaScript 源型链

Posted wangyueming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 源型链相关的知识,希望对你有一定的参考价值。

技术分享图片

 

var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}(即构造器function A 的原型对象)
console.log(a.__proto__.__proto__); //Object {}(即构造器function Object 的原型对象)
console.log(a.__proto__.__proto__.__proto__); //null

技术分享图片

实例:

//构造方法,类,函数
            function Foo(name){
                this.name = name;
            }
            
            var f = new Foo("wang");
            
            //在Foo方法中添加属性
            Foo.prototype.sex = "女";
            Foo.prototype.show = function(){
                console.log("name="+this.name+";sex="+this.sex);
            }
            
            var f2 = new Foo("lacy");
            console.log(f.sex == f2.sex);
            f.show();
            f2.show();
            

结果:

技术分享图片

当查找一个对象的属性时,javascript会向上遍历源型链,到查找到达源型链的顶部(Object.prototype),直到找到给定名称的属性为止,如果还是没有找到就会返回undefined。

实例:

function Person(name, age){ 
    this.name = name; 
    this.age = age; 
  } 
Person.prototype.MaxNumber = 666;
Person.__proto__.MinNumber = -666;
var will = new Person("Will", 28); 
console.log(will.MaxNumber); // 666
console.log(will.MinNumber); // undefined

结果:

技术分享图片

在这个例子中分别给”Person.prototype “和” Person.proto”这两个原型对象添加了”MaxNumber “和”MinNumber”属性

“Person.prototype “对应的就是Person构造出来所有实例的原型,也就是说”Person.prototype “属于这些实例原型链的一部分,所以当这些实例进行属性查找时候,就会引用到”Person.prototype “中的属性。

 

  当一个函数被用作构造函数来创建实例时,该函数的prototype属性值将被作为原型赋值给所有对象实例(也就是设置实例的__proto__属性)

 

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>

    <body>
        <script type="text/javascript">
            //构造器,函数,对象
            function Cat(nickname, color) {
                //各个对象独有的
                this.nickname = nickname;
                this.color = color;
            }
            
            //所有对象公有的
            Cat.prototype.life = 9;
            Cat.prototype.bark = function() {
                console.log(this.nickname, this.color, this.life, "喵喵...");
            }

            var c1 = new Cat("波斯", "绿色");
            c1.bark();
            var c2 = new Cat("加菲", "红色");
            c2.bark();
        </script>
    </body>

</html>

控制台结果:

技术分享图片

关系图:

技术分享图片

 

  (1)、所有函数/构造器都拥有prototype属性,用于指向源型对象

(2)、所有的函数对象即是构造器又是对象

(3)、所有对象都拥有__proto__非标准属性。

(4)、所有函数(构造器)的__proto__都指向Function.prototype对象。

(5)、所有对象的__proto__指向它的构造器的prototype对象。

  (6)、所有函数都是由Function构造出来的,Function自己构造了自己,Object是由Function构造出来的,Function是构造器。

  (7)、所有对象的最终原型对象都指向了Object的prototype属性,Object的prototype对象的__proto__属性指向NULL。

  (8)、所有prototype原型对象中的constructor属性都指向其构造器。

  (9)、原型对象prototype中的成员是所有对象共有的。

  (10)、对象在查找成员时先找本对象自己的所有成员,再查找构造器的原型中的成员(向上再查找父类的成员,多步),最终查询Object的成员。

技术分享图片

JavaScript是一种通过原型实现继承的语言与别的高级语言是有区别的,像java,C#是通过类型决定继承关系的,JavaScript是的动态的弱类型语言,总之可以认为JavaScript中所有都是对象,在JavaScript中,原型也是一个对象,通过原型可以实现对象的属性继承JavaScript的对象中都包含了一个" prototype"内部属性,这个属性所对应的就是该对象的原型。

"prototype"作为对象的内部属性,是不能被直接访问的。所以为了方便查看一个对象的原型,Firefox和Chrome内核的JavaScript引擎中提供了"__proto__"这个非标准的访问器(ECMA新标准中引入了标准对象原型访问器"Object.getPrototype(object)")。

 

以上是关于JavaScript 源型链的主要内容,如果未能解决你的问题,请参考以下文章

C语言 泛型链表的实现

VSCode自定义代码片段12——JavaScript的Promise对象

VSCode自定义代码片段12——JavaScript的Promise对象

30秒就能看懂的JavaScript 代码片段

常用Javascript代码片段集锦

48个值得掌握的JavaScript代码片段(上)