call/apply与bind的区别 (参数,等待执行)
执行:
- call/apply改变了函数的this上下文后马上执行该函数
- bind则是返回改变了上下文后的函数,不执行该函数
返回值:
- call/apply 返回fun的执行结果
- bind返回fun的拷贝,并指定了fun的this指向,保存了fun的参数。
function.bind(thisArg[, arg1[, arg2[, ...]]])
thisArg
调用绑定函数时作为 this 参数传递给目标函数的值。 如果使用new运算符构造绑定函数,则忽略该值。当使用 bind 在 setTimeout 中创建一个函数(作为回调提供)时,作为 thisArg 传递的任何原始值都将转换为 object。如果 bind 函数的参数列表为空,或者thisArg是null或undefined,执行作用域的 this 将被视为新函数的 thisArg。
arg1, arg2, ...
当目标函数被调用时,被预置入绑定函数的参数列表中的参数。
返回值
返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。
bind:语法和call一模一样,区别在于立即执行还是等待执行:
var boundGetX = retrieveX.bind(module); //返回一个新的函数
boundGetX(); // 此处才执行
实现步骤:
- 获取this和参数,创建一个空的函数
- 创建一个返回函数,获取参数,拼接参数,
- 判断是否使用new运算符构造绑定函数, if(this instanceof o)
- 使用了,绑定函数的this指向实例化对象,that.apply(this,arrsum)
- 没有使用,绑定函数的this指向传入的目标函数 that.apply(obj,arrsum)
function person(){
console.log(this.name)
}
person.prototype.hh="hhhhhh"
let obj={name:'obj的name'}
Function.prototype.newbind=function(obj){
//person对象
var that=this
var arr=Array.prototype.slice.call(arguments,1)
//用于实现原型链继承
let o=function(){}
var callfn=function(){
var arr1=Array.prototype.slice.call(arguments)
var arrsum=arr.concat(arr1)
if(this instanceof o){
//this指向实例对象
that.apply(this,arrsum)
}else{
that.apply(obj,arrsum)
}
}
//实现原型链的连接
o.prototype=that.prototype
callfn.prototype=new o
return callfn
}
let tt=person.newbind(obj)
tt()