如何在傳入 Array.forEach() 的 Function 使用 this ?

栏目: JavaScript · 发布时间: 7年前

内容简介:ECMAScript 5ECMAScript 2015

Array.prototype 下的 method 都要我們傳入 Function,若該 Function 含有 this 想讀取 Object 的 Property,就會出現錯誤,該怎麼解決這個常見的錯誤呢 ?

Version

ECMAScript 5

ECMAScript 2015

For Loop

const student = {
  name: 'Sam',
  friends: ['Kevin', 'John', 'Mike'],
  sayHello: function() {
    for(let i = 0; i < this.friends.length; i++)
      console.log(`${this.name} say Hello to ${this.friends[i]}`);
  }
};

student.sayHello();

一個常見的 OOP 需求,object 內有 property,而 method 想要讀取 property 的值。

若使用 for loop 搭配 this 讀取 property,則完全沒有問題。

如何在傳入 Array.forEach() 的 Function 使用 this ?

const student = {
  name: 'Sam',
  friends: ['Kevin', 'John', 'Mike'],
  sayHello: function() {
    this.friends.forEach(function(friend) {
      console.log(`${this.name} say Hello to ${friend}`);
    });
  }
};

student.sayHello();

若將 for loop 改成 Array.prototype 的 forEach() 後, this 成為 undefined

因為 sayHello()student 的 method,所以 this 指向 student ,但傳入 forEach() 的 function 並不是 student 的 method,所以 this 指向 undefined

這該怎麼解決呢 ?

Self

const student = {
  name: 'Sam',
  friends: ['Kevin', 'John', 'Mike'],
  sayHello: function() {
    const self = this;
    this.friends.forEach(function(friend) {
      console.log(`${self.name} say Hello to ${friend}`);
    });
  }
};

student.sayHello();

最傳統、最常見的方法就是將 this 指定給 self ,如此傳入 forEach() 的 function 可透過 Closure (Lexical Scope) 存取 self

如何在傳入 Array.forEach() 的 Function 使用 this ?

Bind

const student = {
  name: 'Sam',
  friends: ['Kevin', 'John', 'Mike'],
  sayHello: function() {
    this.friends.forEach(function(friend) {
      console.log(`${this.name} say Hello to ${friend}`);
    }.bind(this));
  }
};

student.sayHello();

既然傳入 forEach() 的 function 的 this 不見了,我們可以透過 bind() 再度將 this 綁定進去。

如何在傳入 Array.forEach() 的 Function 使用 this ?

forEach 傳入 this

const student = {
  name: 'Sam',
  friends: ['Kevin', 'John', 'Mike'],
  sayHello: function() {
    this.friends.forEach(function(friend) {
      console.log(`${this.name} say Hello to ${friend}`);
    }, this);
  }
};

student.sayHello();

其實 Array.prototype 下的 method,除了傳入 function 外,還有第二個參數,可以將 this 傳進去。

如何在傳入 Array.forEach() 的 Function 使用 this ?

Arrow Function

const student = {
  name: 'Sam',
  friends: ['Kevin', 'John', 'Mike'],
  sayHello: function() {
    this.friends.forEach(friend => console.log(`${this.name} say Hello to ${friend}`));
  }
};

student.sayHello();

最漂亮的解法是改用 ECMAScript 2015 的 Arrow Function,它沒有自己的 this ,而會使用 parent scope 的 this ,也就是 sayHello()this ,因此可以順利讀取到 object 的 property。

Conclusion

  • 只要在 object 的 method 中,傳入 Anonymous Function 到其他 function 中,卻又試圖存取 object 的 property,就會踩到這個雷,有多種解法可以解決,但最優雅的就是 ECMAScript 2015 的 Arrow Function

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Where Wizards Stay Up Late

Where Wizards Stay Up Late

Katie Hafner / Simon & Schuster / 1998-1-21 / USD 16.00

Twenty five years ago, it didn't exist. Today, twenty million people worldwide are surfing the Net. "Where Wizards Stay Up Late" is the exciting story of the pioneers responsible for creating the most......一起来看看 《Where Wizards Stay Up Late》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

随机密码生成器
随机密码生成器

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具