【问题标题】:Extend a JavaScript object with a default function使用默认函数扩展 JavaScript 对象
【发布时间】:2015-05-16 11:47:49
【问题描述】:

在谷歌应用脚​​本中,我有一个一维数据数组,我可以像这样获取值:

data[0]

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

data("A")

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

我知道我可以使用 letter to number functionobject 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
});

我可以扩展数组以便在作为方法调用时执行默认函数吗?

【问题讨论】:

  • 你不能创建既是数组又是函数的东西。你需要它是一个数组吗?听起来你想要的是一个普通的对象。
  • @JLRishe,它不需要是一个数组,但这是最方便的,因为它是 getValues 返回的内容。我可能可以将整个东西包装在一个对象中,但无论如何我认为这是一个有趣的问题。
  • @t.niese,它在为 javascript 提供执行环境的 Google Apps 脚本服务器上运行。但它的范围很窄。我只是提到它来对冲主张反对扩展我不拥有的对象的 cmets。我在这里没那么担心。
  • 如果您不需要支持旧版浏览器,则可以使用Map。见developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 就像一个注释为什么不能创建一个可调用的数组:一个函数被定义为有一个属性length,这个属性是writeable: no。因此,如果使用 __proto__ 或类似的东西构建具有 Array 的功能并且可调用的东西,你最终会得到一个可调用的 array ,它无法更改它的 length

标签: javascript arrays prototype javascript-objects


【解决方案1】:

简单地说,如果它还不是一个函数,你就不能把它变成一个函数,你也不能真的扩展数组。

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

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>

【讨论】:

  • 该死,我刚刚写了一个几乎相同的解决方案!但是我没有想到toArray。做得很好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多