将函数追加到JavaScript Object Literal的__proto__属性是否是一个好主意?

我有一个对象文字:

var tasks = {}; 

我基本上增加了这样的东西:

 function addTask(task) { tasks[task.id] = task } 

我想修改,以便我可以调用每个任务的startfunction。 所以:

 var tasks = {}; tasks.__proto__.start = function(key) { // do stuff with this[key] } function addTask(task) { tasks[task.id] = task tasks.start(task.id) } 

我听说最好避免原始对象,并减缓执行速度。 不过我不会重新分配它,我正在追加它。

有没有其他更好的select?

实际上没有必要为此使用原型。 您不需要创build很多实例,只需要在较高级别抽象出一个通用的function,就可以在tasks对象上添加一个方法。

 const tasks = { start(key) { const task = this[key] // do stuff with task } } // example call tasks.start('123'); 

如果您想确保与现有密钥没有冲突,则可以使用符号 。

 const startSymbol = Symbol('start'); const tasks = { [startSymbol](key) { const task = this[key] // do stuff with task } } // example call tasks[startSymbol]('123'); 

你也可以有一个独立的函数来实现这一点,类似于你的addTask函数:

 function start(tasks, key) { const task = tasks[key] // do stuff with task } // example call start(tasks, '123') 

拥有这个独立的function可能会更好,因为您不必担心任务键和方法名称之间的冲突。

你也可以创build一个包装对象来完成这个分离:

 const taskManager = { tasks: {} // map of key to task // methods add(task) { this.tasks[task.id] = task; this.start(task.id); } start(key) { const task = this.tasks[key]; // do stuff with task } } // example usage taskManager.start('123') 

这种方法的优点在于,你的tasks被封装在一个容器中,对它们进行操作,限制了应该使用tasks的范围,并且更清楚地向程序员指出哪些函数是用来完成任务的。

如果你计划有多个任务pipe理器,那么使用原型可能在这里有意义:

 class TaskManager { constructor() { this.tasks = {} // map of key to task } // methods add(task) { this.tasks[task.id] = task; this.start(task.id); } start(key) { const task = this.tasks[key]; // do stuff with task } } // example usage new TaskManager().start('123') 

从性能和浏览器兼容性的angular度来看,这不是一个好主意。

请参阅mozilla文档中的这些警告:

警告:根据现代JavaScript引擎如何优化属性访问,更改对象的[[Prototype]]是一个非常慢的操作,在每个浏览器和JavaScript引擎中。 对改变inheritance的效果的影响是微妙而又遥远的,并不仅限于在obj上花费的时间。 proto = …语句,但可以扩展到任何访问其[[Prototype]]已被更改的任何对象的代码。 如果你关心性能,你应该避免设置一个对象的[[Prototype]]。 相反,使用Object.create()创build一个具有所需[[Prototype]]的新对象。

警告:虽然Object.prototype。 proto目前在大多数浏览器中都受支持,它的存在和确切的行为仅在ECMAScript 2015规范中作为遗留function标准化,以确保与Web浏览器的兼容性。 为了获得更好的支持,build议只使用Object.getPrototypeOf()。