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

PART 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 に答える