在下面的代码片段中解释“this”的值的变化?

时间:2016-04-13 00:18:42

标签: javascript this

function wrap(func) {
  console.log('0', this)
  return function x() {
    console.log('1', this)
    func()
    return function z() {
      console.log('3', this)
    }
  }
}

var obj = {
  x: 5,
  test: wrap(function y() {
    console.log('2', this)
  })
}

obj.test()()

上面的代码记录

// 0 Window
// 1 Object
// 2 Window
// 3 Window

我无法理解是什么决定了this的价值。

// 0 Window有意义,因为这是首次调用wrap时,此时它的值this不应设置为obj

// 1 Object有意义obj.test现在等于function x(),正确记录thisobj

// 2 Window我不确定为什么会这样。为什么this的值不会传播到func()?我以为this应该是指函数的所有者。这是否意味着即使在obj中创建了function y(),它也会以某种方式被提升到窗口?

// 3 Windowfunction z()同样,为什么this的值未从function x()传递下来。 this的价值不应该传播到那里吗?

2 个答案:

答案 0 :(得分:0)

'this'绑定非常令人困惑。但是,如果您记住以下规则,则会更容易理解。根据Javascript文档,这些订单中有'this'绑定有四个规则:

  1. new operator
  2. 通过调用或应用方法进行显式或硬性绑定
  3. 与包含对象的隐式绑定,如对象的方法
  4. 默认(全局)
  5. 从您的脚本中,只有规则#3和#4适用,因为没有新的运算符和调用或应用方法。

    所以解释是:

    // 0窗口 - 规则#4默认(全局)

    // 1对象 - 规则#3与包含对象的隐式绑定,就像对象的方法一样,在你的情况下是obj.test

    // 2窗口 - 规则#4默认(全局)

    // 3窗口 - 规则#4默认(全局)

答案 1 :(得分:0)

以下,准确指导this文章,按顺序,函数调用desugar

  • wrap.call(window, function() {})
  • obj.test.call(obj)
  • y.call(window)
  • z.call(window)

要记住的是this 通过函数声明传播。 this的值完全取决于函数的调用方式。

我感到困惑的原因是因为我已经习惯了箭头功能,这为你保留了this的价值。

function wrap(func) {
  return () => {
    console.log(this)
    return () => {
      console.log(this)
      func()
      return () => console.log(this)
    }
  } 
}

这令人厌恶

function wrap(func) {
  var _this = this;

  return function () {
    console.log(_this);
    return function () {
      console.log(_this);
      func()
      return function () {
        return console.log(_this);
      };
    };
  };
}

并显示您必须明确传递this的值。虽然即使使用箭头功能,但重要的是要注意对func的调用不会保留this的值。我需要做func.call(this)才能做到这一点。