Can a Javascript Array or Object be overridden to be callable? - Stack Overflow

I want to figure out if Array[] and Object[] can be replaced by Array() and Object(). Can a function pr

I want to figure out if Array[] and Object[] can be replaced by Array() and Object(). Can a function prototype be stuck into arrays or objects prototype chain to make them callable. Basically I am looking for some thing like this:

// 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

Thanks alot!

I want to figure out if Array[] and Object[] can be replaced by Array() and Object(). Can a function prototype be stuck into arrays or objects prototype chain to make them callable. Basically I am looking for some thing like this:

// 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

Thanks alot!

Share Improve this question edited Dec 27, 2011 at 15:53 Rob W 349k87 gold badges807 silver badges682 bronze badges asked Oct 11, 2011 at 20:38 treeformtreeform 1457 bronze badges 3
  • I think I have a solution for this, but I'm still doing research... – Tamzin Blake Commented Oct 12, 2011 at 20:34
  • NO it cannot be done. Why do you want b(0, -1) ? – Raynos Commented Oct 12, 2011 at 21:51
  • @ThomBlake I am. One cannot create an Array-like object that is callable. Without a proxy of course, using es:h proxies you can do pretty much anything. – Raynos Commented Oct 13, 2011 at 9:20
Add a ment  | 

3 Answers 3

Reset to default 2

You probably don't want to do this, especially in any browser. This doesn't have a lot of nice features of Array, including efficiency. That said:

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

I originally wanted to use prototypes, but objects don't inherit callableness from their prototypes.

EDIT: Fixed above to not use arguments. This version does not allow you to set a value to undefined, but that's generally not considered a good practice anyway.

Good question but the answer is no, because objects are not functions.

The closest you can get is this:

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

Then you can do:

b.set(0, -1);

Javascript does not support operator overloading like that. I can't think of a way to have one variable support both [] and () access, but if you don't need [] access, you could try something like:

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);
    };   
})();

In this example, weird_array is not actually an array, so you cannot use []'s on it, but it is a function (wrapped around a data array). You could then do:

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744842907a4596664.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信