用于组合Object和Class的JavaScript mixin创建了TypeError

时间:2014-01-16 19:23:17

标签: javascript object prototype mixins

我正在尝试将现有对象与扩展它的类(及其原型)结合起来。

代码如下,我当然可以根据需要添加更多细节,但我认为这涵盖了问题。如代码中所指定,错误为TypeError: this.prototype is undefined。此代码段中的最后一行是导致此错误的调​​用,错误本身发生在.addMixin(mixin)函数中。

我以前参考的参考文献包括: http://www.joezimjs.com/javascript/javascript-mixins-functional-inheritance/http://javascript.crockford.com/prototypal.html(虽然这是到达上面的垫脚石)

注意:我知道这可以用JQuery和其他库完成,但我想做这个Vanilla。

// setup some tools
var config = {
  writable: true,
  enumerable: true,
  configurable: true
};

var defineProperty = function(obj, name, value) {
  config.value = value;
  Object.defineProperty(obj, name, config);
}

// And mixins
Object.prototype.addMixin = function (mixin) {    
    for (var prop in mixin) {
        if (mixin.hasOwnProperty(prop)) {
            this.prototype[prop] = mixin[prop]; // this is where the error occurs: 'TypeError: this.prototype is undefined'
        }
    }
};

// Define File prototype
var File = Object.create(Object.prototype);
defineProperty(File, 'file', null);
defineProperty(File, 'outputID', null);
defineProperty(File, 'hash', null);
defineProperty(File, 'hashThis', function (callback) {});

// define Timestamp prototype
var Timestamp = Object.create(File);
defineProperty(Timestamp, 'protectedHashValue', null);
defineProperty(Timestamp, 'timestamp', null);
defineProperty(Timestamp, 'read', function () {});
defineProperty(Timestamp, 'verify', function () {});

// Later, we take in a file using the HTML5 file API
// First, create the File object (in an array because there are multiple files)
globalStatus.files[fileIndex] = Object.create(File);
// and now place the file in the file property of the new File object
globalStatus.files[fileIndex].file = evt.target.files[fileIndex];

// Later on we determine that a particular file is a timestamp
// We want to mix in the properties of the Timestamp prototype to this existing File object
globalStatus.files[fileIndex].addMixin(Timestamp); // this is the call which initiates the error

1 个答案:

答案 0 :(得分:2)

内部addMixin方法this指的是一个对象实例,在该对象实例上调用该方法。 实例没有prototype属性 - Function s。

我不确定,您要做的是:将mixin属性添加到所有未来的实例或将它们添加到实例中,因此我将为您提供这两种变体。

对于所有实例,您需要使用的是constructor属性,它返回一个用于创建实例的函数:

Object.prototype.addMixin = function (mixin) {    
    for (var prop in mixin) {
        if (mixin.hasOwnProperty(prop)) {
            this.constructor.prototype[prop] = mixin[prop]; 
        }
    }
};

对于特定实例,只需在this上使用括号表示法:

Object.prototype.addMixin = function (mixin) {    
    for (var prop in mixin) {
        if (mixin.hasOwnProperty(prop)) {
            this[prop] = mixin[prop];
        }
    }
};

谨防mixin参数的属性,即参考类型(例如object Objectobject Array