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