js中bind函数的作用,函数bind形式参数含义
关于原生js中bind函数的简单实现
今天继续研究了bind函数的实现,也知道了shim和polyfill的说法,现在总结一下,
if
(!Function.prototype.bind)
{
Function.prototype.bind
=
function
(oThis)
{
if
(typeof
this
!==
"function")
{
//
closest
thing
possible
to
the
ECMAScript
5
internal
IsCallable
function
throw
new
TypeError("Function.prototype.bind
-
what
is
trying
to
be
bound
is
not
callable");
}
var
aArgs
=
Array.prototype.slice.call(arguments,
1),
fToBind
=
this,
fNOP
=
function
()
{},
fBound
=
function
()
{
return
fToBind.apply(this
instanceof
fNOP
oThis
?
this
:
oThis
||
window,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype
=
this.prototype;
fBound.prototype
=
new
fNOP();
return
fBound;
};
}
这是官方文档上的实现,我分二个方面来谈我要说的东西,
第一个是参数,agruments的使用
var
aArgs
=
Array.prototype.slice.call(arguments,
1),这里是将bind函数的参数数组取出来,第一个参数不要(就是不要oThis)也就是要被绑定方法的那个对象,第二个是
aArgs.concat(Array.prototype.slice.call(arguments)));
这里是用了数组的方法,把参数插在参数数组后面,要注意,这个函数是要被return
出去然后执行的,他的参数数组是return出去的那个fBound函数的参数数组,所以上下两个参数数组是不一样的,有点像柯里化。
第二个是上下文,在其中上下文的变化比较难理解,bind函数主要就是为了绑定上下文来使用的
fToBind
=
this
这里是保存了对象的上下文,紧接着下面的apply方法让要被绑定的那个对象可以使用该上下文
fNOP.prototype
=
this.prototype;
fBound.prototype
=
new
fNOP();
这里是以fNOP为中介把this.prototype这个原对象的属性给fBound,确保fBound是在定义的时候的那个上下文里面执行。本来
bound.prototype
=
self.prototype就可以将原属性集成过来了,但是这样两个对象属性都指向同一个地方,修改
bound.prototype
将会造成self.prototype
也发生改变,这样并不是我们的本意。所以通过一个空函数
nop
做中转,能有效的防止这种情况的发生。
以上这篇关于原生js中bind函数的简单实现就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
javascript中apply,call和bind的区别
apply与call
apply与call功能是一样的,不同的地方在于方法参数
//apply第二个参数是一个数组
func.apply(thisVal,?[arg1,?arg2,?...]);
//call则从第二个参数开始为参数列表形式
func.call(thisVal,?arg1,?arg2,?...);
//用一个例子来描述
//Math.max函数可以返回参数中的最大值
var?max1?=?Math.max(6,?3,?8,?5);
//如果想找出数组中的最大,apply就派上用场了,?因为Math.max不支持传入数组参数
//apply方法可以把数组中的最大值找出
var?array?=?[6,?3,?8,?5];
var?max2?=?Math.max.apply(null,?array);
//call方法与原来的方法比较类似,?只是多了一个thisVal,?
//因为max函数里没有用到this,所以这里的thisVal可以传任意值
var?max3?=?Math.max.call(null,?6,?3,?8,?5);
bind
1. apply与call调用会直接返回函数的执行结果, 而bind则返回一个函数
2. 该函数需求传入参数是原函数参数减去bind传的参数(不考虑thisVal的话)
//语法
func.bind(thisVal,?arg1,?arg2,?...);
//示例
function?func(a,?b,?c)
{
????console.log(a,?b,?c);
}
var?a=1,b=2,c=3;
var?bindFunc?=?func.bind(null,?a);//func没有用到this,所以thisVal可以传null
bindFunc(b,?c);?//注意这里这需要传b和c就可以了
//Math.max使用bind
var?maxFunc?=?Math.max.bind(null,?6,?3);
var?max4?=?maxFunc(8,?5);

javascript:关于Function.prototype.bind()这个方法
这里确实是两个arguments,而且这两个arguments是不同的。
首先你要理解prototype里bind()函数的含义,bind()函数和apply()、call()函数一样,都是用来改变函数的上下文环境(即函数中this所指代的对象),与之不同的是,apply()和call()都是立即执行获取结果,而bind()可以返回一个已经改变了上下文环境的函数,供日后调用。而这个函数本身是有参数的,这里bind()函数就是可以在函数获取上下文环境时给其传参,同时也可以在函数调用时给其传参,所以这里会有两个arguments。
举个例子吧,比方你有一个可变基数的累加函数:
var?add?=?function()?{
????var?sum?=?this.base
????for?(var?i?=?0,?c;?c?=?arguments[i++];)
????????sum?+=?c
????return?sum
}
在这个函数中,基数值base是通过上下文环境决定的,如果基数是1,那么add(1)的结果就是2,如果基数是10,那么add(1)的结果就是11。当然本函数的参数是可变的,当基数为10时,你也可以这么写:add(1,2,3,4),其结果为10+1+2+3+4=20。
那函数的上下文环境怎么决定呢?就是题主所提到的bind()函数。下面我们规定两个上下文:
var?context1?=?{
????base:?1
}
var?context2?=?{
????base:?10
}
这样当你就可以通过bind创造一个基数为1和基数为10的累加函数:
var?addbase1?=?add.bind(context1,?9)
var?addbase10?=?add.bind(context2)
什么?你问我为什么addbase1在bind的时候会有两个参数(context1、9)?因为这里其实等于我在bind的同时就给addbase1这个函数开始传参啦,这个就是题主题目中的第一个arguments。还记得那个切片arguments.slice(1)么?就是把提供上下文的参数context1切掉了,保留了传给addbase1的参数9。
当然,在定义了函数之后我也可以正常传参,如:
addbase1(1,?2,?3,?4)??//结果为20
addbase10(1,?2,?3,?4)?//结果也是20
这里的1,2,3,4就是题主所谓的第二个arguments,而我们看到函数addbase1的结果和addbase10的结果一样,就是因为在bind函数里有一行concat,将我们两次传入的arguments结合了起来,使得addbase1的过程变成:1(基底)+9(第一次传参)+1+2+3+4 = 20
但是要注意的时,第一次传参的arguments和第二次传参的arguments是不同的,因为第一次传入的参数会被保存在函数的闭包中,成为一种currying的属性,不会随着以后的传参而改变(即保存在了代码第五行的args中)。也就是说,当你再次执行如下代码时:
addbase1(1,?2,?3,?4)??//结果依然是20,实际上addbase1和addbase10一样了
实际上也就是说,在bind时传入的参数,也就是第一个arguments,会影响函数的属性;在调用时传入的参数,也就是第二个arguments,不会影响函数的性质。
希望能帮到你。
jQuery中bind函数用法
问题1:
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ""
html xmlns=""
head
meta http-equiv="Content-Type" content="text/html; charset=utf-8" /
titleSimple JQuery/title
script type="text/javascript" src="js/jquery.js"/script
script type="text/javascript"
$(function(){
$('#mybtn').bind('click', {a : 'hello', b : 'world'}, myFun);
});
function myFun(e) {
alert(e.data.a);
alert(e.data.b)
}
/script
/head
body
input type="button" id="mybtn" value="Click me." /
/body
/html
如上面例子,可以传递多个参数。
-------------------------------------------------------
问题2:
$('pTest/p').appendTo('.inner');
$('.inner').append('pTest/p');
上面这个是append()和appendTo()区别,应该一目了然了吧?
而appendChild()不是jquery的方法,而是javascript原生的方法。
append和appendChild的关系是:
其实几乎一样,append就是调用appendChild实现的,只是在append前,做一个简单判断。下面贴下jquery的源代码:
append: function() {
return this.domManip(arguments, true, function( elem ) {
if ( this.nodeType === 1 ) {
this.appendChild( elem );
}
});
}
--------------------------------------------------
问题3:
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ""
html xmlns=""
head
meta http-equiv="Content-Type" content="text/html; charset=utf-8" /
titleSimple JQuery/title
script type="text/javascript" src="js/jquery.js"/script
script type="text/javascript"
$(function(){
$('#mybtn').bind('click', myFun);
});
function myFun() {
alert($(this).attr('value'));
}
/script
/head
body
input type="button" id="mybtn" value="Click me." /
/body
/html
第3个问题不是看的很明白?直接调用应该可以呀,看看这个例子是不是你想要的?
---------------------------------------------------
问题4:网上有很多,查看参考链接这个吧。
JS之bind浅析及应用场景
fn.bind(obj, args)
bind() 方法会创建一个函数,该函数的 this 指向了传入的第一个参数,当 bind() 的参数为空时, this 指向全局对象。如浏览器中的 window 。
因为 js 是一门 Duck typing 语言,所以我们可以通过 bind 实现一些共有方法。
有的时候我们需要针对特定的 this 调用某些方法。写起来比较麻烦,这个时候就可以使用 bind 创建一个 shortcut 方便调用。
bind 也可以绑定构造函数,但是当执行生成的函数时,会忽略this指向,即使在绑定时已经对其赋值。