Javascript传递带有本地引用的回调

时间:2013-05-16 13:57:11

标签: javascript callback

可以在此JSFiddle

上看到一个示例

我正在创建一个实例,更改该实例的一个函数,然后在该实例中的另一个函数内调用该函数。我在更新的函数中访问本地和实例变量时遇到了困难。

代码

var MyObj = function (name) {
    var that = this;
    MyObj.myObjs = (MyObj.myObjs || []),
    this.objName = name,
    this.objIdx = MyObj.myObjs.length;
    MyObj.myObjs.push(this.objName);

    this.doOnSetName = function () {};

    this.setName = function (name) {
        that.doOnNameSet();
        that.objName = name;
        MyObj.myObjs[that.objIdx] = name;
    }
}

var obj1 = new MyObj("obj1");
//obj1.doOnNameSet = function() { alert("objName: "+this.objName) };
//obj1.setName("obj1");

var obj2 = new MyObj("obj2");
obj2.doOnNameSet = function () {
    $("#console").append("Old objName: " + this.name
                         + "<br />New objName: " + name + "<br />")
};
obj2.setName("obj2 - changed");

$("#console ").append("Objects: <br />*" + MyObj.myObjs.join(", <br />*"));

实际结果

Old objName: undefined
New objName: result
Objects: 
*obj1, 
*obj2 - changed

期望的结果

Old objName: obj2
New objName: obj2 - changed
Objects: 
*obj1, 
*obj2 - changed

4 个答案:

答案 0 :(得分:2)

that.objName = name;
MyObj.myObjs[that.objIdx] = name;
that.doOnNameSet();

表示在调用侦听器时已忘记旧名称。我不确定你是怎么打算得到它的。也许在更改之前调用侦听器,并使用新名称作为参数。

obj2.doOnNameSet = function () {
     $("#console").append("Old objName: " + this.name
                          + "<br />New objName: " + name + "<br />");
};

该属性名为objNamename变量显然未定义。你想把它作为参数吗?

答案 1 :(得分:2)

您可以将旧名称和新名称传递给doOnSetNameFiddle):

var MyObj = function (name) {
    var that = this;
    MyObj.myObjs = (MyObj.myObjs || []),
    this.objName = name,
    this.objIdx = MyObj.myObjs.length;
    MyObj.myObjs.push(this.objName);

    this.doOnSetName = function (oldName, newName) {};

    this.setName = function (name) {
        that.doOnNameSet(that.objName, name);
        that.objName = name;
        MyObj.myObjs[that.objIdx] = name;
    }
}

var obj1 = new MyObj("obj1");
//obj1.doOnNameSet = function() { alert("objName: "+this.objName) };
//obj1.setName("obj1");

var obj2 = new MyObj("obj2");
obj2.doOnNameSet = function (oldName, newName) {
    $("#console").append("Old objName: " + oldName
                         + "<br />New objName: " + newName + "<br />")
};
obj2.setName("obj2 - changed");

$("#console ").append("Objects: <br />*" + MyObj.myObjs.join(", <br />*"));

答案 2 :(得分:1)

错误在你的obj2.doOnNameSet方法中。 this.name应为this.objName。您的代码段中未定义name,但可能在代码中的其他位置将其定义为“结果”。您可以通过以下更改来解决此问题

obj2.doOnNameSet = function (name) {

最后,您需要在进行更改之前调用doOnNameSet:

this.setName = function (name) {
        that.doOnNameSet(name);
        that.objName = name;
        MyObj.myObjs[that.objIdx] = name;

    }

答案 3 :(得分:1)

不确定你要做的是什么,但以下内容将在创建时设置“this”名称并将其保存在共享名称列表中(不是像代码那样的全局变量,而是所有实例共享的原型属性) 。使用setName时,数组中的名称将设置为更改的名称:

var MyObj = function (name) {
    this.namesIndex=this.names.length;
    this.names.push(name);
    this.objName = name;
}
MyObj.prototype.names=[];
MyObj.prototype.setName = function (name){
  this.objName=name;
  this.names[this.namesIndex]=name;
}
var o1=new MyObj(1);
var o2=new MyObj(2);
o2.setName("2 changed");

console.log(o2.names);