Javascript常量设置变量
运行此代码时,构造函数Javascript常量设置变量,javascript,jquery,Javascript,Jquery,运行此代码时,构造函数Test(callbacks)首先传入的whatever值将成为始终被调用的回调,即使在Test的后续实例化中也是如此 function Test(callbacks) { if (callbacks) { if (callbacks.callback) { this.callback = callbacks.callback; } } this.options.complete = $.pr
Test(callbacks)
首先传入的whatever值将成为始终被调用的回调,即使在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”);}
如何成为原型的常量值?当您这样做时
this.options.complete = $.proxy(this.options.complete, this);
您正在替换选项。将原型的
功能替换为始终将此
作为上下文的功能
问题在于,您没有一个与this
相对应的this.options
对象,但只有一个对象与具有相同原型的所有对象共享。这一切都从这一行开始:
this.callback = callbacks.callback;
当您调用newtest(eins)
时,eins
作为callbacks
参数进入。然后,该行将this.callback
(即新测试实例上的“callback”属性)设置为callbacks
,即eins
的callback属性
现在,仅此一点不会影响B。然而,有一些棘手的问题:
this.options.complete = $.proxy(this.options.complete, this);
您可能认为这将在您的测试实例上设置“options”属性,对吗?错。Javascript的工作方式是,如果没有在您的实例上定义属性(例如,您没有执行this.options=something
),Javascript将查找“原型链”,在那里它将找到原型的“选项”,并对其进行设置(而不是实例的“选项”,因为您的实例没有)
您可以通过将该行更改为:
this.options = {complete: $.proxy(this.options.complete, this)};
当然,这会丢失您的类型:“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);
如果您碰巧正在使用(优秀的)下划线库,它甚至有一个extend
函数,可以更轻松地完成这类工作:
this.options = _.extend({}, this.prototype.options,
{complete: $.proxy(this.options.complete, this)});
或者(取决于您的样式首选项):
顺便说一句,下划线还有一个与jQuery的“代理”类似的..bind
方法,因此您还可以执行以下操作:
this.options = _.extend({}, this.prototype.options);
this.options.complete = _.bind(this.options.complete, this);
我从来没有说过它不是:-)问题是“function(){console.log(“AAA”);}如何成为原型的常量值?”,答案是它发生在这一行。FWIW,jQuery也有,但我同意,下划线是一个很好的库。幸运的是,OO JS对我来说并不太常见。jQuery扩展和下划线扩展之间有一些细微的区别,但我不记得有什么区别,所以我在示例中坚持使用下划线。但是,是的,你也可以完全使用jQuery。可能是或的重复
this.options = _.extend({}, this.prototype.options);
this.options.complete = _.bind(this.options.complete, this);