进行属性查询时,javascript如何处理`this`?

时间:2019-04-02 18:20:39

标签: javascript

我正在编写一个函数,该函数需要一个对象并在该对象上调用一个方法。调用函数时,我无法解决this的设置问题。

假设我有这个对象:

myObj = {
  x: 2,
  get: function() {
    return this.x;
  }
};

如果我只是这样做:

callbackEval = function(fn) {
  return fn();
};

然后将其调用为

callbackEval(myObj.get)

这将返回undefined,因为this没有绑定。显然,如果我将其写为

callbackEval(function() {
  return myObj.get() 
});

然后,如我所料,它返回2

但是,如果我传递一个属性名称,而不是传递回调,而是查找该属性,然后调用该函数,则会得到不同的结果。

假设我写了这些变体:

propEval = function(obj, fnName) {
  const fn = obj[fnName];
  return fn();
}

propEval2 = function(obj, fnName) {
  return obj[fnName]();
}

propEval3 = function(obj, fnName) {
  return (obj[fnName])()
}

propEval4 = function(obj, fnName) {
  return (obj[fnName] || true)()
}

并这样称呼他们:

propEval(myObj, "get");
propEval2(myObj, "get");
propEval3(myObj, "get");
propEval4(myObj, "get");

然后,我依次得到:

undefined
2
2
undefined

javascript处理这4个变体之间有什么区别?为什么我们在thispropEval2中而不是在propEval3中进行呼叫,为什么绑定propEval4

2 个答案:

答案 0 :(得分:2)

部分答案:this是一个函数的参数。它是第0个参数,以特殊方式隐藏或传递给它(或显式方式-使用callapply)。顺便说一句,也没有方法,只是碰巧是对象属性的函数。如果您通过以下方式调用函数:foo.bar()(=== foo['bar']()),则隐式传递给它foo作为其this绑定。当您以这种方式调用它时:bar(),您不会。

因此:propEval-没有对象,没有this绑定。

propEval2-调用所谓的“方法”的经典示例。

propEval3-()与此处无关。使用或不使用它们,对表达式的求值都是相同的,成员访问运算符和函数调用运算符具有相同的优先级。

propEval4-看起来像上面的那个,不是吗?哈哈!它的实际作用是首先计算表达式(obj[fnName] || true),然后调用结果。可能还是

const someTemporaryVariable = obj[fnName] || true;
return someTemporaryVariable();

我想。

答案 1 :(得分:1)

propEval1,当您调用函数myObj.get时,myObj被作为“ this”上下文传递。调用fn时,您是在没有上下文的情况下调用函数,因此使用了封闭的上下文。注意提供的上下文取决于调用函数的位置以及是否存在.

propEval2propEval3相同(括号无关紧要),因为您始终将函数作为myObj的属性来调用。 myObj.getmyObj['get']相同。

propEval4我还没看过,但是||似乎它会评估条件,然后执行条件的返回,该返回将作为对函数的引用,从而导致类似于propEval1的操作。