3

给定以下代码,我在弄清楚如何设置原型链时遇到了一些麻烦。

var Model = {
    prototype: {
        init: function(){},
        log: function(){ console.log('instance method log was called') }
    },
    log: function(){ console.log('class method log was called') },
    create: function() {
        var object = Object.create(this);
        object.parent = this;
        object.prototype = object.fn = Object.create(this.prototype);
        return object;
    },
    init: function() {
        var instance = Object.create(this.prototype);
        instance.parent = this;
        instance.init.apply(instance, arguments);
        return instance;
    }
}

var User = Model.create();
User.log(); // 'class method log was called'

// create a new method after creation
Model.warn = function() { console.warn('warn was called') }

User.warn() // 'warn was called'

var user = User.init();
user.log(); // 'instance method log was called'

具体来说,这一行让我在 create 方法中感到困惑:

object.prototype = object.fn = Object.create(this.prototype);

我了解 create 方法如何创建一个原型指向 Model 的新对象,但倒数第二行似乎用新对象 (Model.prototype) 覆盖了该原型。但是,看起来原始原型仍然完好无损,因为即使在创建新对象后我也可以向 Model 添加方法,并且新对象仍然可以访问它。

有人可以对实际发生的事情有所了解吗?

编辑- 我应该指出这段代码来自O'reilly的Javascript Web Applications

4

1 回答 1

3

行。所以只是为了删除噪音代码,你在问这个代码:

var Model = {
    prototype: {},
    create: function() {
        var object = Object.create(this);
        object.prototype = Object.create(this.prototype);
        return object;
    }
};

Model.create() 函数的第一行很简单,它创建了一个扩展(原型)模型的新对象。

但是你很困惑,因为下一行覆盖了对象的“原型”属性。不是对象的原型,对象原型仍然是Model,它存储在一个名为[[Prototype]]的隐藏属性中,代码修改的属性与对象的[[Prototype]]无关,它只有相同的姓名。让我们更改名称以理解它,它将是相同的:

var Model = {
    blablabla: {},
    create: function() {
        var object = Object.create(this);
        object.blablabla = Object.create(this.blablabla);
        return object;
    }
};

它扩展了 Model.blablabla,因此当您更改 object.blablabla 时,它不会影响 Model.blablabla。

var SubModel = Model.create();
SubModel.blablabla.newMethod = function() { };
console.log(Model.blablabla.newMethod); // undefined

很多时候,为字段选择正确的名称比看起来更重要。

于 2012-10-04T21:52:55.167 回答