ES6箭头函数、继承、this指针的一点小问题

发布于 2022-09-04 11:37:19 字数 621 浏览 16 评论 0

const base = { name: 'HAHA' }
let ob = Object.create(base)
ob = {
  showName() {
    console.log(this, this.name);
  },
  showNameArrow: () => {
    console.log(this, this.name);
  }
}
ob.showName();  // Object{}   undefined
ob.showNameArrow();   //  window{}   ""

第一个showName的this既然指向ob对象,但是this.name为什么不能通过原型向上查找到{name: 'HAHA'},而是undefined呢?


第二个showNameArrow是因为我不知道在对象里如何写箭头函数:

  1. 是不是在对象里面因为不涉及块级作用域,就没有必要写箭头函数?

  2. 但是如果要写,应该怎么写?

  3. 我这种写法的箭头函数为什么指向全局?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

维持三分热 2022-09-11 11:37:19

第一个showName的this既然指向ob对象,但是this.name为什么不能通过原型向上查找到{name: 'HAHA'},而是undefined呢?

重覆声明,被盖掉了。如果要合成两个对象用Object.assign方法,例如:

const base = { name: 'HAHA' }

let obj = {
  showName() {
    console.log(this, this.name);
  },
  showNameArrow: () => {
    console.log(this, this.name);
  }
}

let ob = Object.assign(base, obj)

第二个showNameArrow是因为我不知道在对象里如何写箭头函数:
是不是在对象里面因为不涉及块级作用域,就没有必要写箭头函数?但是如果要写,应该怎么写?

对象字面文字定义时,不会用箭头函数,这算是例外的应用情况。尤其是代码中有用到this时,大部份都不用箭头函数,不是不能用的问题,而是会得到不如预期的结果。其它还有常见的例外应用情况例如:

  • 在对象的prototype属性中定义的方法

  • DOM事件处理的监听者(事件处理函数)

  • 构造函数

以及常见的箭头函数的应用上陷阱:

  • 函数对象中的call、apply、bind三个方法,无法"覆盖"箭头函数中的this值。

  • 箭头函数没有原本(传统)的函数有的隐藏arguments对象。

  • 箭头函数不能当作generators使用,使用yield会产生错误。

  • 在一些函数库像jQuery、underscore函数库有些有使用callback(回调, 回呼)的API中不一定可以用。

我这种写法的箭头函数为什么指向全局?

因为箭头函数会以对象在字面文字定义时,捕捉到的周边this为预设this,也就是window(浏览器)或全局对象(node),或是在严格模式下的undefined

下面是另一个例子,与题主的例子相似,这例子中演示访问不到对象中的array属性值。

const calculate = {
  array: [1, 2, 3],
  sum: () => {
    return this.array.reduce((result, item) => result + item)
  }
}

//错误: TypeError: Cannot read property 'reduce' of undefined
calculate.sum()

所以,这其实就是为什么在对象字面文字定义中,不要使用箭头函数的理由。你的问题已经自问自答了。

上面的例子与一些内容,主要参考自这篇: When 'not' to use arrow functions

栩栩如生 2022-09-11 11:37:19

第一个问题:

当程序运行到let ob = Object.create(base),ob.name=== 'HAHA'没问题;

但是当程序运行到

ob = {
  showName() {
    console.log(this, this.name);
  },
  showNameArrow: () => {
    console.log(this, this.name);
  }
}

ob对象被重写,name属性自然就不存在了,这个时候ob就等于现在定义的了。
要想showName访问到name可以这么写:

 ob.showName=function(){
    console.log(this, this.name);
}

第二个问题:

箭头函数里面没有自己的this,它的this都是继承自它的外部,这里是window调用了showNameArrow,所以this指向window

据说name在es6中是一个关键字,在这里window下的name没有被定义所以是""。

关于箭头函数的this可以看这里

最冷一天 2022-09-11 11:37:19

先理解this吧,只有很清楚当前的this指向谁时,自然就知道箭头该不该用了

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文