关于原生js中bind函数的简单实现

JavaScript016

关于原生js中bind函数的简单实现,第1张

今天继续研究了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函数的简单实现就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

作为一名程序猿,经常遇到回调函数的情况,原生js的回调函数是一层一层的嵌套调用,而es6提供了一种新的写法,Promise,它可以把原本的嵌套回调函数实现成横向的调用,即链式调用。

下面看一个Promise的简单用法:

接着开始模拟:

首先,_Promise构造函数会接收一个函数resolver并执行,函数中又包含resolve和reject两个参数,然后,_Promise构造函数生成的实例有三种状态,分别是pending(初始值)、fullfilled(成功)和rejected(失败),且由pending变为成功或者失败后状态不可逆。

resolve和reject函数执行的时候会先判断状态,如果是pending则执行,且将状态变为fullfilled或者rejected,并将resolve/reject函数中参数传递给_result,以便then函数调用时使用。

因为有可能存在链式调用,所以执行then函数的返回值需要判断,如果isResolve或者isReject函数返回的是一个新的_Promise实例,则返回这个实例,否则返回当前实例

至此,Promise已经模拟完成~

用setTimeout或setInterval都可以啊,示例:

var bombPos = 0 // 炮弹初始位置

var bomb = document.getElementById('bomb') // 炮弹

setInterval(function(){

    bombPos = bombPos + 10 // 炮弹每次移动距离

    bomb.style.left = bombPos + 'px' // 设置炮弹新位置

}, 100} // 炮弹位置更新时长:100ms