Discuss / JavaScript / 一个非常有代表性的例子

一个非常有代表性的例子

Topic source
name = "window";
var obj = {
  name: "obj",
  func0: () => {
    console.log(this.name);
    return () => console.log(this.name);
  },
  func1: function() {
    console.log(this.name);
    return function() { console.log(this.name); };
  },
  func2: () => {
    console.log(this.name);
    return function() { console.log(this.name); };
  },
  func3: function() {
    console.log(this.name);
    return () => console.log(this.name);
  }
}
var env = {
  name: "env",
  func0: obj.func0(), // window
  func1: obj.func1(), // obj
  func2: obj.func2(), // window
  func3: obj.func3()  // obj
}
env.func0(); // window
env.func1(); // env
env.func2(); // env
env.func3(); // obj

LeoDamnHot

#2 Created at ... [Delete] [Delete and Lock User]

有大神解释一下这个吗 没看懂为什么env.func3() 是 obj

env.func3(); // obj

玩转ACE

#3 Created at ... [Delete] [Delete and Lock User]

这个要结合闭包的概念一起来理解了“闭包是携带状态的函数”。

1、语句 `env.func3()` 中保存的代码:

env.func3(); // 保存的是箭头函数:() => console.log(this.name);

2、箭头函数中的 this 默认指向外层 this 值,我们再来看看 `func3` 中的语句:

func3: function () {
        console.log(this.name);
        return () => console.log(this.name);
    }

根据箭头函数 this 的定义,改写下代码:

func3: function () {
  console.log(this.name);
  var that = this;
  return funciont () {
    console.log(this.name);
  };
}

3、回顾下闭包的定义:“当一个函数返回了一个新的函数后,其内部的局部变量还被这个返回的新函数引用!”,由于“箭头函数中的 this 默认指向外层 this 值”,因此下面代码中返回的新的函数中的 this 变量,一直会指向他的外层 this:

funciont () { console.log(this.name); };

4、再来看下,新函数的外层对象的指向:

func3: obj.func3()  // env 中的 func3 的赋值语句

// obj.func3 的定义:1、匿名函数;2、打印并返回一个箭头函数
function () {
  console.log(this.name);
  return () => console.log(this.name);
}

此时,当执行 `obj.func3()` 时,`console.log(this.name)` 中的 this 指向当前对象 `obj`。综上,所以在 `env.func3()` 调用时,其中的箭头函数保存了外层函数的状态变量 this,指向 obj

https://juejin.cn/post/6844903746984476686

ES6 中的箭头函数:不会使用上文的四条标准的绑定规则, 而是根据当前的词法作用域来决定this, 具体来说, 箭头函数会继承外层函数,调用的 this 绑定( 无论 this 绑定到什么),没有外层函数,则是绑定到全局对象(浏览器中是window)。

个人理解

如果是箭头函数就得看它在哪 如果是匿名函数就看它的实际调用环境

func0: obj.func0(), // window          箭头函数 实际在obj中 但按照箭头函数的this规则 应该是上一层函数 虽然在var对象里 但其实属于window环境
func1: obj.func1(), // obj             匿名函数 调用环境为obj 因此为obj
func2: obj.func2(), // window          箭头函数 同func0
func3: obj.func3()  // obj             匿名函数 同func1
  
env.func0(); // window                 箭头函数 实际在obj中的箭头函数中 因此为obj中箭头函数的this(window)
env.func1(); // env                    匿名函数 调用为env
env.func2(); // env                    匿名函数 调用为env
env.func3(); // obj                    箭头函数 调用为obj中的匿名函数 此时this为obj

Cool

#6 Created at ... [Delete] [Delete and Lock User]

这样说来,传统函数中this根据调用时上下文确定

箭头函数this在定义时根据当前上下文已经确定,调用时this不会根据上下文变化而变化


  • 1

Reply