javascript:在对象之间扩展方法,比如mixins

时间:2016-09-09 18:45:26

标签: javascript underscore.js mixins

我想在不同对象之间共享或重用某些逻辑,它们将非常相似,只是改变了“范围”。

var Mixin = {
    show: function () {
        this.container.show();
    },

    hide: function () {
        this.container.hide();
    },

    play: function (data) {
        data.map().append();
    }
};

var ObjectA = {
    container: $('#container_a');

    foo: function () {
        this.play(otherData); // Mixin common method?
    }    
};

var ObjectB = {
    container: $('#container_b'),

    foo: function () {
        this.play(data); // Mixin common method?
    }
};


ObjectA.show() // show $('#container_a');
ObjectB.show() // show $('#container_b');

我正在尝试使用下划线

_.extend(ObjectA, Mixin);

但似乎我对Mixin的引用有问题(这是对最后一个扩展对象的引用),就像我需要克隆对象并扩展它一样?

有没有办法做类似的事情?

谢谢!

编辑:我对'this'的范围有疑问,即引用窗口,当一个函数作为回调函数继承自mixin时,就像这样。

PersonMixin = {
    mixinFoo: function () {
        this.handleResponse();
    }
};

Person = {
    personMethod: function () {
        OtherLibrary.libMehtod(this.mixinFoo);
    }
};

Object.assign(Person, PersonMixin);

然后,这样的事情会失败,这是一个示例堆栈跟踪

Person.personMethod();
OtherLibrary.libMethod(callbackMixin);
Ajax.post(callbackMixin);
callbackMixin(response); // this.handleResponse() is not defined, because this reference to window object.

编辑2:我可以使用bind()

解决此问题

2 个答案:

答案 0 :(得分:2)

您可以通过多种方式执行此操作,我的偏好是在创建时调整对象__proto__属性,这将导致它通过其原型链继承您的mixin。这不需要使用下划线。

我为ES6调整了你的例子并使它更简单但是应该明白这一点。

const PlayerType = (
  { show() {
      console.info(`show ${this.name}`)
    }
  , hide() {
      console.info(`hide ${this.name}`)
    }
  , play: function (data) {
      data.map().append();
    }
  }
)

const objA = { __proto__: PlayerType
, name: 'objA'
, foo(...args) {
    this.play(...args)
  }    
}

const objB = { __proto__: PlayerType
, name: 'objB'
, foo(...args) {
    this.play(...args)
  }    
}


objA.show()
objB.show()

更简单,没有ES6:

var Mixin = (
  { show() {
      console.info('show ' + this.name)
    }
  , hide() {
      console.info('hide ' + this.name)
    }
  }
)

var a = { __proto__: Mixin, name: 'a' }

var b = { __proto__: Mixin, name: 'b' }

a.show()
b.show()

替代 - 与Object.create()做同样的事情。

var Mixin = (
  { show() {
      console.info('show ' + this.name)
    }
  , hide() {
      console.info('hide ' + this.name)
    }
  }
)

var a = Object.create(Mixin, { name: { value: 'a', enumerable: true } })

var b = Object.create(Mixin, { name: { value: 'b', enumerable: true } })

a.show()
b.show()

答案 1 :(得分:2)

它有效,只需检查你的语法。

var Mixin = {
 show: function() {
  console.log(this.tmp);
 }
}

var oA = {
 tmp: 'tmpA'
}

var oB = {
 tmp: 'tmpB'
}

var mA = Object.assign(oA, Mixin);
var mB = Object.assign(oB, Mixin)

mA.show();
mB.show()