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, 也无法再替换其他对象了