定义
- this是执行上下文的一个属性,它指向最后一次调用这个方法的对象
判断this指向的四种方式
- 函数调用模式
- 当一个函数不是一个对象的属性时,直接作为函数来调用,this指向全局对象
- 方法调用
- 如果一个函数作为一个对象的方法来调用时,this指向这个对象
- 构造器调用模式
- 如果一个函数用new调用时,函数执行前会创建一个对象,this指向这个新创建的对象
- apply、call、bind调用模式
- 都可以显示地指定调用函数的this指向
- apply接收两个参数,一个是this绑定的对象,后面的其余参数是传入函数执行的参数
function.apply(thisArg,[argsArr])
const person = { fullName: function(city, country) { return this.firstName + " " + this.lastName + "," + city + "," + country; } } const person1 = { firstName:"John", lastName: "Doe" } person.fullName.apply(person1, ["Oslo", "Norway"]);//'John Doe,Oslo,Norway' Math.max.apply(null, [1,2,3]); // 3 const arr = [1,2,3]; const otherArr = [3,4,5]; arr.push.apply(arr,otherArr); console.log(arr); // [1, 2, 3, 3, 4, 5]- call,调用对象的一个方法,以另一个对象替换当前对象,接收参数序列
function.call([thisObj[,arg1[, arg2[, [,.argN]]]]]) - call方法可以用来代替另一个对象调用一个方法,可将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象
- call()方法的作用和apply()方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组
function isArray(object){ return Object.prototype.toString.call(object) == '[object Array]'; //[object Array]表示该对象的类型是数组 } // 借用Object原型上的toString方法来验证下对象是否是数组? function accumulation(){ return [].reduce.call(arguments,(a,b)=>{return a+b}) }- bind
- bind()方法创建一个新的函数,在bind()被调用的时候,这个新函数的this被指定为bind()的第一个参数,而其余的参数将会作为新函数的参数,供调用的时候使用
function bind(thisArg[,arg1[,arg2[, ...]]])- 返回一个原函数的拷贝,并拥有指定的this值和初始参数
const OBJ = { petName: 'kyogre', qq: '2971411050', sayHi: function () { console.log(`我是${this.petName} 很高兴认识你`) } } let sayHi = OBJ.sayHi; sayHi(); //我是undifined 很高兴认识你 ps: this非严格模式指向了window window.petName不存在 let sayHi = OBJ.sayHi.bind(OBJ); sayHi(); //我是kyogre 很高兴认识你 ps:通过bind强制绑定sayHi函数内部的this指向OBJ //bind后sayHi会永久指向OBJ,使用call也无法更改绑定
call、bind、apply区别
- call传入的是参数列表,apply传入的是数组,也可以是类数组
- bind返回的是一个改变了this指向的函数,便于稍后调用,不像call和apply会立即调用;bind和call很像,传入的也是参数列表,但是可以多次传入,不需要像call,一次传入
- 注意:当 bind 返回的函数使用new作为构造函数时,绑定的 this 值会失效,this指向实例对象,但传入的参数依然生效 (new调用的优先级 > bind调用)
// bind 返回的函数 作为普通函数调用
let bindFun = normalFun.myBind(obj, '我是参数传进来的name') // this:obj
bindFun('我是参数传进来的age')
// bind 返回的函数 作为构造函数调用
let bindFun = Person.myBind(obj, '我是参数传进来的name') // this:obj
let a = new bindFun('我是参数传进来的age') // this:a
-------------------------------------------------------------------------------2024.5.12每日一题