函数应该附加到对象还是它的原型上?

ask*_*low 5 javascript prototype object new-operator ecmascript-5

我正在学习 javascript,我想知道对象内部的函数和原型的概念。

我对概念的理解

据我了解,函数应该附加到对象的原型上以分配更少的内存。

例如(如果我说的是真的),两个版本都会做同样的工作,但第二个版本会分配更少的内存:

var collectionOfObjects = [];
for(var i=0; i<1000; i++){
    collectionOfObjects.push({id: 2, sayHi: function(){console .log('hi')}})
}
//vs
function Foobar(id){
    this.id = id || 0;
}
Foobar.prototype.sayHi = function(){
    console.log('hi');
}
var otherCollection = [];
for(var i=0; i<1000; i++){
    otherCollection.push(new Foobar());
}
Run Code Online (Sandbox Code Playgroud)

//this attaches sayHi function to the object instead of its prototype
var foobar = {
    id: 0,
    sayHi: function(){
        console.log('Hi');
    }
}
Run Code Online (Sandbox Code Playgroud)

由于我不应该使用__proto__,我如何将sayHi函数附加到 foobar 的原型而不是 foobar 对象?我认为添加sayHiObject.prototype不是一个好的解决方案,因为它会sayHi为每个对象添加功能。

Ale*_*yne 3

原型链是通过new关键字 aclass或 来设置的Object.create()。无论哪种方式,它都是在创建对象时设置的。

所以你已经知道一种方法,那就是向构造函数的原型添加函数并用 实例化new

现代方法是使用 a class,但您在此处特别提到了遗留代码,因此我将假设出于本次讨论的目的,这已不再适用。

最后一种方法是使用Object.create()它给你一个带有原型的对象:

var myProto = {
  // There is only one of this function, ever.
  sayHi: function() {
    console.log('hi');
  }
}

var otherCollection = [];
for(var i=0; i<1000; i++){
    var obj = Object.create(myProto)
    obj.id = i // or other custom setup.
    otherCollection.push(obj);
}
Run Code Online (Sandbox Code Playgroud)

也就是说,在现代 JavaScript 引擎中,每个对象具有独特的功能并不是什么大问题。我曾经开发过一些相当大的 JavaScript 应用程序,由于函数实例的数量根本就不是性能瓶颈,因此内存使用情况也很糟糕。

例如,在带有功能钩子的现代 React 中,避免在每次渲染上创建数百个新函数将非常麻烦(如果在某些情况下不是不可能的话)。它就是这样设计的,而且仍然表现得很好。如果它表现不好,也绝不是因为功能太多。