2017-03-26 132 views
1

我在引擎蓋下圍繞原型鏈,但我在構建函數時遇到了一些困難。我想要構建一個函數來接收對象並添加到對象的原型中。我究竟做錯了什麼?原型鏈繼承

function getObject(obj) { 
    function F() {} 
    F.prototype.say = function(){ 
    console.log("Hello", this.name); 
    }.bind(obj); 

    obj.prototype = Object.create(F.prototype); 
    return obj; 
} 

var r = getObject({ name: "James"}); 

r.name 
r.say() 

// r = { name: "James" } 
// r.say() "Hello James" 

我得到了我正在尋找的東西。我受到限制,不允許使用ES6課程......我知道對不對?

function getObject(obj) { 
    function F() { } 
    F.prototype.say = function(){ 
    console.log("Hello", this.name); 
    }; 
    const output = Object.create(F.prototype); 
    return Object.assign(output, obj); 
} 

var r = getObject({ name: "James"}); 
r // { name: "James" } 
r.name // "James" 
r.say() // "Hello James" 
+4

對象沒有原型屬性函數。他們只有一個dunder proto鏈接 –

回答

2

我已經修改了代碼。對象沒有原型。函數具有可用於鏈接的原型。希望這可以幫助。

function getObject(obj) { 
    function F() {} 
    F.prototype = Object.create(obj); 

    F.prototype.say = function(){ 
     console.log("Hello", this.name); 
    }.bind(obj); 

    return new F(); 
} 

var r = getObject({ name: "James"}); 

console.log(r.name); // James 
r.say() // Hello James 
+1

謝謝,正是我在找的東西 –

2

您可以添加方法的對象像obj.something = function() {};

至於方法鏈,你想回到你的this繼承函數中。

因此,像這樣將回答您的問題

function getObject(obj) { 
    obj.say = function() { 
     console.log(`Hello ${this.name}`); 
     return this; 
    } 
    obj.hi = function() { 
     console.log('hi'); 
     return this; 
    } 
    return obj; 
} 

var newObj = getObject({}); 

newObj.say().hi(); 
// Helo A K 
// hi 

而且分配obj.prototypes等於一類,而不是類原型。所以在將來如果你想讓一個原型等於一個類的原型使用obj.prototype = Object.create(anothingObj.prototype);

+0

新的f()不是一個類。它可能看起來像一個類的行爲,但新的關鍵字只是創建一個空的對象.JS沒有類 –

+0

它不是一個類,但它模擬一個類。新關鍵字不會創建空對象。 'new F();'實際上包含'say'函數。順便說一句,JavaScript ES6有類。 –

+0

新關鍵字正在創建一個空對象,您可以檢查ECMAScript規範,函數F()只是將它指向新的空對象。是的,ES6可能有類關鍵字,但並不意味着JS有類。這只是語法糖。它與引擎蓋下的新F()相同,只是代碼少得多。 –

1

你明確地在一個對象上添加一個原型屬性。 obj.prototype = undefined當你用new關鍵字調用它時,它只會向該屬性添加一個空對象。所以新的obj將是obj = {name:'james' , prototype: {}}。現在對象的原型屬性將指向函數F的原型。正確的方法是通過Object.create。你可以模仿的是同樣的行爲像這樣

if(!Object.create){ 
Object.create = function(o) { 
function F() {} 
F.prototype = o ; 
    return new F(); 
}; 
} 

您可以檢查出MDN Docs爲的Object.create的詳細說明填充工具