我目前正在构建一个双向链表实现。
我正在尝试(或希望)做的是使用 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;
但是,这当然行不通,因为:
i
不是函数;我当然可以只使用一个函数来设置元素:
list.setAtIndex(index, node);
但我更愿意以某种方式覆盖对象的数组表示法。
所以,我的问题是,这可能吗?如果是这样,我可以获得一些提示吗? 我的搜索尝试仅返回资源像这样,我现在知道 getter / setter 是如何工作的。
我想说这是一个非常糟糕的主意。对于链表来说,获取索引 i 处的项目的成本是 O(n)。通过索引访问链表是Java所犯的一个错误,其他人不应该重蹈覆辙。 C++ 和 C# 不会犯这个错误。
在大多数情况下,数组通常更适合随机插入和删除,因为线性搜索的O(n) 成本在性能方面完全占主导地位,并且数组更适合预取。不,真的:http://bulldozer00.com/2012/02/09/vectors-and-lists/
我建议使用完全没有索引访问的链表实现,因为当您确实可以证明您将从使用链表中获得性能优势时,也许可以实现队列。我建议在所有其他情况下使用内置数组。除了在大多数用途中总体上更好之外,您还将获得比任何第三方链表实现更多的内置数组优化的好处。
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)
}
}
})
}
}