保存对内置方法的引用的好处

benefits of saving reference to built-in methods

本文关键字:引用 方法 内置 保存      更新时间:2023-09-26
 ap = Array.prototype,
 aps = ap.slice,
 apsp = ap.splice,
我经常在不同的框架中看到类似的代码。这样做的好处是什么?为什么不直接使用呢?

当完全按照您所展示的方式使用时,主要原因是为了减少代码中大量使用所引用的方法或对象的键入量。此外,这可以减少脚本的总体大小。考虑:

Array.prototype.someFunction1 = function () { /*someFunction1 */ };
Array.prototype.someFunction2 = function () { /*someFunction2 */ };
Array.prototype.someFunction3 = function () { /*someFunction3 */ };
Array.prototype.someFunction4 = function () { /*someFunction4 */ };

…(284个字符)与

var ap = Array.prototype;
ap.someFunction1 = function () { /*someFunction1 */ };
ap.someFunction2 = function () { /*someFunction2 */ };
ap.someFunction3 = function () { /*someFunction3 */ };
ap.someFunction4 = function () { /*someFunction4 */ };

…它有261个字符。琐碎,是的,但在大范围内,这可以在分布式代码中产生足够的差异(想想google托管的jQuery)。

然而,有时这样做是为了通过闭包来保留作用域:

  var self = this;
  this.someProperty = 5;
  var myDiv = document.createElement('div');
  myDiv.addEventListener('mousedown', function(e) { alert(self.someProperty); }, false);

几个好处:

  1. 运行时更快(获得最终结果的查找次数更少)
  2. 缩小前更小的代码
  3. 通过缩小更容易减少
  4. 编码时少输入

需要注意的是,我认为对于不熟悉代码或其约定的人来说,它使代码可读性降低,因为代码不是自文档化的。每个人都知道Array.prototype.splice是什么,但是陌生人不知道aps是什么,直到他们研究代码,追踪它的定义并记住它是什么。


有人在评论中要求我解释查找次数减少的问题:

对于解释器解析Array.prototype.splice,它必须做以下操作:

  1. 在本地范围中查找Array名称。它找不到它。
  2. 查看任何闭包(例如父作用域)中Array的名称。它找不到它。
  3. 在全局作用域中查找Array名称。它找到它。
  4. Array对象上,查找prototype属性。
  5. prototype属性上,寻找splice属性,现在它终于有了它需要的功能。

对于解释器解析aps,它必须这样做:

  1. 在本地范围中查找aps名称。它找到它,而不是它有它需要的功能。

aps的预赋值实际上已经预先完成了查找,因此它们已经在运行时解决了。这减少了一些灵活性,因为如果splice或prototype属性的值被更改,变量aps将不会反映该更改,但是如果您知道它们不应该更改(运行时解释器不知道的事情),那么您可以利用这个快捷方式。

这种模式存在的一个功能原因是防止其他javascript代码更改特定方法的含义。从本质上保护不受如下代码的影响

Array.prototype.splice = function() {
  // This is evil
};

另一种更可能的情况是,开发者只是不想输入Array.prototype.splice,而更喜欢apsp这样的短版本。

有两个好处。

  • aArray.prototype.slice更容易缩小
  • a是单次查找,Array.prototype.slice是多次查找

所以基本上它们都是微优化。这在图书馆中很有价值因为图书馆关心的是尽可能的高效