任何天才能告诉我这个小代码中发生了什么吗?来自JavaScript Ninja的秘密

Jan*_*ray 10 javascript

我几乎没有启动JavaScript,我想知道是否有任何天才可以帮助我逐行理解这一点?

1:  Function.prototype.bind = function(){
2:   var fn = this, 
3:      args = Array.prototype.slice.call(arguments), 
4:      object = args.shift();
5:   return function(){
6:   return fn.apply(object,
7:      args.concat(Array.prototype.slice.call(arguments)));
8:  };
9: };
Run Code Online (Sandbox Code Playgroud)

我只是初学者,但如果你能教我,那你真棒.我知道原型,调用,移位,应用一点,所以你可以跳过初学者部分(虽然我认为你不应该这样,其他几乎没有进入JS的人可能会学习如何).

注意:我知道有一个"类似的代码" 在这里问一个类似的问题,但我要求逐行解释,他们不是(不重复)(另外,你可以跳过第8和第9行):)

Mik*_*uel 12

这是EcmaScript 3 bind部分应用的EcmaScript 5 方法的部分实现.它使

myObject.method.bind(myObject, 1, 2)(3, 4)
Run Code Online (Sandbox Code Playgroud)

相当于

myObject.method(1, 2, 3, 4)
Run Code Online (Sandbox Code Playgroud)

但它也更方便,因为你可以做到

var m = myObject.method.bind(myObject, 1, 2);
m(3, 4);
m(5, 6);
Run Code Online (Sandbox Code Playgroud)

代替

myObject.method(1, 2, 3, 4);
myObject.method(1, 2, 5, 6);
Run Code Online (Sandbox Code Playgroud)

尼特:这两个是不完全等价的,因为如果第一次调用myObject.method确实this.method = somethingElse;那么绑定的方法仍然会调用原始.

要打破它:

Function.prototype.bind = function(){
Run Code Online (Sandbox Code Playgroud)

向内置函数类型添加方法.

var fn = this, 
Run Code Online (Sandbox Code Playgroud)

this应该是Function正常使用的商店,以便它可以在封闭物内使用.

args = Array.prototype.slice.call(arguments), 
Run Code Online (Sandbox Code Playgroud)

创建一个包含参数的数组bind.

  object = args.shift();
Run Code Online (Sandbox Code Playgroud)

从中删除第一个参数args并将其存储在中object.这将用作稍后应用的thisfn.

 return function(){
Run Code Online (Sandbox Code Playgroud)

返回一个充当部分应用方法的函数.调用此函数

return fn.apply(object,
Run Code Online (Sandbox Code Playgroud)

调用左边的函数.bind将第一个参数传递给bindas this. apply是一种特殊的函数反射方法,它允许使用类似于*args**kwargs在python或...Java中的参数数组调用函数.

  args.concat(Array.prototype.slice.call(arguments)));
Run Code Online (Sandbox Code Playgroud)

作为参数传递fn,参数bind后跟闭包的参数.


ori*_*ori 5

假设我们有一个功能

function hi(a, b) { alert('hi! '+(a+b)); }
Run Code Online (Sandbox Code Playgroud)

为每个函数定义一个函数(例如,你可以使用hi.bind())

1:  Function.prototype.bind = function(){
Run Code Online (Sandbox Code Playgroud)

fn是this,因此是原始函数(在我们的例子中this = hi)

2:   var fn = this, 
Run Code Online (Sandbox Code Playgroud)

arguments (函数的参数)不是普通数组,因此以下是将其转换为包含完全相同元素的数组的技术 arguments

3:      args = Array.prototype.slice.call(arguments), 
Run Code Online (Sandbox Code Playgroud)

移动args,返回第一个(这是你想要调用函数的上下文)

4:      object = args.shift();
Run Code Online (Sandbox Code Playgroud)

此函数返回一个新函数

5:   return function(){
Run Code Online (Sandbox Code Playgroud)

apply是一个允许调用具有给定焦点和参数的函数的函数.hi(2,3)等于hi.apply(window, [2,3])

6:     return fn.apply(object,
Run Code Online (Sandbox Code Playgroud)

该函数将使用参数to bind和您传递给我们所在函数的任何其他参数调用(bind返回)

7:        args.concat(Array.prototype.slice.call(arguments)));
8:     };
9: };
Run Code Online (Sandbox Code Playgroud)

所以hi(2,3)等于(hi.bind(window, 2, 3))()等于 (hi.bind(window, 2))(3)