Javascript 与在原型上创建的方法相比,在构造函数中创建的方法是否存在性能损失?

Javascript 与在原型上创建的方法相比,在构造函数中创建的方法是否存在性能损失?,javascript,performance,idioms,Javascript,Performance,Idioms,我可以通过两种方式声明对象的方法: 第一种方法使用self=this习惯用法 function SelfIdiomExample(name){ var self = this; self.sayHello = function (name){ alert("Hello, "+name); } } 当您需要方法中对象的引用时(例如,如果该方法将作为回调传递),这非常有用。另一种方法是修改原型: function PrototypeModExample(

我可以通过两种方式声明对象的方法:

第一种方法使用
self=this
习惯用法

function SelfIdiomExample(name){
    var self = this;

    self.sayHello = function (name){
         alert("Hello, "+name);
    }
}
当您需要方法中对象的引用时(例如,如果该方法将作为回调传递),这非常有用。另一种方法是修改原型:

function PrototypeModExample(){
   //pass
}

PrototypeModExample.prototype.sayHello = function(name){
   alert("Hello, "+name);
}
两者都有相同的结果:

var sieg = new SelfIdiomExample();
var pmeg = new PrototypeModExample();

sieg.sayHello("Barnaby");
pmeg.sayHello("Josephine");
当我理解
self=this
习惯用法的用例时,我想知道:


使用构造函数中创建的方法与原型上创建的方法相比,是否存在性能损失?

与往常一样,您必须进行测试才能回答以下问题:

当您进行测试时,似乎没有太大的差异(在某些情况下,低于百分之几,对
self
有轻微的优势)。
self
的一个优点是,通过将其更改为一个字符的变量名,可以更好地将其最小化,这显然是某些框架使用它的原因

在你的例子中,我想说使用
self
是多余的,不是必需的。通常,人们仅在使用闭包时才使用
self
,并且在某些回调中
this
的值不再是您希望的那样:

counter.prototype.incrementWithDelay(delay) {
    var self = this;
    setTimeout(function() {
        self.counter++;
    }, delay);
}
但是,如果您只有一个普通的方法,那么就没有什么理由使用
self

counter.prototype.set(val) {
    this.counter = val;
}
那么这里呢,

var self = this;
这根本不影响性能。它的速度非常快,因为它只是访问一个局部变量。即使是嵌套函数,这在JavaScript中也是一个非常快速的操作

然而,在构造函数中创建的方法与在原型上创建的方法有着巨大的性能差异

在本例中:

var PrototypeModExample = function(){
  this.name = "Joe";
};

PrototypeModExample.prototype.sayHello = function(){
   alert("Hello, " + this.name);
};

var a = new PrototypeModExample();
var b = new PrototypeModExample();
console.log(a.sayHello === b.sayHello); // true
构造函数的每个实例都可以访问相同的函数对象。这可以通过使用
==
操作符比较两个实例上的函数对象来证明。只有当它们是同一对象时,它才会返回
true
。因此,在全球范围内,我们现在有2个实例,但它们共享一个函数对象,用于实现
sayHello
方法。这意味着当您想要创建一个新实例时,该函数已经被设置和创建

换句话说,对于所有实例,
obj.sayHello
指向相同的函数对象,该函数对象在任何实例存在之前创建


但另一方面:

function SelfIdiomExample(name){
    var self = this;
    this.name = "Joe";

    this.sayHello = function(){
         alert("Hello, " + self.name);
    }
}

var a = new SelfIdiomExample();
var b = new SelfIdiomExample();
console.log(a.sayHello === b.sayHello); // false
工作方式不同。现在我们看到
==
比较是错误的。这是因为为每个实例创建了一个新的函数对象。创建此函数需要时间(需要解析)和内存(需要存储此函数的唯一版本)。因此,当创建大量这样的实例时,这种方法既慢又占用更多内存

换句话说,对于所有实例,
obj.sayHello
指向在创建实例本身时创建的唯一函数对象



因此,通常首选原型方法。特别是在可能存在大量实例的情况下,因为每个实例都可以共享其方法的函数对象。

它只是对变量的赋值引用。-使用它来测量“差异”PS:在第一种情况下,您实际上根本不需要
self
,您可以使用
this
在原型方法中始终获得对对象的引用。此外,您在第一个代码段中缺少
var
。请不要忘记使用
var
声明您的局部变量@虫族这是一个非常有用的工具。谢谢它回答了我的问题。我想知道更多关于下面到底发生了什么。谢谢Alex,回想起来,我应该在问问题之前测试一下!这就是我一直在寻找的答案。