在 JavaScript 中覆盖对象的括号 [index] getter/setter?

问题描述 投票:0回答:4

我目前正在构建一个双向链表实现。
我正在尝试(或希望)做的是使用 setter / getter 来设置列表中的元素,就像在数组中一样:

var index = 5;
list[index] = node_x;

但是,我不能只使用这种语法,因为节点在技术上不是列表的属性。
将列表视为 2 个钩子。这 2 个钩子连接到链条的两端,但您只能访问这 2 个连接链节(以及通过它们连接的兄弟链节)。
其余的链链接不是列表的属性。这就是为什么我需要在我的对象上覆盖括号

[]
的实现(如果可能的话)。

我的(简化/缩短)代码是:

(function () {
    "use strict"
    window.List = function () {
        var Length //Etc
        return {
            //Getter / Setter example.
            get length() {return this.Length;},
            set length(n) {this.Length = n;},
            //Function example.
            insertBeginning: function (newNode) {/*  */},
            insertEnd: function (newNode) {/*  */},

            //Index getter / setter attempt.
            get i(index){ console.log(index); },
            set i(index, node){ console.log(index); }
        };
    };

}());

var list = new List();
list.length = 10 //This works just fine
console.log(list.length) // Returns 10, like expected.

现在,我尝试使用

i
getter/setter 做的是设置如下元素:

var index = 5;
list.i(index) = node;

但是,这当然行不通,因为:

  1. i
    不是函数;
  2. 显然,我无法将变量分配给函数。

我当然可以只使用一个函数来设置元素:

list.setAtIndex(index, node);

但我更愿意以某种方式覆盖对象的数组表示法。

所以,我的问题是,这可能吗?如果是这样,我可以获得一些提示吗? 我的搜索尝试仅返回资源像这样,我现在知道 getter / setter 是如何工作的。

javascript object getter-setter
4个回答
3
投票

我想说这是一个非常糟糕的主意。对于链表来说,获取索引 i 处的项目的成本是 O(n)。通过索引访问链表是Java所犯的一个错误,其他人不应该重蹈覆辙。 C++ 和 C# 不会犯这个错误。

在大多数情况下,数组通常更适合随机插入和删除,因为线性搜索的

O(n) 成本在性能方面完全占主导地位,并且数组更适合预取。不,真的:http://bulldozer00.com/2012/02/09/vectors-and-lists/

我建议使用完全没有索引访问的链表实现,因为当您确实可以证明您将从使用链表中获得性能优势时,也许可以实现队列。我建议在所有其他情况下使用内置数组。除了在大多数用途中总体上更好之外,您还将获得比任何第三方链表实现更多的内置数组优化的好处。


3
投票
除了这是一个坏主意之外,这根本不可能。


0
投票
自 ES6 以来,通过

代理,这已经成为可能:

class List { constructor() { const isIndex = input => !!input.match(/^\d+$/) return new Proxy({}, { // also available: "delete", "has", ... get: (target, prop, receiver) => { if (isIndex(prop)) { console.log(`getting List[${prop}]`) return `value${prop}` } else { return Reflect.get(target, prop, receiver) } }, set: (target, prop, receiver) => { if (isIndex(prop)) { console.log(`setting List[${prop}]`) // ... } else { return Reflect.set(target, prop, receiver) } } }) } }
    

-1
投票
我不知道你是否喜欢这个,但是看看吧

codepen.io 前

我认为它还不是完全令人满意,因为它默认说在提供参数时,你想要访问

set

© www.soinside.com 2019 - 2024. All rights reserved.