Wrapping my head around prototypes in JS [duplicat

2019-07-04 16:22发布

This question already has an answer here:

I've been trying to understand the concept of prototypes in JS, but for some reason I'm finding it really baffling. Why and when would you use a prototype?

What's the difference between this (from this MDN example):

function Person(gender) {
  this.gender = gender;
}

Person.prototype.sayHello = function()
{
  alert ('hello');
};

And this:

function Person(gender) {
  this.gender = gender;

  this.sayHello = function() {
    alert('hello');
  };
}

I think I understand how to use them, but I don't know why I would use them. Maybe I'm missing something - scratch that - CLEARLY I'm missing something!

Can someone please explain the difference between those two examples and why I should use one over the other?

Thanks!

4条回答
趁早两清
2楼-- · 2019-07-04 16:49

Prototype is important for inheritance. If you do not need inheritance, then there is really no difference. However, consider this:

function Person(gender) {
 this.gender = gender;

 this.sayHello = function() {
  alert('hello');
 };
}

function User(){

}

How can a User be a Person? There is really no easy way here. However, this is possible with prototype:

jsFiddle Demo

function Person(name) {
 this.name = name;
}

Person.prototype.sayHello = function() {
  alert(this.name);
 };

function User(name){
 this.constructor(name);
}

User.prototype = new Person();

var u = new User("joe");
u.sayHello();//alerts joe

Now, we can go even further, and override the functionality of saying hello for User when using prototype like this:

jsFiddle Demo

User.prototype.sayHello = function(){ 
 alert("Username: " + this.name);
}
查看更多
欢心
3楼-- · 2019-07-04 17:02

When you create a new Person() with the prototype example, it will not load sayHello() into the memory with the person object.

Instead, it will add it to the object as soon as it is needed/called, and it is only loaded once when it is.

When working with a lot of objects, this could save a lot of memory for the user.

查看更多
趁早两清
4楼-- · 2019-07-04 17:04

classes and inheritance. instead of spending an hour or two explaining it myself I highly recommend going through this little tutorial. I skipped it ahead to the section on prototypes and it explains it very well in a fun way.

查看更多
闹够了就滚
5楼-- · 2019-07-04 17:15

Person is a constructor and it is executed every time a new instance is created. Constructors are just functions and functions are just objects in JavaScript. Functions can have properties f.a = 1, just like a basic object: o = {a: 1}.

When you add a function as a property of an object, it's called a method. So by defining the methods of Person in the constructor, they are redefined on ever instantiation. As pointed out already, this is extra work.

By defining the methods upfront using the prototype property of functions, the methods are defined only once.

An additional benefit of defining methods on the prototype is that they become static. Static methods do not require an instance object. For example, the array slice method can be invoked on an array instance: [1,2,3].slice(1). But if we don't have an array instance, we can still access and invoke the slice method from the Array object's prototype: Array.prototype.slice.call(arguments).

Edit: static methods are more commonly seen as Object.method, not necessarily properties of the prototype. It should be clarified that the instance method .slice() was being invoked statically.

查看更多
登录 后发表回答