【问题标题】:Can a Javascript Array or Object be overridden to be callable?可以重写 Javascript 数组或对象以使其可调用吗?
【发布时间】:2011-10-11 20:38:37
【问题描述】:

我想弄清楚 Array[] 和 Object[] 是否可以用 Array() 和 Object() 代替。函数原型是否可以嵌入数组或对象原型链中以使其可调用。基本上我正在寻找这样的东西:

// some magic with prototypes
????????????????

a = [1, 3, 4]
b = [1, 3, 4]

console.log(a[1]) // prints 3
console.log(b(1)) // prints 3

a[0] = -1
// same as
b(0, -1)

console.log(a[1], b(1)) // prints -1 -1

非常感谢!

【问题讨论】:

  • 我想我有一个解决方案,但我仍在研究中......
  • 不,它不能完成。为什么要b(0, -1)
  • @ThomBlake 我是。无法创建可调用的类数组对象。当然,如果没有代理,使用 es:h 代理你几乎可以做任何事情。

标签: javascript arrays monkeypatching


【解决方案1】:

您可能不想这样做,尤其是在任何浏览器中。这没有 Array 的很多不错的特性,包括效率。也就是说:

function ArrayFunction (arr) {
  var f = function s (p, v) {
    if (v !== undefined) {
      s[p] = v
    }
    return s[p]
  }

  for (var i = 0; i < arr.length; i++) {
    f[i] = arr[i]
  }

  return f
}

var a = new ArrayFunction([1, 3, 4])
var b = new ArrayFunction([1, 3, 4])

b(1, 5)
a[1] //3
b[1] //5

我最初想使用原型,但对象不会从其原型继承可调用性。

编辑: 上面已修正为不使用arguments。此版本不允许您将值设置为 undefined,但无论如何这通常都不是一种好的做法。

【讨论】:

  • 您应该解释使 JavaScript 引擎“非常难过”的意思。我认为您的意思是使用 arguments 的函数速度较慢。
  • @JuanMendes 是的,这让小耶稣哭了。
  • 哇,这真是个怪物!它越来越接近我正在寻找的东西。我想知道在创建新数组或对象时是否可以将这个新的 ArrayFunction 设为隐式?
  • @Raynos 我没有忘记 - 我认为这已经够糟糕了。我不相信克隆 Array.prototype 方法,因为它不是真正的 Array - 如果我正在使用它并想要这些方法,我会自己编写它们。
【解决方案2】:

好问题,但答案是否定的,因为对象不是函数。

你能得到的最接近的是:

Array.prototype.set = function(a,b) { this[a] = b; };

那么你可以这样做:

b.set(0, -1);

【讨论】:

  • 是的,我还要补充一点,您不能覆盖 JS 中函数调用 () 或索引数组访问 [] 的行为。
  • 好吧,无论如何,函数都是对象。
【解决方案3】:

Javascript 不支持这样的运算符重载。我想不出一种方法让一个变量同时支持 [] 和 () 访问,但如果您不需要 [] 访问,您可以尝试以下方法:

var weird_array = (function() {
    var data = [1,2,3];
    return function(idx, n) {
        if (arguments.length === 1)
            return data[idx];
        else if (arguments.length === 2)
            return (data[idx] = n);
    };   
})();

在这个例子中,weird_array 实际上不是一个数组,所以你不能在它上面使用 [],但它是一个函数(包裹在一个数据数组上)。然后你可以这样做:

weird_array();  // => undefined
weird_array(0); // => 1
weird_array(1); // => 2
weird_array(2); // => 3
weird_array(3); // => undefined
weird_array(1, 5); // => 5
weird_array(1); // => 5

【讨论】:

  • 谢谢!太酷了,你可以用对象构建闭包,也可以用闭包构建对象,但是我需要 () 和 [] 形式。
猜你喜欢
  • 2010-11-07
  • 2016-09-23
  • 2017-03-05
  • 2013-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多