Javascript:如何确保"this"在一个对象中始终相同?

Javascript: how to ensure that "this" is always the same within an object?

有什么方法可以确保 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();

我想要实现的是:我希望能够准备一堆 functions/methods 以便稍后调用(这只是一个精简的示例,实际上,调用将分布在整个整个应用程序)。

在对象中,我想访问对象的方法和属性,就好像它们被称为 "normally" 一样(如 testThis.show('standardCall') 的示例所示,它按预期工作),即无论如何调用方法,我都需要 this 在方法中始终相同。在此示例中,我希望 this.bar 始终显示 "something"。 有什么办法可以确保这种行为吗? call/apply 方法似乎不起作用。

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

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

或者,您可以绑定函数以指定 this 是什么,

您只需要 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 对象。