js中bind函数的作用,函数bind形式参数含义

http://www.itjxue.com  2023-01-05 14:27  来源:未知  点击次数: 

关于原生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指向,即使在绑定时已经对其赋值。

(责任编辑:IT教学网)

更多

推荐免费资源文章