The writing method in advanced programming is as follows
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.lessons = ['Math','Physics'];
}
Person.prototype = {
constructor: Person,
getName: function(){
return this.name;
}
}
So if I write it like this, is it the same? The only difference is that their constructors are different?
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.lessons = ['Math','Physics'];
Person.prototype.getName = function(){
return this.name;
}
}
PHP中文网2017-05-19 10:35:10
The second way of writing will perform the operation on the prototype every time an instance is created! The point is that this operation is meaningless, and this method is the same for every instance.
In the first method, when the prototype is written outside the constructor, the problem of repeated definition or memory allocation can be solved both formally and through memory allocation.
Corresponding to the first way of writing in memory, no matter how many instances you create, each instance occupies only name, age, job and lessons. There is only one copy of getName in memory, shared by all instances; in the second way of writing, each newly created instance will allocate an extra space (stack) to execute the prototype definition.
The big difference is that once a function class is defined, its default constructor property is itself, and its instance will return this value when accessing the constructor property.
function Person() {};
console.log(Person.prototype.constructor); // Person
var p = new Person();
console.log(p.constructor); // Person 表示p的构造函数是Person类
Why do you need to define constructor in method 1? Because it reassigns the prototype. If you don’t define constructor (Person.prototype = {getName: function() {}}
),那么上例中p.constructor
返回值将是 Object
, that is, the constructor of p is Object, which is obviously inconsistent with the facts.
The more sensible approach in method 1 is not to reassign the prototype, but only add the attribute getName we need to the prototype, and change it to Person.prototype.getName = function() {return this.name;}
, which is the definition method in the second method. This way, the default attributes of the prototype will not be overwritten.
習慣沉默2017-05-19 10:35:10
首先,你应该搞清楚js中的原型,在js中,原型指的是构造函数的prototype属性的值,由构造函数创建出来的实例会自动链接到原型对象也就是其构造函数的prototype属性上。
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.lessons = ['Math','Physics'];
}
Person.prototype = {
constructor: Person,
getName: function(){
return this.name;
}
}
这个写法中,Person为构造函数,可以创建出一个实例对象,
var p=new Person();
然后p可以继承原型中的属性,在原型中constructor指向的是当前的构造函数
你的写法可以理解为在构造函数中给原型的getname属性赋值了一个函数
PHPz2017-05-19 10:35:10
The former way of writing rewrites the prototype, and your way of writing just adds a method to the prototype. The two are different ways
世界只因有你2017-05-19 10:35:10
According to the way you write it, storage space will be reallocated to the instance during each instantiation process. One of the meanings of the prototype pattern is that all instances can share the attributes and methods on the prototype, although doing so alone has flaws. The second point is that I still prefer to write the prototype object object literal. I personally think that one is more intuitive, and the second is conducive to maintenance. As follows:
Person.prototype = {
constructor: Person,
getName: function(){
return this.name;
}
}
Be sure to write the constructor attribute, otherwise a pointing error will occur. At this time, the prototype object is rewritten. If this attribute is not specified, the prototype chain will not be able to play its due role.
为情所困2017-05-19 10:35:10
The prototype chain is not perfect, it contains the following two problems.
Question 1: When the prototype chain contains a prototype of a reference type value, the reference type value will be shared by all instances;
Question 2: When creating a subtype (such as creating an instance of Son), parameters cannot be passed to the constructor of a supertype (such as Father).
In view of this, in practice the prototype chain is rarely used alone.
To this end, there will be some attempts below to make up for the shortcomings of the prototype chain.
In order to solve the above two problems in the prototype chain, we started to use a technique called borrowing constructors (constructor stealing) (also called classic inheritance).
Basic idea: call the supertype constructor inside the subtype constructor.
function Father(){
this.colors = ["red","blue","green"];
}
function Son(){
Father.call(this);//继承了Father,且向父类型传递参数
}
var instance1 = new Son();
instance1.colors.push("black");
console.log(instance1.colors);//"red,blue,green,black"
var instance2 = new Son();
console.log(instance2.colors);//"red,blue,green" 可见引用类型值是独立的
Obviously, borrowing constructors solves the two major problems of the prototype chain in one fell swoop:
First, it ensures the independence of reference type values in the prototype chain and is no longer shared by all instances;
Second, when creating a subtype, you can also pass parameters to the parent type.
Following this, if you only borrow the constructor, you will not be able to avoid the problems of the constructor pattern - the methods are all defined in the constructor, so function reuse is not available. And supertypes (such as Father ) are also invisible to subtypes. Considering this, the technique of borrowing constructors is rarely used alone.
For more information, please refer to JS Prototype Chain and Inheritance. Don’t be confused anymore. Just click if you like it. Like and support, thank you!