Javascript 为什么使用原型而不是方法

Javascript 为什么使用原型而不是方法,javascript,methods,prototype,Javascript,Methods,Prototype,我在看。这里有一个例子 function Car(){ this.running = false } Car.prototype.start = function(){ this.running = true } Car.prototype.stop = function(){ this.running = false } var c = new Car() c.running // false c.start // true c.running // true 但还有另一种

我在看。这里有一个例子

function Car(){
this.running = false
}
Car.prototype.start = function(){
    this.running = true
}
Car.prototype.stop = function(){
    this.running = false
}

var c = new Car()
c.running // false
c.start // true
c.running // true
但还有另一种方法可以做同样的事情

function Car(){
    this.running = false;
    this.start = function(){
        this.running = true
    }
    this.stop = function(){
        this.running = false
    }
}

var c = new Car()
c.running // false
c.start // true
c.running // true
问题:

  • 与方法相比,使用原型的优缺点是什么
  • 我们什么时候应该避免/使用原型
  • 我们什么时候应该避免/使用方法

  • 理想情况下,每当您希望在一个类型的多个实例之间共享属性时,都可以使用原型。在您的第一个示例中

    function Car() {
      this.running = false
    }
    Car.prototype.start = function() {
      this.running = true
    }
    Car.prototype.stop = function() {
      this.running = false
    }
    
    var c = new Car()
    var d = new Car()
    var e = new Car()
    console.log(c.__proto__ === d.__proto__) //true
    c.running // false
    c.start // true
    c.running // true
    
    在这里,c、d和e的原型对象将保持不变,因此您可以节省运行时内存消耗,因为您可以为这三个对象重用相同的函数,但上下文不同

    在你的第二个例子中

    function Car(){
        this.running = false;
        this.start = function(){
            this.running = true
        }
        this.stop = function(){
            this.running = false
        }
    }
    
    var c = new Car() // check comparing  c.__proto__ ===  d.__proto__
    var d =  new Car()
    var e = new Car()
    c.running // false
    c.start // true
    c.running // 
    
    在这里,c、d、e将拥有自己的函数副本,消耗更多内存!!
    理想情况下,在设计此类对象时应该考虑可重用性。prototype方式似乎比method way更好,性能也更好。

    理想情况下,只要您想在一个类型的多个实例之间共享属性,就可以使用prototype。在您的第一个示例中

    function Car() {
      this.running = false
    }
    Car.prototype.start = function() {
      this.running = true
    }
    Car.prototype.stop = function() {
      this.running = false
    }
    
    var c = new Car()
    var d = new Car()
    var e = new Car()
    console.log(c.__proto__ === d.__proto__) //true
    c.running // false
    c.start // true
    c.running // true
    
    在这里,c、d和e的原型对象将保持不变,因此您可以节省运行时内存消耗,因为您可以为这三个对象重用相同的函数,但上下文不同

    在你的第二个例子中

    function Car(){
        this.running = false;
        this.start = function(){
            this.running = true
        }
        this.stop = function(){
            this.running = false
        }
    }
    
    var c = new Car() // check comparing  c.__proto__ ===  d.__proto__
    var d =  new Car()
    var e = new Car()
    c.running // false
    c.start // true
    c.running // 
    
    在这里,c、d、e将拥有自己的函数副本,消耗更多内存!! 理想情况下,在设计此类对象时应该考虑可重用性。原型方法似乎比方法方法更好,性能更好

  • 原型在性能和内存使用方面更快、更便宜。在第一个示例中,当您调用
    newcar()
    JavaScript时,只创建一个具有1个布尔属性的对象。
    Car
    类的所有实例共享其原型中的相同方法(方法不重复并且引用相同的内存地址,
    carA.start===carB.start
    )。在第二个示例中,每次调用
    new Car()
    都会创建新函数(内存中的不同地址)。每个实例都有自己对方法的引用(它们不是严格相等的,
    carA.start!==carB.start

  • 当需要使用闭包实现封装时,请使用方法(我建议改用
    Symbol
    s)。在所有其他情况下,我们更喜欢原型

  • 顺便说一句,在V8中,通过原型链查找属性/方法要比查找闭包快得多

  • 看#2
  • 原型在性能和内存使用方面更快、更便宜。在第一个示例中,当您调用
    newcar()
    JavaScript时,只创建一个具有1个布尔属性的对象。
    Car
    类的所有实例共享其原型中的相同方法(方法不重复并且引用相同的内存地址,
    carA.start===carB.start
    )。在第二个示例中,每次调用
    new Car()
    都会创建新函数(内存中的不同地址)。每个实例都有自己对方法的引用(它们不是严格相等的,
    carA.start!==carB.start

  • 当需要使用闭包实现封装时,请使用方法(我建议改用
    Symbol
    s)。在所有其他情况下,我们更喜欢原型

  • 顺便说一句,在V8中,通过原型链查找属性/方法要比查找闭包快得多

  • 看#2

  • 我认为你的术语有点不恰当。方法是一个对象属性,它是一个函数——不管这个属性是对象自己的属性还是对象原型的属性。我认为你的术语有点不恰当。方法是一个对象属性,它是一个函数——不管这个属性是对象自己的属性还是对象原型的属性。