JS中__proto__和prototype

參考http://www.itdecent.cn/p/dee9f8b14771
js萬(wàn)物皆對(duì)象, 對(duì)象包括普通對(duì)象和函數(shù)對(duì)象(構(gòu)造器對(duì)象)

  • 1 構(gòu)造器對(duì)象也就是函數(shù)對(duì)象, 如
    var Person = function(){}
    //生成方式
    Person在生成時(shí), 會(huì)隱式使用如下方式
    new Function('person', 'function(){}')
    生成, 而Function.prototype會(huì)將自己引用到Person.__proto__上, 
    so
        Person.__proto__ === Function.prototype

包括其他如Object, Array, 只要是函數(shù)對(duì)象, 它們的 __ proto __ 都是Function.prototype

        console.log(Object.__proto__ === Function.prototype);
        console.log(Function.__proto__ === Function.prototype);
        //Function.prototype = new Function();
        console.log(typeof Function.prototype);//funciton
        //Array.prototype = new Object();普通對(duì)象
        console.log(typeof Array.prototype);//object;
        通過(guò)在Array.prototype這個(gè)普通對(duì)象上定義各種方法, 如map reduce sort等

        由此可以看出Function.prototype是Function, 
        其他的都是object, 
        所以可以看做是一個(gè)普通的object對(duì)象
  • 2 普通對(duì)象是通過(guò)函數(shù)對(duì)象new出來(lái)的, 然后在將函數(shù)對(duì)象(構(gòu)造器)的prototype屬性(就是一個(gè)普通對(duì)象)賦給普通對(duì)象的__ proto __, 這樣普通對(duì)象就可以調(diào)用構(gòu)造器prototype上的所有方法, 如:
        var Person = function(name){
            this.name = name;
        }
        //如果不定義他的原型, 默認(rèn)只是一個(gè)包含屬性constructor構(gòu)造函數(shù)的普通對(duì)象
        //這里給Person.prototype定義一個(gè)eat屬性
        Person.prototype.eat = function(){
            console.log('eat');
            console.log(this.name);
        };
        var tom = new Person('tom');
        //在生成tom時(shí), 步驟如下
        //(1)創(chuàng)建一個(gè)空對(duì)象var obj = {}
        //(2)Person.apply(obj,arguments)
        //apply其實(shí)是Function.prototype定義的方法
        // 會(huì)讓Person()函數(shù)內(nèi)部的this指向obj,
        所以你寫(xiě)的this.name就相當(dāng)于obj.name1。給對(duì)象添加屬性.
        //(3)obj.__proto__ === Person.prototype // 搭建原型鏈
        //這一步這是tom可以調(diào)用eat方法的關(guān)鍵
        //(4)return obj;
        // 讓var tom = new Person();中的tom接收obj,也就是這里的tom就是函數(shù)內(nèi)部的obj

        tom.eat();//eat

總結(jié):
除Function.prototype為Function(因?yàn)镕unction.prototype = new Function),

其他所有構(gòu)造器對(duì)象的prototype都是一個(gè)普通的object, 可以給這個(gè)object定義不同的屬性, 然后通過(guò) new 構(gòu)造器 生成普通對(duì)象, 會(huì)搭建原型鏈, 即

var tom = new Person();
tom.__proto__ = Person.prototype

tom就能使用Person.prototype上所有的方法, 由于Person.prototype只是個(gè)普通的object對(duì)象(通過(guò)Person生成, 包含constructor屬性, 所以

Person.prototype.constructor = Person;
Person.prototype.__proto__  = Object.prototype 
console.log(Object.getOwnPropertyNames(Object.prototype));

Object.prototype對(duì)象上的方法包括如下:


image.png

所以tom能使用Object.prototype的所有方法

Object.prototype.__proto__ = null;

Function.prototype為Function, 當(dāng)執(zhí)行

var Person = function(){}

搭建原型鏈時(shí)會(huì)將Function.prototype賦給Person.__ proto __屬性, ,而Function.prototype是一個(gè)Function, 包含的屬性值:

image.png

所以Person的call方法來(lái)源于Funciton.prototype.call, 可以直接調(diào)用Person()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容