簡體   English   中英

在javascript中混淆原型繼承

[英]Confuse about prototype inheritance in javascript

我想在構造函數上實現一個extend方法,並用它來初始化一個實例,如:

var view_instance = View.extend()

所以我試過這個:

define(function (require, exports, module) {

    function View(size, color) {
        this.size = size;
        this.color = color;
    };

    View.prototype = {
        show: function () {
            console.log("This is view show");
        }
    }

    View.extend = function (props) {
        var tmp = new this("12", "red");
        console.log(this);
            console.log(tmp instanceof this) //true
        console.log(tmp.prototype); //undefined!
        return tmp
    }

    return View;
})

在上面的extend方法中,我通過new this()初始化一個實例,但是我無法記錄它的原型,我檢查this是對的。

那我的代碼出了什么問題? 為什么原型會消失? 我該怎么辦?

tmp.constructor.prototype是你想要的。 o.__proto__是這個的快捷方式o.constructor.prototype它是非標准

[編輯]

你可以在這個問題中看到這個數字。 它表明Foo.prototype.constructor指向Foo本身。 但是,由於您使用View.prototype = {...}行覆蓋構造函數的原型,因此View.prototype.constructor將是function Object() { [native code] }而不是View本身。 因此,更准確的方法是直接為原始原型分配屬性或使用手動設置的constructor屬性覆蓋它:

// Assign properties to the original prototype to prevent overwriting the `constructor` properties.
View.prototype.show = function() {};

// Or set the constructor manually.
View.prototype = {
  show: function() {},
  constructor: View
};

您的代碼沒有任何問題。 它做了它應該做的事情。 prototype屬性僅存在於函數中。

當您使用new關鍵字進行函數調用之前,JavaScript會創建一個繼承自構造函數prototype的對象。

簡單來說:

function F() {}                                        // we have a constructor
var o = new F;                                         // we create an instance
console.log(Object.getPrototypeOf(o) === F.prototype); // o inherits from
                                                       // F.prototype

JavaScript中的對象通過委托從其他對象繼承。 這意味着我們嘗試訪問上面看到的對象o上的屬性:

  1. JavaScript將首先嘗試在o上找到屬性。
  2. 如果它找不到o上的屬性,那么它將嘗試在Object.getPrototypeOf(o)上找到它(或者更簡潔地將它放在o.__proto__ )。 o的原型是F.prototype
  3. 如果它找不到F.prototype上的屬性,那么它將嘗試在F.prototype.__proto__上找到它,它是Object.prototype
  4. 如果它無法在Object.prototype上找到該屬性,那么它將放棄,因為Object.prototype.__proto__null

簡而言之,這就是原型繼承。

您的代碼日志undefinedtmp.prototype的原因是因為tmp沒有任何名為prototype屬性。 只有函數具有prototype屬性。 試試這個:

console.log(Object.getPrototypeOf(tmp));

以上與以下相同。 但是,不推薦使用對象的__proto__屬性。 需要您自擔風險使用它:

console.log(tmp.__proto__);

如果您想了解有關繼承的更多信息,請閱讀以下文章:

  1. Aadit M Shah | 為什么原型繼承很重要
  2. JavaScript繼承和構造函數屬性 - Stack Overflow

prototype屬性屬於構造函數。 實例具有指向同一對象的非標准__proto__屬性。 所以:

console.log(tmp.__proto__);

要么:

console.log(Object.getPrototypeOf(tmp));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM