- 编码实现bind();
bind的功能:
1):改变this的指向
2):bind前面的函数不会执行
3):返回改变this指向的函数
要实现 new fn.bind(obj) ,
fn.bind(obj,1,2)(),
fn.bind(obj)(1,2),
fn.bind(obj,1)(2),
<script>
;(()=>{
function mybind(obj){
let bindArr= Array.prototype.slice.call(arguments,1); //排除bind(obj)中的对象 获得被处理的数据
let that = this;//储存调用此方法的对象 即 fn.dind中的 fn
function change(){
let chaArr = Array.prototype.slice.call(arguments); //回去bind返回函数执行的之后被处理数据
return that.apply(obj,bindArr); // 若此方法被调用会执行
}
return change;//仅仅返回 change 函数并不会执行
}
Function.prototype.mybind = mybind;
})();
let Obj = {name:'wc',};
function fn(a,b){
return a+b;
}
console.log(fn.mybind(Obj,1,2)
</script>
但是此时 fn.bind(obj)(1,2), fn.bind(obj,1)(2) 这两种情况并不能实现
修改
function change(){
let chaArr = Array.prototype.slice.call(arguments); //回去bind返回函数执行的之后被处理数据
return that.apply(obj,bindArr.concat(chaArr)); // 若此方法被调用会执行
}
//bindArr.concat(chaArr) 将两次参数合并 作为change()方法处理数据
这时还有一个问题 如何判断 new 这种情况呢?
new 运算符会开辟一个新空间,将this指向这个空间 并返回。
继续修改:
function change(){
let chaArr = Array.prototype.slice.call(arguments); //回去bind返回函数执行的之后被处理数据
return that.apply(this instanceof change?this:obj ,bindArr.concat(chaArr)); // 若此方法被调用会执行
}
//this instanceof change?this:obj
//将 apply方法的修改的this指向变为动态的 如果是:new fn.bind(obj,1,2)() =>new change()
//这是 this instanceof change == ture;
//so apply 要改变的指针为 this 即 新开辟这块空间
//反之 还为obj
现在基本要求都可以实现
但是 此时 change() 的原型 与fn 的原型并不一致
添加
change.prototype = that.prototype;
这会造成 耦合 即 change 原型的修改 会影响 fn
解耦
function JO(){}//此时是 构造器
JO.prototype = that.prototype;
change.prototype = new JO();
完整:
<script>
;(()=>{
function mybind(obj){
let bindArr= Array.prototype.slice.call(arguments,1); //排除bind(obj)中的对象 获得被处理的数据
let that = this;//储存调用此方法的对象 即 fn.dind中的 fn
function change(){
let chaArr = Array.prototype.slice.call(arguments); //回去bind返回函数执行的之后被处理数据
return that.apply(this instanceof change?this:obj ,bindArr.concat(chaArr)); // 若此方法被调用会执行
}
function JO(){}//此时是 构造器
JO.prototype = that.prototype;
change.prototype = new JO();
return change;//仅仅返回 change 函数并不会执行
}
Function.prototype.mybind = mybind;
})();
let Obj = {name:'wc',};
function fn(a,b){
return a+b;
}
console.log(fn.mybind(Obj,1,2)());
console.log(fn.mybind(Obj)(1,2));
console.log(fn.mybind(Obj,1)(2));
</script>