【问题标题】:What is the difference between assigning a function directly to a constructor versus to it's prototype, and why?将函数直接分配给构造函数与原型之间有什么区别,为什么?
【发布时间】:2014-02-17 20:05:49
【问题描述】:

如果它关闭,请原谅我的术语。我不明白两者之间的区别:

function Person() {};
Person.walk = function() {};

还有……

function Person() {};
Person.prototype.walk = function() {};

似乎第二种方式是构造函数的约定,但我不明白区别以及为什么这样做。谢谢!

【问题讨论】:

  • 第一个类似静态方法,第二个依赖实例。
  • 就像一些答案澄清的那样,第一个是静态方法,第二个是您可以在实例上调用的方法。有关构造函数和原型的更多信息:stackoverflow.com/a/16063711/1641941

标签: javascript inheritance constructor prototype


【解决方案1】:

第一种情况:

function Person() {};
Person.walk = function() {};

您只能通过以下方式调用该函数:

Person.walk();

如果你创建了 Person 的实例,你将无法调用该方法:

p = new Person();
p.walk() // -> TypeError: Object #<Person>  has no method 'walk'

另一方面,如果使用原型,则只能通过实例调用方法。

【讨论】:

  • 使用原型方法你仍然可以通过 Person.prototype.walk() 调用该方法,但我不确定你为什么要这样做。
  • p.prototype.walk(); 不正确。 p 没有属性 prototype
  • 是的,没错。我什至从 p.__proto__.walk() 都试过了。
【解决方案2】:

第一个函数与该构造函数的对象实例没有关系,您可以将其视为“静态方法”。

第二个函数,当你扩展构造函数原型时,它将可用于使用 new 关键字创建的所有对象实例

例子:

// constructor function

function MyClass () {
  var privateVariable; // private member only available within the constructor fn

  this.privilegedMethod = function () { // it can access private members
  //..
  };
}

// A 'static method', it's just like a normal function 
// it has no relation with any 'MyClass' object instance
MyClass.staticMethod = function () {};

MyClass.prototype.publicMethod = function () {
// the 'this' keyword refers to the object instance
// you can access only 'privileged' and 'public' members
};

var myObj = new MyClass(); // new object instance

myObj.publicMethod();
MyClass.staticMethod();

【讨论】:

    【解决方案3】:

    原型是一种用于创建实例的模板,与构造函数不同。请注意,原型的成员实际上并未复制到实例中,而是实例利用原型的资源,除非该资源已由实例拥有。

    var Class = function () {};
    Class.prototype.a = 1;
    Class.prototype.b = 2;
    
    // creates a new instance named "c"
    var c = new Class();
    c.b = 3;
    
    console.log(
        c.hasOwnProperty('a'), // -> false
        c.hasOwnProperty('b'), // -> true
        c.a, // -> 1 (prototype)
        c.b, // -> 3 (instance)
        Class.prototype.b // -> 2 (prototype)
    );
    

    【讨论】:

    • “原型的成员实际上并未复制到实例中,而是实例利用原型的资源”是什么意思。当我在创建 var c = new Class() 之后在控制台中键入 c 时,它表明 c 是一个具有“a”和“b”属性的对象。这不意味着那些原型属性(或成员......属性/成员是同一件事吗?)是该 c 对象的一部分?
    • @natecraft1 我无法更好地解释这一点:stackoverflow.com/a/572996/1636522 :D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 2023-03-18
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多