运行此代码时,构造函数Test(callbacks)
首次传入的任何值都将成为始终调用的回调,即使在Test
function Test(callbacks) {
if (callbacks) {
if (callbacks.callback) {
this.callback = callbacks.callback;
}
}
this.options.complete = $.proxy(this.options.complete, this);
}
Test.prototype = {
options: {
type: "GET",
complete: function() {
this.callback();
}
},
callback: function() { console.log("OVERRIDE ME"); },
execute: function() {
$.ajax(this.options);
}
};
var eins = {callback: function() {console.log("AAA");}};
var zwei = {callback: function() {console.log("BBB");}};
var A = new Test(eins);
var B = new Test(zwei);
A.execute();
B.execute();
每次获得输出AAA
时运行此代码。 function() {console.log("AAA");}
如何成为原型的常量值?
答案 0 :(得分:2)
这一切都从这一行开始:
this.callback = callbacks.callback;
当您拨打电话new Test(eins)
时,eins
会以callbacks
参数的形式出现。然后该行将this.callback
(即新的Test实例上的“callback”属性)设置为callbacks
的回调属性,即。 eins
。
现在,仅此一点不会影响B.但是,有一些棘手的事情:
this.options.complete = $.proxy(this.options.complete, this);
您会认为这会在您的Test实例上设置“options”属性,对吗?错误。 Javascript的工作方式是,如果未在您的实例上定义属性(例如,您没有this.options = something
),那么Javascript将查找“原型链”,在那里它将找到原型的“选项” ,并设置它(不是你的实例的“选项”,因为你的实例没有)。
您可以通过将该行更改为:
来解决所有问题this.options = {complete: $.proxy(this.options.complete, this)};
但当然会失去你的type: "GET",
,所以你需要这样做:
this.options = {type: "GET", complete: $.proxy(this.options.complete, this)};
或者你需要将你的选项基于原型:
this.options = {};
for (var key in this.prototype.options) {
this.options[key] = this.prototype.options[key];
}
this.options.complete = $.proxy(this.options.complete, this);
如果您碰巧使用(优秀的)Underscore库,它甚至可以使用extend
函数来更轻松地执行此类操作:
this.options = _.extend({}, this.prototype.options,
{complete: $.proxy(this.options.complete, this)});
或(取决于您的风格偏好):
this.options = _.extend({}, this.prototype.options);
this.options.complete = $.proxy(this.options.complete, this);
顺便提一下,Underscore也有_.bind
方法,可以与jQuery的“代理”相媲美,所以你也可以这样做:
this.options = _.extend({}, this.prototype.options);
this.options.complete = _.bind(this.options.complete, this);
答案 1 :(得分:1)
当你这样做时
this.options.complete = $.proxy(this.options.complete, this);
您将原型的options.complete
函数替换为始终以this
作为上下文的函数。
问题在于,this.options
没有this
对象,但只有一个与所有具有相同原型的对象共享。