箭头函数的this指向
箭头函数的this指向 是 函数在 声明
的位置的作用域中的this指向。
简单说,箭头函数所在的作用域中(函数体外部那一层),this指向哪,函数内部的this就指向哪。
let obj = {
fn: () => {
console.log(this); // Window对象
}
}
obj.fn()
非箭头函数的this指向
非箭头函数中的this指向问题,大致可分为四种。即默认绑定、隐式绑定、显示绑定和new绑定。
-
默认绑定(指向window)
普通函数调用时函数体中的this
function fn() { console.log(this) // Window对象 } fn() //该调用方式使得函数体内部的this指向window //注意:该调用方式可理解为window.fn()
延时器setTimeout()或定时器setInterval()中的this
setTimeout(function() { console.log(this) // Window对象 },1000) setInterval(function(){ console.log(this) // Window对象 },1000)
特例:在严格模式下,this无法绑定window,此时this指向undefined
"use strict" function fn1(){ console.log(this) // undefined } fn1()
-
隐式绑定(指向调用者)
对象中的函数中的this
let obj = { fn: function() { console.log(this) }, age: 18 } obj.fn() // this指向obj, 谁调用指向谁 let obj = { a: { fn: function() { console.log(this) }, desc: '内部的a' }, desc: '外部obj' } obj.a.fn() // this指向obj.a let p = { name: 'zs', fn: obj.a.fn } p.fn() // this指向p
事件处理函数中的this
let btn = document.querySelector('button') btn.onclick = function() { console.log(this) // this指向事件源, btn }
-
new绑定(指向实例对象)
new绑定即为通过构造函数 new 出新的实例对象时,构造函数中this的指向
function Person (name,age) { this.name = name this.age = age console.log(`我叫${name},我今年${age}岁`) // 我叫zs,我今年18岁 console.log(this) // 指向p实例对象 } let p = new Person('zs',18)
拓展:new的作用
1. 新建一个对象 2. 构造函数体中的this指向这个对象 3. 执行构造函数中的函数体 4. 返回这个对象
-
显示绑定(想让this指向谁,this就指向谁,优先级最高)
call
apply
bind
都可以指定函数执行时的this指向
-
call
调用函数的同时,指定了函数调用时的this指向语法:函数名.call(this指向的内容,参数1,参数2,…)
function fn () { console.log(this) console.log('嘎嘎') } fn() // 默认绑定, 指向window let obj = { name: 'zs' } fn.call(obj) // (1) 立刻执行fn函数 (2) 指定了函数执行时的this指向obj
call 还可以借调构造函数,进行实例的属性扩展
function Person (name, age) { this.name = name this.age = age console.log(this) // obj对象 } let obj = { money: 100 } // 借调构造函数, 扩展了实例的属性 // 简单说使得构造函数中的this指向obj,且obj中扩展了构造函数中的属性 Person.call(obj, '老铁', 20) // (1) 立刻执行Person函数 (2) 指定函数执行时 this指向 console.log(obj) // {money: 100, name: "老铁", age: 20} 拥有构造函数中的属性
-
apply
调用函数的同时,指定了函数调用时的this指向语法:函数名.apply(this指向的内容,[参数1,参数2,…])
function fn () { console.log(this) // obj对象 } let obj = { name: 'zs' } fn.apply(obj) // (1) 立刻执行fn函数, (2) 指定this指向了obj
apply 也可以借调构造函数,进行实例的属性扩展,其结果于call一样
function Person (name, age) { this.name = name this.age = age console.log(this); // obj对象 } let obj = { money: 100 } Person.apply(obj, ['zs', 18]) console.log(obj) // {money: 100, name: "老铁", age: 20}
-
bind
会基于原函数, 得到一个一模一样的新函数, 并且绑定死了新函数的this指向语法:函数名.bind(this指向)
function fn () { console.log(this) } let obj = { name: 'zs' } let newFn = fn.bind(obj) fn() // this指向window 原函数的正常调用 newFn() // this指向obj对象 let obj2 = { name: 'ls' } newFn.call(obj2) // this指向obj对象,原因是bind绑定后返回的新函数的this已绑定死,不可改变