Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Javascript库有对数组方法的本地引用(push、slice等)?_Javascript_Angularjs_Backbone.js - Fatal编程技术网

为什么Javascript库有对数组方法的本地引用(push、slice等)?

为什么Javascript库有对数组方法的本地引用(push、slice等)?,javascript,angularjs,backbone.js,Javascript,Angularjs,Backbone.js,我一直在阅读一些javascript库的代码。我注意到AngularJS和Backbone.js都保留了对数组函数的本地引用。e、 g: var push = [].push // or array.push 当数组是语言的一种结构并且应该可以全局访问时,这样做有什么意义?因为数组原型的函数可以应用于非数组 例如,将项目推入类似数组的对象中: var o = { length: 0 }; [].push.call(o, 'hi'); o; //Object {0: "hi", length

我一直在阅读一些javascript库的代码。我注意到AngularJS和Backbone.js都保留了对数组函数的本地引用。e、 g:

var push = [].push  // or array.push

当数组是语言的一种结构并且应该可以全局访问时,这样做有什么意义?

因为数组原型的函数可以应用于非数组

例如,
将项目推入类似数组的对象中:

var o  = { length: 0 };
[].push.call(o, 'hi');
o; //Object {0: "hi", length: 1}
另一种常见做法是将
参数
对象切片到本机数组中:

(function() {
   return [].slice.call(arguments); //[1, 2]
}(1, 2));
正如您所看到的,保存对这些函数的引用可以减少查找开销,使代码更小,并且便于缩小

在我看来,这主要是为了方便和可读性,因为反复编写
[]数组方法看起来相当笨拙。性能和缩小提升是额外的


通过Angular的来源,我发现了以下几个案例:

  • push
    在中使用。请注意,jQuery对象具有类似数组的结构,类似于本答案中的第一个示例
  • slice
    用于、和函数中

主干也是
slice
s参数对象(at和),它还使用
slice
at。

我认为库开发人员特别热衷于使他们的库能够适应页面上可能发生的随机事件。如果您很早就获得了对正确的Array.prototype.push的引用,并使用闭包将其挡在您作为库编写者所不知道的其他代码之外,那么如果页面上的其他代码决定劫持此内置方法,则会减少发生意外事件的机会(并使故障排除更加容易),哪种Javascript是非常允许的

考虑:

function Library(){
 var push=[].push;
 var data=[]; 
 this.save1=function(x){push.call(data, x);}
 this.save2=function(x){data.push(x);}
 this.get=function(){console.log(data);}
}
var o=new Library();

//Random on-page code
Array.prototype.push=function(x){console.info("doSomethingCrazy!");}

//Lets use the library functionality!
o.save1(1);
o.save2(2);

Douglas Crockford在他的讲座中指出,一个原因是JavaScript库的开发人员可以有条件地添加实用程序方法,例如string.split,这样,只有在浏览器提供的标准库尚未定义对象的原型时,才会将其添加到对象的原型中

我假设,如果浏览器不支持这些功能,他们可以自己定义这样的功能。但是我不是100%确定。一种可能性是新声明的
push
变量可以最小化为一个字符的名称(减少库的最小大小),但是
[]不能。push
不能。为什么这确实是可能的,通过Angular.js源代码查看似乎没有这种情况。所有
push
s都是对数组执行的。此外,在本地保存对该函数的引用不会有明显的性能提升。@MattDiamant但是,库通常肯定会将这些类型的函数应用于非数组。@MattDiamant我同意这是一个最小的性能提升。我更新了答案以反映这一点。此外,我还快速浏览了Angular source,并添加了我发现的用例。