是否可以重写Javascript数组或对象以进行调用?

时间:2011-10-11 20:38:38

标签: javascript arrays monkeypatching

我想弄清楚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

非常感谢!

3 个答案:

答案 0 :(得分:2)

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

你能得到的最接近的是:

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

然后你可以这样做:

b.set(0, -1);

答案 1 :(得分:2)

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

答案 2 :(得分:2)

您可能不想这样做,尤其是在任何浏览器中。这没有很多很好的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,但这通常不被认为是一种好的做法。