一般地,
- this是个对象;
- 在函数中使用;
- 可用apply、call、bind改变this的指向,null、undefined除外;
- 函数也是个对象
- “谁调用的函数,函数中的this就指向谁”
- 优先级:
new fn()> 显示绑定(bind、call、apply) > 隐式绑定obj.fn()> 默认绑定fn() - 箭头函数中的
this指向父级作用域的this
<script>
function lxx(){
console.log(this);
}
lxx()
</script>
以上代码,相当于在全局环境中定义了个函数,并且调用了函数。换个说法就是,给全局环境中的window对象上定义了个属性lxx,该属性的值是一个函数,调用时相当于window.lxx()。此时window调用了lxx函数,则this指向window。
<script>
var person = {
name: 'lxx',
eat: function(){
console.log(this);
}
}
person.eat()
</script>
以上代码,person调用的eat函数,则eat函数中的this指向person。
<script>
var person = {
name: 'lxx',
eat: function(){
console.log(this);
}
}
var fn = person.eat
fn()
</script>
以上代码,将person对象的eat函数赋值给了fn,然后调用fn函数,相当于window.fn(),此时window调用的eat函数,则eat函数中的this为window。
<script>
function lxx(){
console.log(this);
}
lxx.call('aaa') // 将this指向字符串aaa对象
lxx.apply('bbb') // 将this指向字符串bbb对象
</script>
以上代码,通过call、apply两个函数调用lxx函数,并修改函数中的this指向。
<script>
function lxx(num1, num2){
console.log(num1 + num2, this);
}
lxx.call('aaa', 1, 2) // 参数依次传入
lxx.apply('bbb', [1, 2]) // 参数放到数组中
</script>
以上代码,展示了call、apply两种方式传参的区别。
<script>
function lxx(){
console.log(this);
}
var fn = lxx.bind('aaa')
fn()
</script>
以上代码,使用bind改变了this指向,bind方法可以修改this指向,返回值为一个新的函数,该函数是一个已经绑定了this指向的函数,此时,再调用该函数fn,函数中的this则指向绑定的字符串aaa对象。
<script>
let oDiv = document.getElementById('app')
oDiv.onclick = function(){
console.log(111, this);
}
oDiv.onclick = function(){
console.log(222, this);
}
</script>
以上代码,给一个DOM元素绑定事件处理函数。oDiv是一个对象,onclick是对象上的一个属性,值为一个函数,可以理解成oDiv.onclick(),根据“谁调用指向谁”,此时,函数中的this指向oDiv。另外此种方式只可绑定一个事件处理函数,下边的会覆盖掉上边的。相当于给onclick属性赋值了一个新函数。
<script>
let oDiv = document.getElementById('app')
oDiv.addEventListener('click', function(){
console.log(111, this);
})
oDiv.addEventListener('click', function(){
console.log(222, this);
})
</script>
以上代码,是给DOM对象绑定事件处理函数的另一种方式,此种方式可以给一个DOM对象绑定多个事件处理函数,这里猜测:内部实现可能是收集绑定的多个函数,当调用函数时使用显示绑定(call等)的方法修改函数中的this指向fn.call(oDiv)。
<script>
[1,2,3].forEach(function(item){
console.log(item, this);
}, 'aaa')
</script>
以上代码,是数组的forEach方法,当迭代数组中的每一项时,独立执行回调函数,此时this的指向为window。也可以通过传递forEach的第二个参数来修改回调函数中的this指向,此时this的指向为字符串对象aaa。