簡體   English   中英

重寫對象的構造函數的原型不起作用

[英]Rewrite object's constructor's prototype doesn't work

這是我的代碼:

function Class() {};

Class.prototype.extend = function () {
    var instance = new Class();
    instance.constructor.prototype = {
        say: function () {
            console.log("Hello");
        }
    }
    console.log(instance); //Class {extend: function}
}

Class.extend = function () {
    this.prototype.extend();
}

Class.extend();

extend方法中,我重寫了一個實例的原型instance.constructor.prototype = {..}

但是,當我記錄實例時,它不會顯示say方法

為什么重寫不起作用? 我該怎么辦呢?

這是演示

當您分配新的原型對象時,只有新實例化的對象才會擁有新的原型:

function Class() {};

Class.prototype.extend = function () {
    var instance = new Class();
    instance.constructor.prototype = {
        say: function () {
            console.log("Hello");
        }
    }
    console.log(instance);    //Class {extend: function}
    console.log(new Class()); //Class {say: function}
}

Class.extend = function () {
    this.prototype.extend();
}

Class.extend();

這是因為在實例化對象時,會從構造函數的原型中復制對原型對象的引用。 如果要添加到所有現有實例和將來實例的原型,只需修改原型對象,而不是將全新對象分配給構造函數:

function Class() {};

Class.prototype.extend = function () {
    var instance = new Class();
    instance.constructor.prototype.say = function () {
        console.log("Hello");
    }
    delete instance.constructor.prototype.extend;
    console.log(instance); //Class {say: function}
}

Class.extend = function () {
    this.prototype.extend();
}

Class.extend();

您成功更改了Class.prototype ,但您將其更改為完全不同的對象

instance有一個對其原型對象的引用,稱為instance.__proto__ 創建新的Class實例時,實例的__proto__指向與Class.prototype相同的對象。

但是,您更改 Class.prototype 所指的內容 這將影響將來實例的__proto__ ,但不影響任何現有實例 instance.__proto__仍然指向Class.prototype用來引用的舊對象。

在構造instance之后,它首先看起來如何:

instance.__proto__ ===> { extend: function } <=== Class.prototype

這是將Class.prototype分配給新對象的方式:

instance.__proto__ ===> { extend: function }
                        { say:    function } <=== Class.prototype

相反 ,您要修改對象Class.prototype指的是:

instance.constructor.prototype.say = function () {
    console.log("Hello");
}

這將為您提供如下最終圖片:

instance.__proto__ ===> { extend: function, say: function } <=== Class.prototype

看到Class.prototypeinstance.__proto__仍然指向同一個對象,但對象本身現在有一個額外的屬性。

我確實添加了這個功能。 但是您正在更改prototype對象本身,而不是更改其屬性:

演示

Class.prototype.extend = function () {
    var instance = new Class();
    instance.constructor.prototype.say =
        function () {
            console.log("Hello");
        }
    console.log(instance);
    // Class {extend: function, say: function}

}

當您嘗試訪問some_obj.some_field ,JS引擎本身將首先檢查對象自己的屬性,然后轉到some_obj.prototype並查找some_field

通過分配instance.constructor.prototype = {...}您將更改prototype將指向所有新創建的對象的位置,但不會更改已存在的對象。

雖然這是一種非標准方法,但這將有助於您在JS環境中允許您編輯proto內部屬性。

function Class() {};

Class.prototype.extend = function () {
    var instance = new Class();
    instance.__proto__ = instance.constructor.prototype = {
        say: function () {
            console.log("Hello");
        }
    }


    console.log(instance); //Class {extend: function}
    console.log(instance.say)
}

Class.extend = function () {
    this.prototype.extend();
}

Class.extend();

暫無
暫無

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

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