Day7 函数中的this

154 阅读2分钟

Day7打卡 函数中的this

每日一名

Spring cleaning can't wait.

释义:春季大扫除事不宜迟!

函数中的this指向问题

一定不看在哪定义,一定是看在哪调用的

1.回顾this使用场景

1.obj.fun(); // this指向的是.前的obj
2.new 构造函数; // this指向是new创建的新对象
3.构造函数的prototype;// 如构造函数.prototype.方法名,调用时是对象.方法名() this指向的是方法名.前的对象
4.fun()、普通函数、匿名函数、回调函数 this -> window, 因为这些函数前没有.,也没有new; 严格模式是undefine. 5.在DOM事件中 // this指向的是当前正在触发事件的dom元素对象 button.onclick = function() {} button.addEventListener('click', function(){}) (这里不能用箭头函数,一旦更换,this指向是个层Window)
6.在Vue中 // this指向的是当前vue对象, 如果要获得当前元素对象,需要借助e.target和$event一起使用
7.箭头函数 // this是指当前函数之外最近作用域中的this (a.几乎所有匿名函数都可以箭头函数简化;b.箭头函数是对大多数匿名函数的简写)

当然不是函数都可以用箭头函数,如下:

var obj = {
  name: 'zs',
  has: ['apple', 'pear', 'banner'],
  say: function() {
     this.has.forEach(function(item){
     // 回调this,指向window
        console.log(`${this.name}${item}`)
     })
  }
}
obj.say(); 
// 有apple
// 有pear
// 有banner

把上面的回调函数改成箭头函数

var obj = {
  name: 'zs',
  has: ['apple', 'pear', 'banner'],
  say: function() { // 此处不能改成箭头函数,一改this指向了外层window
     this.has.forEach((item) => {
        console.log(`${this.name}${item}`)
     })
  }
}
obj.say(); 
// zs有apple
// zs有pear
// zs有banner

小结:普通函数转箭头函数

函数中没有this
刚好内部的this跟外部的this一致时

反过来,如果希望内部的this和外部的this不一致时,则不能改为箭头函数

在es6中为对象方法提供了一种不带function简写

var 对象 = {
   属性名:值,
   方法名() { this.属性值 } (不带function, 又不影响this)
}

箭头函数没有作用域吗?

因为箭头函数只影响this,不影响箭头函数内的局部变量,所以依然有作用域

为啥箭头函数只影响this?

是因为箭头函数的底层原理,就是bind!!!

那箭头函数里的this能不能用call实现?

不行,因为箭头函数的底层是bind,被bind绑定的this是永久替换,所以不能再改变。

8.可以用call,apply, bind替换函数中的this

  • call, apply 是临时替换
  • bind 是永久替换

替换函数中this3种情况:

1.一次调用临时替换一次,可用call. call 做了3件事:

1) 立即调用.前的函数;2)自动将.前函数中的this替换成新对象;3)向调用函数中传实参

2.如果多个实参值是一个数组,需要将数组拆散再传参,可用apply

1)立即调用.前的函数;2)自动将.前函数中的this替换成新对象;3)先拆散数组转成多个元素值,再传给函数的形参

3.以上是临时替换,每次都要call很麻烦!如果想永久替换,用bind创建函数副本并永久绑定this

1) var 新函数 = 原函数.bind(替换的this对象); 2) 替换新函数中this为指定对象

调用的时候直接用新函数即可。

被bind()永久绑定的this,即使使用call, 也无法再替换其他对象了