使用箭头函数应该注意什么?

使用箭头函数应该注意什么?

箭头函数没有它自己的this值,箭头函数内的this值==继承==自外围作用域。导致内部的this就是外层代码块的this。正是因为它没有this,所以也就==不能用作构造函数、原型对象、对象里面定义函数、事件回调函数(这四样一般指向外层window,造成本身代码的bug)==。

==简单对象(非函数)是没有执行上下文的!==
箭头函数this的具体含义,应该==继承的是执行上下文==里面的this

不要在对象里面定义函数,对象里面的行数应该用传统的函数方法

const test = {
    array: [1, 2, 3],
    sum: () => {
        console.log(this === window); // => true
        return this.array.reduce((result, item) => result + item);
    }
};
test.sum();
//因为 test.sum()是在全局环境下进行调用,此时this指向全局
//改:
const test = {
    array: [1, 2, 3],
    sum() {
        console.log(this === test); // => true
        return this.array.reduce((result, item) => result + item);
    }
};
test.sum();

不要在对原型对象上定义函数,在对象原型上定义函数也是遵循着一样的规则

Person.prototype.sayName = () => {
    console.log(this === window); // => true
    return this.name;
};
//也不能这样,也是用传统函数写法解决

不要用箭头定义构造函数

如果使用箭头函数会报错。
显然,箭头函数是不能用来做构造函数。

const Message = (text) => {
    this.text = text;
     console.log(this === window); // => true,与下面的例子不同这里的箭头函数写在了外层this指向window
};
const helloMessage = new Message('Hello World!');
// Throws "TypeError: Message is not a constructor"

不要用箭头定义事件回调函数

箭头函数在声明的时候就绑定了执行上下文,要动态改变上下文是不可能的,在需要动态上下文的时候它的弊端就凸显出来:
定义事件回调函数

const button = document.getElementById('myButton');
button.addEventListener('click', () => {
    console.log(this === window); // => true,this是window,箭头函数当做参数传入,他的this是window
    this.innerHTML = 'Clicked button';
});
//解决办法仍然是用传统函数写法解决
const button = document.getElementById('myButton');
button.addEventListener('click', function() {
    console.log(this === button); // => true这时this回到Button本身
    this.innerHTML = 'Clicked button';
});

关于箭头函数中的this的指向

==箭头函数没有自己的this, 它的this是继承而来;==

==默认指向在定义它时所处的对象(宿主对象--父执行上下文,外层环境),而不是执行时的对象, 定义它的时候,可能环境是window;==

例如这段函数中,this指向的是Person对象,可以看到控制台打印结果,此时的箭头函数所处的宿主对象是Person,所以this指向的是person
image
image

普通函数中的this:

下面看这样一段代码,非箭头函数,就指向调用他的window ,settimeout是window全局方法
image
,打印‘我叫 我今年 岁’

  1. this总是代表它的直接调用者(js的this是执行上下文), 例如 obj.func ,那么func中的this就是obj

2.在默认情况(非严格模式下,未使用 'use strict'),没找到直接调用者,则this指的是 window (约定俗成)

3.在严格模式下,没有直接调用者的函数中的this是 undefined

4.使用call,apply,bind(ES5新增)绑定的,this指的是 绑定的对象

例子

//以下代码会输出33,11而不是33,22
var x = 11;
    var obj = {
      x: 22,
      methods: {
        x: 33,
        say: function () { console.log(this.x) },
        say2: () => { console.log(this.x) }
      }
    }
  
    obj.methods.say();//methods调用,methods的x是33
    obj.methods.say2();//简单对象没有上下文,this指向object父执行上下文window
    
//以下代码会输出1,而不是100 
var age = 99;
  
    function PersonX() {
      this.age = 0;
      setTimeout(() => {
        this.age++;
        console.log(age)
      }, 1000);
    }
  
    PersonX();
    //构造函数作用域里的箭头函数this指向父作用域person,0+1=1

猜你喜欢

转载自www.cnblogs.com/chenluqing/p/11901051.html
今日推荐