call,apply,bind 实现
/**
* 实现
* call ,
* apply ,
* bind
*/
var c = {
name:‘huge‘,
age:1236
}
var d = {
name:‘huge‘,
age:1236
}
function Person(sex,hobby,other){
this.other = other;
this.sex = sex;
this.hobby = hobby;
this.wife = "五";
}
Function.prototype.myCall = function(context){
//不传默认为window
var context = context || window,
result;
context.myFnTmp = this;
// ES6 的话 用如下方法展开;
// var args = Array.prototype.slice.call(arguments,1);
// result = context.myFnTmp(...args);
// 用eval
var args =[];
for(var i = 1;i < arguments.length; i++){
args.push("arguments["+i+"]");
}
result = eval("context.myFnTmp("+args+")")
delete context.myFnTmp;
return result;
}
// Person.myCall(c,‘女‘,‘00‘);
// Person.myCall(d,‘男‘,‘99‘);
// console.log(c); console.log(d);
Function.prototype.myApply =function(context,arr){
//不传默认为window
var context = context || window,
result;
context.myFnTmp = this;
// 用eval
var arr =arr || [],
args = [];
for(var i = 0;i < arr.length; i++){
args.push("arr["+i+"]");
}
result = eval("context.myFnTmp("+args+")")
delete context.myFnTmp;
return result;
}
// Person.apply(c,[‘女‘,‘00‘]);
// Person.myApply(d,[‘男‘,‘99‘]);
// console.log(c); console.log(d);
// 缺陷 ; 当执行实例化操作时,丢失属性
Function.prototype.myBind = function(context){
var args = Array.prototype.slice.call(arguments,1),
self = this;
return function(){
var newArgs = Array.prototype.slice.call(arguments);
self.myApply(context,args.concat(newArgs))
}
}
//缺陷 ;会修改原来的函数原型
Function.prototype.myBind = function(context){
var args = Array.prototype.slice.call(arguments,1),
self = this;
var fn = function(){
var newArgs = Array.prototype.slice.call(arguments);
// 当 new 时,this指向新的实例,所以要换上下文,变为实例对象
self.myApply(this instanceof self ? this : context,args.concat(newArgs))
}
// 需要统一原型的构造函数,使上述的instanceof 成立
fn.prototype = this.prototype;
return fn;
}
//缺陷 ;会修改原来的函数原型
Function.prototype.myBind = function(context){
var args = Array.prototype.slice.call(arguments,1),
self = this,
tmp = function(){};
tmp.prototype = this.prototype;
var fn = function(){
var newArgs = Array.prototype.slice.call(arguments);
// 当 new 时,this指向新的实例,所以要换上下文,变为实例对象
self.myApply(this instanceof self ? this : context,args.concat(newArgs))
}
// 需要统一原型的构造函数,使上述的instanceof 成立
// 圣杯模式;隔离原型
fn.prototype = new tmp();
return fn;
}
var pp = Person.bind(c,‘女‘,‘00‘);
var ppp1 = new pp(‘拿三个呢‘)
console.log(ppp1);
var pp1 = Person.myBind(d,‘女‘,‘00‘);
var ppp2 = new pp1(‘拿三个呢‘)
console.log(ppp2);console.log(pp); console.log(pp1);
call,apply,bind 实现