1. 程式人生 > >詳談javascript的原型鏈問題

詳談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