均用于改变this指向。call和apply立即执行,bind延迟执行。
let fn = function(a,b){
console.log(this,a,b);
}
let obj = {name:"obj"};
fn.call(obj,1,2)
fn.apply(obj,[1,2])
fn.bind(obj,1,2)
call
win.p = this
this在被调用时指向调用对象
//es5
Function.prototype.newCall = function(win){
var win = win || window;
win.p = this;
var newArgs = [];
for(var i =0;i<arguments.length;i++){
newArgs.push('arguments[' + i + ']');
}
var result = eval('win.p(' + newArgs + ')')
delete win.p
return result
}
//es6
Function.prototype.newCall = function(win,...arr){
var win = win || window;
win.p = this;
var result = win.p(...arr)
delete win.p
return result
}
function perrson(a,b){
return{
name:this.name,
a:a,b:b
}
}
var dog = {name:"白白"}
var bb = perrson.newCall(dog,"更快","更高")
console.log(bb) //{ name: '白白', a: '更快', b: '更高' }
apply
//es5
Function.prototype.newApply = function(win,arr){
var win = win || window,result;
win.p = this;
if(!arr) {
result = win.p()
}else{
var newArgs = [];
for(var i =0;i<arr.length;i++){
newArgs.push('arr[' + i + ']');
}
var result = eval('win.p(' + newArgs + ')')
}
delete win.p
return result
}
//es6
Function.prototype.newApply = function(win,arr){
var win = win || window,result;
win.p = this;
if(!arr) {
result = win.p()
}else{
result = win.p(...arr)
}
delete win.p
return result
}
function perrson(a,b){
return{
name:this.name,
a:a,b:b
}
}
var dog = {name:"白白"}
var bb = perrson.newCall(dog,["更快","更高"])
console.log(bb) //{ name: '白白', a: '更快', b: '更高' }
bind
//es5
Function.prototype.newBind = function(win){
if(typeof this !== "function"){
throw new TypeError("错误")
}
var that = this,
arr = Array.prototype.slice.call(arguments,1),
o = function(){},
newf = function (){
var arr2 = Array.prototype.slice.call(arguments),
arrsum = arr.concat(arr2)
if(this instanceof o){
that.apply(this,arrsum)
}else{
that.apply(win,arrsum)
}
}
o.prototype = that.prototype;
newf.prototype = new o
return newf
}
网友评论