bing与call/apply的区别
var p1={
name:'张三',
hobby: this.hobby,
play: function(sex,age){
console.log('年龄为'+age+'岁,性别为'+sex+'的',this.name+'喜欢'+this.hobby);
}
}
var p2={
name:'李四',
hobby:'踢足球'
}
使p1的this指向指向p2,call改变this的指向并立即执行,
bind改变this指向后返回一个新的函数,不执行
p1.play.call(p2,'男',20);
p1.play.apply(p2,['男',20]);
var fn=p1.play.bind(p2,'男',20);
fn();
;(function(){
var tab=function(){
this.tab=document.getElementsByClassName('tab')[0];
this.tabs=document.getElementsByClassName('t-item');
this.pages=document.getElementsByClassName('p-item');
}
Tab.prototype={
init:function(){
this.bindEvent();
},
bindEvent: function(){
var _self=this;
//此处事件处理函数,一般都放在外面,单独写
this.tab.addEventListener('click',function(){
_self.tabClick.call(_self);//或者 this.tab.addEventListener('click',this.tabClick.bind(this),false)
},false); //如果上面的把bind替换成call,就会直接执行了
},
tabClick: function(e){
console.log(e)
}
}
return new Tab().init();
})
重写bind方法
bind 是挂载在Function.prototype
用apply模拟bind
Function.prototype.bindy=function(context){
var _self=this,
args=Array.prototype.slice.call(arguments,1);
return function(){
var newArgs=Array.prototype.slice.call(arguments);
_self.apply(context,args.concat(newArgs))
}
}
var p={
age: 20
}
function Person(name,sex){
console.log(this);
console.log(this.age);
console.log(name,sex);
}
Function.prototype.bindy=function(context){
var _self=this,
args=Array.prototype.slice.call(arguments,1);
return function(){
var newArgs=Array.prototype.slice.call(arguments);
_self.apply(context,args.concat(newArgs))
}
}
var p2=Person.bindy(p,'zhangsan'); //此时的bingy的this指向不对
new p2('男');
var p2=Person.bind(p,'zhangsan');
new p2('男');
改为下面的形式就可以了(2021.06.21不懂)
Function.prototype.bindy=function(context){
var _self=this,
args=Array.prototype.slice.call(arguments,1);
var fn= function(){
var newArgs=Array.prototype.slice.call(arguments);
_self.apply(this instanceof _self?this:context,args.concat(newArgs))
}
fn.prototype=this.prototype;
return fn;
}
var p2=Person.bindy(p,'zhangsan');
new p2('男');
// var p2=Person.bind(p,'zhangsan');
// new p2('男');