简体   繁体   English

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

[英]Can any genius tell me what's going on in this small code? From Secrets of the JavaScript Ninja

I'm barely starting JavaScript and I'm wondering if there are any geniuses out there that can help me understand this line by line? 我几乎没有启动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: };

I'm just beginner, but if you can teach me, then you're awesome. 我只是初学者,但如果你能教我,那你真棒。 I know about prototypes, call, shift, apply a bit so you can skip the beginner parts (though I think you shouldn't so other who are barely getting into JS may learn how). 我知道原型,调用,移位,应用一点,所以你可以跳过初学者部分(虽然我认为你不应该这样,其他几乎没有进入JS的人可能会学习如何)。

Notice: I know that there's a somewhat "similar code" asking a similar question here but I'm asking line by line explanation and they're not (not duplicate) (also, you can skip line 8 & 9) :) 注意:我知道有一个“类似的代码” 在这里问一个类似的问题但我要求逐行解释,他们不是(不重复)(另外,你可以跳过第8和第9行):)

This is a partial implementation, in EcmaScript 3, of the EcmaScript 5 bind method which does partial application . 这是EcmaScript 3中部分应用的EcmaScript 5 bind方法的部分实现 It makes 它使

myObject.method.bind(myObject, 1, 2)(3, 4)

is equivalent to 相当于

myObject.method(1, 2, 3, 4)

but its also more convenient because you can do 但它也更方便,因为你可以做到

var m = myObject.method.bind(myObject, 1, 2);
m(3, 4);
m(5, 6);

instead of 代替

myObject.method(1, 2, 3, 4);
myObject.method(1, 2, 5, 6);

Nit: The two are not entirely equivalent, because if the first call to myObject.method does this.method = somethingElse; Nit:这两个并不完全等价,因为如果第一次调用myObject.method执行this.method = somethingElse; then the bound method would still call the original. 然后绑定的方法仍然会调用原始方法。

To break it down: 要打破它:

 Function.prototype.bind = function(){ 

Adds a method to the builtin function type. 向内置函数类型添加方法。

 var fn = this, 

Stores this which should be a Function in normal use so that it can be used inside a closure. 存储this应该是一个Function正常使用,以便它可以封闭内部使用。

 args = Array.prototype.slice.call(arguments), 

Creates an array containing the arguments to bind . 创建一个包含bind参数的数组。

  object = args.shift(); 

Removes the first argument from args and stores it in object . args删除第一个参数并将其存储在object This will be used as the this value for fn when it is applied later. 这将在以后应用时用作fnthis值。

  return function(){ 

returns a function that acts as a partially applied method. 返回一个充当部分应用方法的函数。 This function when called 调用此函数

 return fn.apply(object, 

calls the function to the left of .bind passing the first argument to bind as this . 调用该函数的左.bind传递到第一个参数bindthis apply is a special reflective method of functions which allows calling of a function with an array of arguments similar to *args or **kwargs in python, or ... in Java. apply是一种特殊的反射函数方法,它允许调用一个函数,该函数的参数类似于python中的*args**kwargs ,或者是Java中的...

  args.concat(Array.prototype.slice.call(arguments))); 

passes as arguments to fn , the arguments to bind followed by the argument to the closure. 作为参数传递给fnbind的参数后跟闭包的参数。

Let's say we have a function 假设我们有一个功能

function hi(a, b) { alert('hi! '+(a+b)); }

Define a function for every function (so you could use for example hi.bind() ) 为每个函数定义一个函数(所以你可以使用例如hi.bind()

1:  Function.prototype.bind = function(){

fn is this , hence the original function (in our example this = hi ) fn是this ,因此是原始函数(在我们的例子中this = hi

2:   var fn = this, 

arguments (the function's arguments) are not a normal array, so the following is a technique to convert it into an array which contains exactly the same elements as arguments arguments (函数的参数)不是普通数组,因此以下是将其转换为包含与arguments完全相同的元素的数组的技术

3:      args = Array.prototype.slice.call(arguments), 

shifts the args, returning the first one (which is the context with which you want to call the function) 移动args,返回第一个(这是你想要调用函数的上下文)

4:      object = args.shift();

this function returns a new function 此函数返回一个新函数

5:   return function(){

apply is a function that allows to to call a function with a given focus and arguments. apply是一个允许调用具有给定焦点和参数的函数的函数。 hi(2,3) equals hi.apply(window, [2,3]) hi(2,3)等于hi.apply(window, [2,3])

6:     return fn.apply(object,

The function will be called with the arguments to bind and any additional arguments you pass to the function we're in (which bind returns) 该函数将使用bind参数和您传递给我们所在函数的任何其他参数调用( bind返回)

7:        args.concat(Array.prototype.slice.call(arguments)));
8:     };
9: };

So hi(2,3) equals (hi.bind(window, 2, 3))() equals (hi.bind(window, 2))(3) 所以hi(2,3) equals (hi.bind(window, 2, 3))() equals (hi.bind(window, 2))(3)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM