关于在js和jquery中bind的不同使用及手写实现Function.bind

时间:2021-09-11 09:05:24

在js和jquery中都有bind,那么之间的区别是啥呢?

jquery 中bind的使用方法:

用于绑定函数,当然类似的还有on等方法

$(selector).bind(event,data,function)


bind使用举例;
$("button").bind("click",function(){
$("p").slideToggle();
});
$('.myClass').on({
click:function(eleDom){
...do someting
},
dbclick:function(eleDom){
...do someting
}
})

bind的实现考虑了浏览器的兼容性,看jquery源码,可以发现bind的实现,其中针对不同浏览器的事件监听,包括addEventListener,attachEvent,on+(click,focus)

bind: function (type, callback) {
if (document.addEventListener) {
this.each(function (i, item) {
item.addEventListener(type, callback, false);
});
}
else if (document.attachEvent) {
this.each(function (i, item) {
item.attachEvent('on' + type, callback);
});
}
else {
this.each(function (i, item) {
tem['on' + type] = callback;
});
}
}

补充:bind()绑定自定义事件时,需要用trigger出发,代码如下:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>测试jquery的事件绑定和触发</title>
</head>
<body style="padding: 30px;">
<p>欢迎来到该界面</p>
<button type="button" id="firstbtn">绑定事件</button>
<button type="button" id="secondbtn">事件触发</button>
<script src="jquery.js"></script>
<script>
var btn1=$("#firstbtn");
//jquery定义一个自定义事件 diy 注意:回调函数中的第一个参数是事件,需要接受其他参数的话,在后面跟上其他参数即可
btn1.bind("diy",function(event,a,b,fun){
console.log(a,b);
fun();
});
//jquery自定义事件触发示例, 注意: trigger传入的参数第一个是自定义的事件名,第二个参数是一个数组,数组中的项会和自定义事件中回调的参数项对应
$("#secondbtn").click(function(){
btn1.trigger("diy",["11","34",function(){alert("绑定并触发成功了")}]);
});
</script>
</body>
</html>

接着我们来看看js中的bind的使用
先看一段代码:
<!doctype html>
<html>
<head>

<meta charset="utf-8">
<title>TEst</title>
</head>
<body>
<div id='scroll' style='background-color:green;height:100px;width:40px;'>hello </div>
<script type="text/javascript">
function T() {
this.id = "Object";
this.dom=document.getElementById("scroll");

}
T.prototype = {
init: function() {

this.dom.onmouseover = function() {
console.log("Over-->"+this.id);
}//a

this.dom.onmouseout = function() {
console.log("Out -->"+this.id);
} .bind(this)//b
}
};
(new T()).init();
</script>

</body>
</html>
输出结果是什么呢:
over--scroll
out--object
是不是有点蒙圈,不着急,那我们来看看这个官网是怎么对bind做解释的:bind方法会创建一个新函数,当调用这个绑定函数的时候,绑定函数会以创建它时候传入bind方法的 第一个参数作为this,传入bind方法的第二个以及以后的参数加上这个绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。 多读几遍理解理解,再读几遍 其实就是改变了函数执行的上下文环境,还是上文这个例子,我们来看下为什么两次打印出的结果不同 在第一次的时候,this指的是当前之前环境,即谁调用就是谁,调用者就是this.dom,那么this.dom=document.getElemnetById('scroll');,所以打印出来就是这个元素 的id即scroll, 而第二次的时候,this被改变了。改变成了谁调用的init这个函数,那就是new T(),那么this.id在T中已经定义啦,所以打印出来就是object。好了
其实每学习一个东西最终的目的都是要用到实践中来,看段例子:
 var logger = {
x: 0,
updateCount: function(){
this.x++;
console.log(this.x);
}
}

