this的指向
1. 非箭头函数的this指向
this指向:谁调用,指向谁
-
① 以普通函数的形式调用,this永远指向Window
// 1.普通函数 // "use strict"下 this的指向是undefined function fn1() { console.log('this指向:', this) // Window } fn1() // 普通函数的this指向是Window,严格模式下是undefined
-
② 以方法的形式调用,this指向的是方法调用时对应的对象
// 2.对象中的方法 let obj = { name: '胖丁', age: 22, eat: function () { console.log('this指向:', this) // obj对象 function fn() { console.log('this指向:', this) // 普通函数的this指向都是Window } fn() } } // 以方法的形式调用,this的指向是方法对应的对象 obj.eat()
-
③ 以构造函数的形式调用,this指向构造函数的实例化对象
// 3.构造函数中的方法 function Fn2(name) { this.name = name this.sleep = function () { console.log(`${this.name}` + '爱睡觉') // 芳芳爱睡觉 console.log('this的指向:', this) // 构造函数实例化的对象conFn2 } } Fn2.prototype.run = function(){ console.log(this) // 构造函数实例化的对象conFn2 } let conFn2 = new Fn2('芳芳') conFn2.sleep() conFn2.run() // 以构造函数的形式调用时,this指向就是构造函数的实例化对象
2. 箭头函数this指向
-
箭头函数的this指向在
定义(声明)
的时候,继承自外层第一个普通函数的thisconst ArrowOut = () => { console.log('声明在函数外的箭头函数的this指向:', this) // window } function ArrowPoint() { console.log('ArrowPoint中的this的指向', this) // obj对象 const ArrowInt = () => { console.log('声明在函数内的箭头函数的this指向:', this) // obj对象 } // 调用两个箭头函数 ArrowOut() ArrowInt() } const obj = { name: '胖丁' } ArrowPoint.call(obj)
-
箭头函数没有prototype(原型对象),所以说箭头函数本身上没有this
-
箭头函数不能作为构造函数
let a = () => { console.log('this的指向:', this) } console.log(a.prototype) // undefined
-
在构造函数中声明的箭头函数
-
this指向构造函数对应的实例化对象,在原型链上声明的箭头函数指向window,在原型链上对应的方法中声明的箭头函数指向构造函数的实例化对象
function Fn1() { console.log('Fn1中this指向:', this) // 指向构造函数实例化对象 const fn1 = () => { console.log('fn1中this指向:', this) // 指向构造函数实例化对象 } fn1() } // 箭头函数在原型链上的this指向 Fn1.prototype.eat = () => { console.log('Fn1中原型链箭头函数this指向:', this) // window } Fn1.prototype.run = function () { console.log('Fn1中原型链普通函数this指向:', this) // 指向构造函数实例化对象 const fn2 = () => { console.log('Fn1中原型链普通函数里箭头函数的this指向:', this) // 指向构造函数实例化对象 } fn2() } const conFn1 = new Fn1() conFn1.eat() conFn1.run()
-
在对象方法中声明的箭头函数
-
在对象中声明的箭头函数方法this指向window,在对象方法中声明的箭头函数指向方法对应的对象
let arrowObject= { name:'死胖丁', eat:()=>{ console.log('箭头函数在对象中的this指向:',this) // window }, sleep:function(){ const arrObj = ()=>{ console.log('在对象方法中this指向:',this) // 对象方法对应的对象arrowObject } arrObj() } } arrowObject.eat() arrowObject.sleep()
-
箭头函数的this指向是无法被改变的
-
call(),apply(),bind()无法直接修改箭头函数的this指向(箭头函数会忽略第一个参数,还是可以正常传参)
const obj1 = { name: '小胖丁' } const unChangeArrowFn = (name) => { console.log('箭头函数中的this指向是否被改变了:', this, name) // window,小猪 } function changeFn() { console.log('普通函数中this的改变:', this) // 对象obj1 } changeFn.call(obj1) unChangeArrowFn.call(obj1, '小猪')