2

我只想替换 JavaScript 对象的“仿函数”函数。下面的代码演示了这个问题:

// PART 1: Declaration
function obj() {
    return obj.a + " " + obj.b; 
};
obj.a = "a"; 
obj.b = "b"; 
confirm(obj()); // output: "a b"; 

// PART 2: Modification
// now replace only functor 
// (not working this way as it replaces the whole object)
obj = function () {
    return obj.b + " " + obj.a; 
};
confirm(obj()); // expected output: "b a"; 

我需要这个,因为我无权访问第 1 部分并且需要修改对象的功能...

有没有办法在 JavaScript 中做到这一点?

复制(例如使用 for 循环)不起作用,因为它不会复制所有隐藏的属性......

更新:修改后的代码不是未定义的......

UPDATE2:这似乎适用于这个例子:(需要jQuery)

obj = $.extend(function() { return obj.b + " " + obj.a; }, obj);
confirm(obj()); // output: "b a"; 

(但它并没有解决我的问题......)

4

3 回答 3

1

你需要一个对象和一个函数相互引用,然后你只改变它的函数部分。

var obj = function() {
    var x = function() {return x.f();}; 
    x.f = function() { return x.a + " " + x.b; };
    return x;
}();

obj.a = "a";
obj.b = "b";

alert(obj());

要更改功能,只需更改 obj.f:

obj.f = function () {
    return obj.b + " " + obj.a; //swap the order.
};

alert(obj());

编辑:错过了你说你无权访问 Part1 的部分,所以这个解决方案对你不起作用,但把它留在这里以防它帮助别人,因为它允许你使用 obj()直接地。

于 2013-05-07T09:19:43.770 回答
0

您需要反转您的函数/对象。那就是制作一个对象并在其中放入一个函数。这意味着为了调用该函数,您需要指定对象:

obj = {
  functor : function () {
    return this.a + " " + this.b; 
  }
};
obj.a = "a"; 
obj.b = "b"; 
confirm (obj.functor ()); // output: "a b"; 

// PART 2: Modification
// now replace only functor 
obj.functor = function () {
    return this.b + " " + this.a; 
};
confirm (obj.functor()); // expected output: "b a"; 
于 2013-05-07T08:20:05.083 回答
0

我会这样包装它(将此代码粘贴到 Chrome 的控制台中):

// PART 1 - exactly as provided

function obj() {
    return obj.a + " " + obj.b; 
};
obj.a = "a"; 
obj.b = "b"; 
console.log(obj()); // output: "a b";

// PART 2 - object is used in different context

var API = {
    setObj: function(obj) {
        this._obj = obj;
    },
    useObj: function() {
        console.log("API: " + this._obj());
    }
}

API.setObj(obj);
API.useObj();

// PART 3 - wrapping obj, changing it's default behavior

objWrapper = function(obj) {

    var wrappedObj = function() {
        return wrappedObj.b + " " + wrappedObj.a;
    }

    var i;
    for(i in obj) {
        if(obj.hasOwnProperty(i)) {
            wrappedObj[i] = obj[i];
        }
    }

    return wrappedObj;
}
obj = objWrapper(obj);
console.log(obj()); // expected output: "b a";
console.log(obj.a);
console.log(obj.b);
obj.c = "c";
console.log(obj.c);

// PART 4 - checking different context

API.setObj(obj);
API.useObj();

这是使它工作的唯一方法。您必须更新对该函数的每个引用,因此如果您无法模拟API.setObj(obj);,则无法使其工作。您不能只重新定义函数的主体。也许将来他们会添加它,因为它确实很有帮助,它会使 JS 成为更函数式的编程语言。

我将confirm对话框替换console.log为它很烦人!;)

希望它会有所帮助!

于 2013-05-07T08:22:26.360 回答