js原型鏈,一步一步找祖宗

小小田發表於2018-05-04

一、es6類

class A{

 coco = ()=>{}
    //箭頭函式預設繫結外部環境的this,所以在類裡面這麼寫等於於是寫在建構函式的this上的,每次在new這個類的時候都會生成一個coco函式

 bar(){}
 //在類裡面這麼寫函式等於是寫在建構函式的prototype上的,當然new的時候不會重新生成一個bar,但是因為沒有為其繫結this,所以通常在寫react的時父元件向子元件傳遞繫結事件時需要手動繫結this指明執行時this指向父級,而不是執行環境時的this

 render(){
 return <div onClick={this.bar.bind(this)}></div>
複製程式碼

} }

二、如何指定原型鏈 1、準備一個物件和函式,如下,然後手動的將建構函式的prototype指定物件。

var obj = {b:function(){}}

function Foo(){

}
//預設情況Foo.prototype上有一個constuctor:Foo.prototype = { constuctor: Foo }
複製程式碼

預設情況下新增原型方法時 :Foo.prototype.a = function(){}

手動設定原型物件:Foo.prototype = obj

var a = new Foo()

//a等於 { proto: Foo.prototype }

這時當別人new Foo時,就會構造出一個新的物件(例:a),a裡面會預設有個__proto__的屬性指向Foo.prototype, (補充:Foo.prototype預設是一個物件,並且預設的物件裡有個constuctor屬性,constuctor的值指向該原型物件對應的建構函式 (例:Foo(){}),但是上面例子中,由於我們手動的將Foo.prototype指向了另一個新物件,新物件裡也並沒有給出constuctor的屬性,((注:當然可以選擇給這個新物件的增加一個constuctor屬性並且賦值))這時就會出現構造出來的a在訪問constuctor時到原型鏈(Foo.prototype)上找,但是因為Foo.prototype上沒有constuctor這個屬性,那麼就會繼續向更深的原型鏈上去找,直到找到Object為止。

2、使用Object.create()指定原型

var obj = {bb:1}

var a = Object.create(obj)

//a 等於{

__proto__:{ bb :1}
複製程式碼

}

a.rr = 1;

var b = Object.create(a)

// b 等於 {

__proto__:{

    rr:1,

    __proto__:{bb:1}

    
}
複製程式碼

}

b.constuctor //結果 Object(){}

由於沒有指定constuctor,所以是由Object建構函式構造 上面這種寫法是最簡單的持續繼承的方式,祖宗十八代的原型鏈,簡潔易懂,沒啥子好說的

3、es6的extends指定原型

class A{

rr(){}
複製程式碼

}

class B extends A{

}

//轉換成es5

function A(){

}

A.prototyper ={ constructor:A, rr:function(){} }

function B(){

}

B.prototype = new A()

//執行結果B.prototype ={

__proto__:{

    constructor:function A(){},

    rr::function(){}

}
複製程式碼

}

B.prototype.constructor = B

需要補充的知識點B.prototype = new A()這句話可以看出B.prototype 被賦值給了一個新的物件,並且這個新物件裡沒有constructor這個這個屬性,只有原型__proot__指標上有一個constructor是指向A的,B.prototype.constructor = B這句話,為了保證被B類new出來的物件原型鏈能正常找B祖宗,所以需要指定B.prototype.constructor =B;

私人學習筆記,可能有寫錯的地方,希望大神指出

相關文章