詳談javascript的原型鏈問題
1、建立物件的幾種方法
// 字面量 var obj1 = { name:'小一' }; //new Object() var obj2 = new Object({name:'小二'}); // 建構函式 function f(name) { this.name = name } var obj3 = new f('小三'); // Object create() 一個新物件,帶著指定的原型物件和屬性 var obj4 = Object.create({name:'小四'}); console.log(obj1); console.log(obj2); console.log(obj3); console.log(obj4);
列印結果:
另外:Object.create(proto,propertiesObject) // 建立一個新物件,使用現有的物件來提供新建立的物件的__proto__。 //proto:新建立物件的原型物件 // propertiesObject引數為null或者一個物件,如果是其他型別則會報錯。表示新增到新建立物件的可列舉屬性
那麼什麼是原型鏈呢?簡單來說就是組成原型的鏈,我們知道每個例項都有一個屬性__proto__指向它的原型,而原型也是一個物件,也有__proto__指向它的原型,這樣一層層找下去,就形成了原型鏈。最後是原型鏈有什麼作用呢?
function Foo(){ this.name = name } var obj5 = new Foo('小明'); var obj6 = new Foo(); obj5.__proto__.say = function () { console.log('hello') }; obj5.say(); obj6.say();
列印結果:
發現都能列印,因為say()方法是新增在原型物件上的,例項obj5和obj6都是由Foo()同一個建構函式new出來的例項,所以obj5和obj6的__proto__指向同一個原型物件,當給原型物件新增方法或者屬性時,obj5和obj6都能訪問到。這樣可以解決多個例項都用到同一方法時,直接給原型物件新增,而不必每一個例項物件去新增一個方法或者屬性。在訪問屬性或者方法時會先在例項物件上查詢,如果找不到就會往上找。
再來解釋一下__proto__,prototype,constructor的聯絡
例項是由建構函式new出來的一個物件
例項的__proto__指向原型物件 obj5.__proto__ === Foo.prototype
建構函式的prototype指向原型
原型的constructor指向它的建構函式 obj5.__proto__.constructor === Foo
instanceof又是什麼作用呢?其實就是用來檢驗例項的__proto__和建構函式的prototype是不是指向同一個原型物件。如果是,則返回true,否則返回false