美文网首页
什么是原型链

什么是原型链

作者: 天马行空_eaa7 | 来源:发表于2021-05-24 00:05 被阅读0次

    1.对prototype的理解

    function F(){};

    f1=new F();

    f2=new F();

    以上的代码,F()是一个构造函数,f1和f2是有这个构造函数产生的实例对象。</pre>

    prototype是构造函数的一个属性,他的值就是由这个构造函数构造出来的对象 (如f1和f2) 的原型对象.(换句话说,prototype既是构造函数的属性,也是f1,f2的原型对象)。f1._ proto _= F.prototype

    构建对象中有一种模式叫做原型模式,意思是将对象实例所不可共享的属性及方法定义在构造函数中,而将可共享的属性及方法放在原型对象中,也就是prototype指向的对象中。p1和p2对象实例的内存空间里面各有一份name和age,但是它们却共享一份sayName方法,意思是它们调用的sayName方法是同一个。所以prototype的好处之一就是提高了代码的复用性,减少内存消耗。

    在了解原型对象的同时我们还有一个小知识要明白:

    每当代码读取一个对象属性的时候会执行一次搜索,搜索目标是给定名字的属性,搜索路径为:

    对象实例本身---->原型对象---->对象的父类对象---->父类对象原型...---->原型链末端

    2.prototype的注意点

    • 不可变性

      尽管prototype是共享的,但不能通过对象实例重写原型中的值,但是可以由对象统一改。通俗一点:只能爸爸统一改,不能儿子改。(这也和类型有关系,孩子不能改变基本类型的值,但是可以改变对象,比如改变数组内容)

      • 基本类型

        function person(){

        Person.prototype={ num:0}

        }

        var p1=new Person();

        var p2=new Person();

        P1.num++;

        p2.num // 0 (对象实例不能改变基本类型)

      • 非基本类型

        Function person(){

        Person.prototype={ num:[1,2,3] };

        }
        var p1=new person();

        var p2=new person();

        P1.num[2]=8;

        P2.num // [1,2,8] (对象实例不能改变基本类型)

    • 同名覆盖性

      如果我们在实例中添加了一个与原型属性同名的属性,那么该属性会创建到对象实例中并且会覆盖掉原型中的相应属性。</pre>

    • 使用对象字面量创建原型方法,会切断之前的链而重写原型链

    总结:
    • prototype的用法:构造函数模型用于定义实例的属性,二原型模型用于定义方法和共享属性(在ES5中是这样,在ES6中有class关键字代替)

    3.prototype和 _ proto _的区别

    __ proto __ 是某个实例对象的属性,它指向这个对象的原型对象。而prototype则是构造函数的属性。从上面的例子分析,f1. __ proto 和f2. _ proto__就等同于F.prototype。

    图片1.png

    4.原型链

    每个对象都有自己的原型对象,那一层层地,就形成了原型链。原型链的最上端,就是Object.prototype(注意这里的Object是一个构造函数啊),它没有原型对象(为null)。原型链后面的对象,能够使用前面的属性和方法(假如没有覆盖掉的话)。因此,有着相同原型对象的两个对象,就可以使用与原型对象相同的方法和属性了,这也是使用prototype的好处了。

    5.constructor

    prototype对象有一个constructor属性,F.prototype.constructor的值就是F本身。用文字描述,一个函数对象的原型对象的constructor属性指向这个函数本身。(ES6中class的constructor可能就是这样封装的)</pre>

    利用这一点,我们可以进行判断一个对象是否由某个构造函数产生的。(利用这个例子来理解constructor属性吧)

    function A(){};
    var a = new A();
    console.log(a.constructor===A) //true

    分析一下以上的代码,a原本是没有constructor这个属性的,但是它的原型对象有,所以它“继承”了下来,自己也能使用这个属性。即a.constructor,其实也等于a.proto.constructor和A.prototype.constructor,而A.prototype.constructor的值,就是A(同理,A.constructor=A.proto.constructer=Object.prototype.constructor=Object本身,即 方法A的构造函数是Object),因此返回true了。

    关于constructor的作用还有很多,这里不详述了

    5.prototype的作用

    定义在原型对象上的所有属性和方法,都能被派生对象继承。这就是JavaScript继承机制的基本设计。prototype对象的作用,就是定义所有实例对象共享的属性和方法,所以它也被称为实例对象的原型,而实例对象可以视作从prototype对象衍生出来的。

    相关文章

      网友评论

          本文标题:什么是原型链

          本文链接:https://www.haomeiwen.com/subject/bgfzjltx.html