如果读者对bind的使用已经非常清楚了,就请直接拉到文章底部,bind源码供上;对于那些对bind使用生疏的读者,本人也提供了详细的bind的使用的介绍。
话不多说,马上开始
// bind:
// 修改函数的this指向,然而不是修改这个函数本身的this;
// bind执行后会返回一个新的函数,这个新得函数在执行的时候,this是被修改过的
// 1.使用:
var x = 10;
var obj = {
x: 30
}
function show(a, b, c) {
console.log(this, this.x, a, b, c);
}
// 修改函数this指向,并且返回一个新的函数
var newShow = show.bind(obj);
show("huang", "yang", "quan");
newShow();
// 传参:
// 注意:在新函数里面传递的参数,在新函数执行的时候,会被拼接在bind函数的参数的后面
// 比如:会拼接在事件源对象event 的前面
var AShow = show.bind(obj, "huang", "yang", "quan");
var BShow = show.bind(obj, "huang");
AShow();
BShow("yang", "quan");
// 注意:
// 新返回的函数(指:AShow,BShoe)的constructor 是 原来的函数(指:show)
// 而且像创建出来的对象里的 this 肯定不是我们改变后的那个this(指:obj)
// 但是,我们在开发中是不会遇到这样的情况的,当作bind一个知识点知道即可
console.log( new AShow().constructor );
// 2. 来源 (js中一切都是对象,函数也是一个对象)
console.log(show.bind instanceof Function);
console.log(show.bind == Function.bind);
结果:看对应行数
3.单对象编程
html:
<button class="btn">点击</button>
js:
// 3.应用:
// eg: 单对象编程
var list = {
init: function() {
this.dom = document.getElementsByClassName('btn')[0];
this.ms = "你很帅";
this.bindEvent();
},
bindEvent: function() {
// this.dom.onclick = this.showMessage;//undefined
this.dom.onclick = this.showMessage.bind(this, 'a', 'b', 'c');//你很帅
},
// e是事件源对象,事件触发时才有
showMessage: function(a, b, c, e) {
console.log(this.ms, a, b, c, e);
}
}
list.init();
结果:点击
4.bind 比较call apply;
bind:是返回一个新的被改变过this指向的函数,这个函数可以等某个状态被改变的时候在去执行
call / apply:是在一个函数执行的时候,去改变这个函数的this指向
bind 底层是call 或是 apply
5.功能总结:
咱们先约定一些词语:
源函数A
A.bind(obj)返回 新函数B
函数A 有多个参数 x, y, Z…
1): 函数A调用bind方法时,需要传递参数 (有:this要指向的对象obj, A函数执行的参数x, y, Z...)
2): 函数A调用bind方法后,返回新的函数B
3): 函数B在执行的时候, 具体的功能实际上是使用函数A的功能,只不过this指向被改为obj
4): 函数B在执行的时候,传递的参数会被拼接在bind传递的参数的后面,一并在内部传递给A执行
5): new B()的构造函数依旧是A, 而生成的对象里面的this不会被修改为obj(this按 new B() 操作生成)
6.bind实现:
// 实现bind:
Function.prototype.newBind = function(target) {
var self = this;
var _args = [].slice.call(arguments, 1);
var temp = function () {};
var f = function() {
var args = [].slice.call(arguments, 0);
return self.apply(this instanceof temp ? this : (target || window), _args.concat(args));
}
temp.prototype = self.prototype;
f.prototype = new temp();
return f;
}
至此,已经分享完bind的使用和源码实现,如果文章中有错误的地方,请各位指出,我及时改正。
如果对bind的源码实现有不明白,请留言,或者私聊我,谢谢各位
祝大家在前端道路上越走越容易,手刃offer