针对普通函数 this 指向改变
1. call / bind (param1, pram2,....)
第一个参数是新的指向,后面都是参数,可以传入多个字符串
call会立即执行 ,bind需要手动执行
2. apply(param1, [pram2,....])
第一个参数是新的指向,后面是参数(数组形式),会立即执行
例子:
let obj1 = {name:'当前对象的name', sayName: function (val)
{console.log('name=====', this.name)}}
打印:name===== '当前对象的name'
改变指向:
let obj2 = {name:'对象obj2的name'}
obj1.sayName.call(obj2) / obj1.sayName.apply(obj2)
打印:name===== '对象obj2的name'
bind需要手动执行:
let obj3 = {name:'对象obj3的name'}
obj1.sayName.bind(obj3)()
打印:name===== '对象obj3的name'
普通函数与箭头函数的不同:
(1)首先是this的指向,普通函数的this 是动态的,谁调用该函数指向谁,普通函数如果前面没有明确的对象调用,非严格情况下 都是指向window; 箭头函数的指向是静态的,函数创建的时候this指向就确定了,不是调用时确定;
(2)箭头函数 不能使用new 来创建实例对象;不能作为构造函数使用;
(3)箭头函数 没有显示原型prototype, 只有隐式原型__proto__; 一个普通函数这两种都有;
(4) 箭头函数本身是没有 arguments 属性;可以使用reset参数来替代
(5) 普通函数可以是具名和匿名函数;箭头函数是匿名函数
(6) 普通函数可以先调用后声明;箭头函数不可以
哪些最好不要用箭头函数:
(1)在原型上挂载方法的时候
Function.prototype.custCall = function () {
console.log('arguemts====' , arguments) // 所有参数 第一个参数是设置的新的指向
let context = arguments[0] // 新的指向
context.fn = this // obj.getName 要调用的方法
var arr = [...arguments]
arr.splice(0,1)
console.log('arr', arr)
context.fn(...arr)// 利用谁调用指向谁 最终指向context 也就是新的指向
}
然后再次调用obj1.getName.custCall(obj2, 'custStr1', 'custStr2')
如果custCall 是箭头函数,那么 this 指向的是windown 而不是调用该函数的那个对象
(2)一个对象内部的属性是方法的时候,该方法最好不用箭头函数,
let obj = {
name: 'lisi',
sayName: function () {
retun this.name
}
}
obj.sayName() // 此时this 指向 obj 对象
如果写成箭头函数, this指向 window 对象 严格模式下 指向undefined
(3)vue 的生命周期函数 不要用箭头函数, 否则this 指向的是undefined ,而不是当前组件实例
错误写法:
mounted: () => {} // this 指向undefined
正确写法
mounted(){} // this 指向当前组件实例对象
如果对你有帮助,麻烦点个赞 谢谢~~