使用默认函数扩展 JavaScript 对象

Extend a JavaScript object with a default function

在 google 应用程序脚本中,我有一个一维数据数组,我可以像这样从中获取值:

data[0]

我希望能够像这样传递列名:

data("A")

这样我就不必将字母转换成它们的数组位置。所以我想扩展数组对象(扩展并不是真的有风险,因为它在隔离的脚本环境中 运行)。

我知道我可以使用这个 letter to number function and this object extension question 向数组原型添加一个函数,如下所示:

Array.prototype.byCol = function(colName) {
  return this[getColumnNumber(colName) - 1];
}

function getColumnNumber(str) {
  var out = 0, len = str.length;
  for (pos = 0; pos < len; pos++) {
    out += (str.charCodeAt(pos) - 64) * Math.pow(26, len - pos - 1);
  }
  return out;
}

var data = [1,2,3,4];

document.write(data.byCol("B"));

但这是一个比我想要的稍微笨重的调用语法。

基于 default functions 上的这个问题,看起来可以将默认函数分配给对象,但他们只是通过创建这样的函数对象来实现:

var test = new func(function() {
    // do something
});

我能否扩展数组,以便它在作为方法调用时执行默认函数?

简而言之,如果它还不是一个函数,你就不能将它变成一个函数,而且你不能真的扩展数组。

您可以做的是创建一个包装函数来包装一个数组并提供您想要的功能,并且还包括在需要时取回原始数组的能力:

var wrapper = (function() {
  function getColumnNumber(str) {
    return Array.prototype.reduce.call(str.toUpperCase(), function (t, c) {
        return 26 * t + c.charCodeAt(0) - 64;
    }, 0) - 1;
  }

  return function(arr) {
    return function(col, val) {
      if (arguments.length === 0) {
        return arr;
      }
      if (arguments.length > 1) {
        arr[getColumnNumber(col)] = val;
      }
      return arr[getColumnNumber(col)];
    };
  };
})();

var w = wrapper([10, 20, 30, 40, 50]);

snippet.log(w('D')); // 40

w('D', 33);          // set value

snippet.log(w('D')); // 33

w()[3] = 42;         // access underlying array directly
w().push(60);

snippet.log(w('D')); // 42
snippet.log(w('F')); // 60
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>