Javascript:如何确保对象中的“this”始终相同?

时间:2016-01-11 20:58:54

标签: javascript this

有没有办法确保this在对象中访问时始终是一样的?

我有以下代码:

var stack = [];
var callStack = function ()
{
	for (var i in stack) {
		// does not work
		stack[i][0].apply(null, stack[i][1]);
		// does not work either
		stack[i][0].apply(stack[i][0], stack[i][1]);
	}
};
var testThis = {
	bar : "something",
	show : function()
	{
		console.log(this.bar, arguments);
	}
}

testThis.show('standardCall');
stack.push([testThis.show, ['someVar']]);
stack.push([testThis.show, ['otherVar', 'yetAnotherVar']]);
callStack();

我想要实现的是:我希望能够准备一堆稍后要调用的函数/方法(这只是一个简化的例子,实际上,调用将遍及整个应用程序)

在对象中,我希望能够访问对象的方法和属性,就像它们被称为“正常”一样(如testThis.show('standardCall')中的示例所示,其工作方式与预期一样),即我无论方法如何被调用,都需要this在方法中始终相同。在这个例子中,我希望this.bar始终显示“某事”。 有没有办法确保这种行为? call / apply方法似乎不起作用。

注意:我正在寻找一个通用的解决方案,所以,显然,我无法通过引用“bar”来解决它(如testThis.bar),将其从对象的上下文中删除等。)

2 个答案:

答案 0 :(得分:2)

this取决于函数的调用方式。因此,在存储函数时,还必须指定要用作this的内容,以便将其作为第一个参数传递给https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply



var stack = [];
var callStack = function (){
  for (var i=0; i < stack.length; i++) {
    // Setting what this will be
    //                     v
    stack[i][0].apply(stack[i][1], stack[i][2]);
  }
};
var testThis = {
  bar : "something",
  show : function() {
    console.log("testThis.show "  + this.bar, arguments);
  }
};

var testThat = {
    foo: 1,
    doIt: function(some) {
       console.log('testThat.doIt Foo is '+ this.foo + ' and ' + some);
    } 
}

stack.push([testThis.show,  testThis, ['someVar']]);
stack.push([testThis.show, testThis, ['otherVar', 'yetAnotherVar']]);
stack.push([testThat.doIt,  testThat, ['anything']]);
stack.push([testThat.doIt, testThat, ['something']]);

callStack();
&#13;
&#13;
&#13;

或者,您可以绑定该函数以指定this将是什么,see the answer by Alex

答案 1 :(得分:1)

你只需要bind你的范围 - 这里有几种方法:

stack.push([testThis.show.bind(testThis), ['someVar']]);
stack.push([testThis.show.bind(testThis), ['otherVar', 'yetAnotherVar']]);

或者,如果你100%总是希望保证在testThis的上下文中执行此功能,你可以这样做:

testThis.show = testThis.show.bind(testThis);

然后你可以正常继续:

stack.push([testThis.show, ['someVar']]);
stack.push([testThis.show, ['otherVar', 'yetAnotherVar']]);

并且随时调用该函数 - 即使稍后使用.bind(..a different object...) - this调用它将是testThis对象。