你会如何在 javascript 中重载 [] 运算符

IT技术 javascript operator-overloading
2021-01-30 07:05:13

我似乎找不到[]在 javascript 中重载运算符的方法有大佬知道吗?

我在想……

MyClass.operator.lookup(index)
{
    return myArray[index];
}

还是我看的不对。

6个回答

您可以使用 ES6 代理(在所有现代浏览器可用来做到这一点

var handler = {
    get: function(target, name) {
        return "Hello, " + name;
    }
};
var proxy = new Proxy({}, handler);

console.log(proxy.world); // output: Hello, world

查看MDN 上的详细信息

@Pacerier 您可以target[name]在 getter 中返回,OP 只是显示示例
2021-03-23 07:05:13
我们将如何使用它来创建我们自己的带有索引访问器的类?即我想使用我自己的构造函数,我不想构造一个代理。
2021-03-26 07:05:13
这不是真正的重载。您现在不是调用对象本身的方法,而是调用代理的方法。
2021-03-27 07:05:13
也适用于[]运营商,顺便说一句:var key = 'world'; console.log(proxy[key]);
2021-03-30 07:05:13

你不能在 JavaScript 中重载运算符。

它被提议用于 ECMAScript 4,但被拒绝了。

我不认为你很快就会看到它。

那么 jQuery 如何根据你使用 [] 或 .eq() 返回不同的东西?stackoverflow.com/a/6993901/829305
2021-03-18 07:05:13
链接失效了:(
2021-03-18 07:05:13
您现在可以使用代理来完成。
2021-03-25 07:05:13
这可能已经在某些浏览器中通过代理实现了,并且将在某个时候出现在所有浏览器中。参见github.com/DavidBruant/ProxyArray
2021-03-29 07:05:13
尽管您可以定义带有符号的方法,只要您将它们作为数组而不是“.”来访问。这是Smalltalk的如何映射之类Object arg1: a arg2: b arg3: cObject["arg1:arg2:arg3:"](a,b,c)所以你可以有myObject["[]"](1024):P
2021-04-12 07:05:13

简单的答案是 JavaScript 允许通过方括号访问对象的子对象。

所以你可以定义你的类:

MyClass = function(){
    // Set some defaults that belong to the class via dot syntax or array syntax.
    this.some_property = 'my value is a string';
    this['another_property'] = 'i am also a string';
    this[0] = 1;
};

然后,您将能够使用任一语法访问类的任何实例上的成员。

foo = new MyClass();
foo.some_property;  // Returns 'my value is a string'
foo['some_property'];  // Returns 'my value is a string'
foo.another_property;  // Returns  'i am also a string'
foo['another_property'];  // Also returns 'i am also a string'
foo.0;  // Syntax Error
foo[0];  // Returns 1
foo['0'];  // Returns 1
出于性能原因,我绝对不会推荐这个,但它是这里问题的唯一实际解决方案。也许编辑说明这是不可能的会使这是一个很好的答案。
2021-03-17 07:05:13
不是问题想要的。问题是寻求一种方法来捕获foo['random']您的代码无法执行的操作。
2021-03-29 07:05:13

使用代理。在答案的其他地方提到过,但我认为这是一个更好的例子:

var handler = {
    get: function(target, name) {
        if (name in target) {
            return target[name];
        }
        if (name == 'length') {
            return Infinity;
        }
        return name * name;
    }
};
var p = new Proxy({}, handler);

p[4]; //returns 16, which is the square of 4.
可能值得一提的是,代理是 ES6 的一项功能,因此浏览器支持更有限(而且Babel 也不能伪造它们)。
2021-03-29 07:05:13

由于括号运算符实际上是属性访问运算符,因此您可以使用 getter 和 setter 对其进行挂钩。对于 IE,您将不得不使用 Object.defineProperty() 代替。例子:

var obj = {
    get attr() { alert("Getter called!"); return 1; },
    set attr(value) { alert("Setter called!"); return value; }
};

obj.attr = 123;

IE8+ 也一样:

Object.defineProperty("attr", {
    get: function() { alert("Getter called!"); return 1; },
    set: function(value) { alert("Setter called!"); return value; }
});

对于 IE5-7,onpropertychange只有事件适用于 DOM 元素,但不适用于其他对象。

该方法的缺点是您只能将请求挂钩到预定义的属性集,而不能挂钩没有任何预定义名称的任意属性。

加 1 以抵消减 1,因为这不仅仅是 IE。
2021-03-14 07:05:13
似乎这实际上可以在任意属性上调用: var a = new Array(2); function trap_indexing(obj,index) { Object.defineProperty(obj,index,{ get() { console.log("getting"); return this['_shadow'+index]; }, set(p) { console.log("setting"); this['_shadow'+index] = p; } }); } trap_indexing(a,0); trap_indexing(a,1); trap_indexing(a,2); a[0] = 'barf'; console.log(a[0]); a[1] = 'cat'; console.log(a[1]);
2021-03-24 07:05:13
你能在jsfiddle.net上演示你的方法吗?我认为该解决方案应该适用于表达式中的任何键,obj['any_key'] = 123;但是我在您的代码中看到的我需要为任何(尚不知道的)键定义 setter/getter。那是不可能的。
2021-04-01 07:05:13
这可以为类函数完成吗?我正在努力寻找自己的语法。
2021-04-06 07:05:13