正常情况下调用我们可能这么写:
document.querySelector('button').addEventListener('click', function(){
logger.updateCount();
});
但是我们也可以这样写:
document.querySelector('button').addEventListener('click', logger.updateCount.bind(logger));
本来通常情况下处理函数要用一层匿名函数包裹下,才能维持处理函数本身的this,这里直接通过bind(logger)将其执行时候的this指向logger对象,bind()
创建一个函数,当这个函数在被调用的时候,它的this关键词会被设置成被传入的值(这里指调用bind()时候传入的参数) 再举个例子,现在来综合起来:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Event Bubbling</title>
<link rel="stylesheet" type="text/css" href="http://cdn.datatables.net/1.10.13/css/jquery.dataTables.css">

<!-- jQuery -->
<script type="text/javascript" charset="utf8" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

<!-- DataTables -->
<script type="text/javascript" charset="utf8" src="http://cdn.datatables.net/1.10.13/js/jquery.dataTables.js"></script>
<script>
window.onload=function(){
var hh=document.getElementById('hha');

var OOO = {
color: "red",
element: document.getElementById('text'),
events: function() {

hh.addEventListener("click", function(e) {
console.log(this.color);
console.log(this.element);
this.element.style.color = this.color;
}.bind(this));
return this;
},
eventsecond: function() {

hh.addEventListener("click", function(e) {
console.log(this.color);
console.log(this.element);
this.element.style.color = this.color;
});
return this;
},
init: function() {
this.events();
},
inittwo:function(){
this.eventsecond();
}
};
OOO.init();
}
</script>
</head>
<body>
<div id='ro_btnReplace'>
<input type='button' id='hha' value='clickme'>
<div id='text' style='height:100px;width:100px;'>
fdfdf
</div>
</div>
</body>
</html>
好了,现在点击,结果打印出来是什么呢?
关于在js和jquery中bind的不同使用及手写实现Function.bind
然后字体也变成了红色,但是现在我们坐下改动,我们不用bind方法了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Event Bubbling</title>
<link rel="stylesheet" type="text/css" href="http://cdn.datatables.net/1.10.13/css/jquery.dataTables.css">

<!-- jQuery -->
<script type="text/javascript" charset="utf8" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

<!-- DataTables -->
<script type="text/javascript" charset="utf8" src="http://cdn.datatables.net/1.10.13/js/jquery.dataTables.js"></script>
<script>
window.onload=function(){
var hh=document.getElementById('hha');

var OOO = {
color: "red",
element: document.getElementById('text'),
events: function() {

hh.addEventListener("click", function(e) {
console.log(this.color);
console.log(this.element);
this.element.style.color = this.color;
}.bind(this));
return this;
},
eventsecond: function() {

hh.addEventListener("click", function(e) {
console.log(this.color);
console.log(this.element);
this.element.style.color = this.color;
});
return this;
},
init: function() {
this.events();
},
inittwo:function(){
this.eventsecond();
}
};
OOO.inittwo();
}
</script>
</head>
<body>
<div id='ro_btnReplace'>
<input type='button' id='hha' value='clickme'>
<div id='text' style='height:100px;width:100px;'>
fdfdf
</div>
</div>
</body>
</html>
这次打印出来的结果是什么呢
关于在js和jquery中bind的不同使用及手写实现Function.bind
然后最近在看博客有人在写如何实现bind这个方法,那么我就先盗过来了,打算以后再好好看看
if(!Function.prototype.bind){

  Function.prototype.bind = function(oThis){

    if(typeof this !=="function"){ //如果不函数抛出异常

      throw new TyperError("")

    }

    var aArgs = Array.prototype.slice.call(arguments,1), //此处的aArgs是除函数外的参数

      fToBind = this,                  //要绑定的对象

      fNOP = function(){},

      fBound = function(){

        return fToBind.apply(

          this instanceof fNOP ? this:oThis||this,aArgs.concat(Array.prototype.slice.call(arguments)));

          )

      };

    fNOP.prototype = this.prototype;

    fBound.prototype = new fNOP();

    return fBound;

  }

}