这是我参与更文挑战的第1天,活动详情查看: 更文挑战
当前方法中对于obj.objAge是因为objAge:this.age是在定义时候这个this指向的是window所以才是17,但是obj.myFun()是在执行的时候this指向了obj对象,但是由于当前对象中并没有age这个属性所以是undefined
这个三个主要都是用来重新定义this的指向问题的
call和apply看起来使用方式是一样的,但是bind是返回了一个函数,再这次那个一次才能输出
call的参数(想要将this指向的对象,参数1,参数1...);
apply的参数(想要将this指向的对象,[参数1,参数1,....])
bind的参数(想要将this指向的对象)(参数1,参数2,参数3)
总结:
这个三个方法都是用来改变this指向的,但是call和apply方法都是立即执行函数,在调用了call之后就会立即执行被指定的方法。但是bind是返回一个函数,可以在任何时候被调用
Call的源码实现过程
call的使用代码
var demo = {
name:"账户",
age:16
}
var demo2 = {
name :'demo2',
age:12,
getAge:function(){
console.log(this.age)
}
}
demo2.getAge() // 未使用call的时候 12
demo2.getAge.call(demo) // 使用call函数之后 16 ,其中的this指向了demo对象
myCal的实现流程
-
如何将
myCall函数绑定到demo2.getAge方法上-
将
myCall方法绑定到函数的原型上 -
Function.prototype.myCall = myCall
-
-
如何在
myCall中获取到demo2.getAge方法-
该方法在可以在函数内部的
this中获取到 -
function myCall(obj){ obj.myFunc = this }
-
-
如何在
myCall方法中直接值函数呢?-
直接在函数内容调用方法就好了
-
function myCall(obj){ obj.myFunc = this obj.myFunc() }
-
-
现在执行完成之后传入参数的对象中多了个
myFunc方法-
直接函数内删除方法即可
-
function myCall(obj){ obj.myFunc = this obj.myFunc() delete obj.myFunc }
-
-
避免
myFunc会覆盖Function.property中原有的方法-
Symbol可以确保方法名称是唯一,不会覆盖原型中的其他方法let name = Symbol(new Date().getTime()) obj[name] = this
-
-
对于
getAge中的函数如果存在参数的话-
获取传入的参数放置到内部函数中
-
let args = [...arguments].slice(1) obj[name](...args)
-
全部代码
function myCall(obj){
let name = Symbol(new Date().getTime())
obj[name] = this
let args = [...arguments].slice(1)
obj[name](...args)
delete obj[name]
}
Function.prototype.myCall = myCall
var demo = {
name:"账户",
age:16
}
var demo2 = {
name :'demo2',
age:12,
getAge:function(args1,args3){
console.log(this.age,args1,args3)
}
}
demo2.getAge.myCall(demo,3,4,5,56)
Apply方法的实现
function myCall(obj){
let name = Symbol(new Date().getTime())
obj[name] = this
let args = arguments[1] || []
obj[name](...args)
delete obj[name]
}
Bind方法的实现
-
之前绑定方法的方式和
call方法的实现一样function myBind(obj){ let fn = this return function(...newsArray){ return fn.apply(obj,newsArray) } }