繁体   English   中英

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

[英]javascript: extending methods between objects, like 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()解决此问题

您可以通过多种方式执行此操作,我的首选是在创建对象时调整对象__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() 

它有效,也只需检查语法即可。

 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() 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM