Source: http://www.cnblogs.com/renlong0602/p/4387588.html
The center of this article:
This article is more difficult to understand, so it is more obscure to read. So, let me make a brief list of the outlines:
In the first part, starting with the function prototype, the goal is to figure out what this attribute is, why it exists, and what it does when it comes to creating objects!
In the second part, when reading, please clarify the difference between the __proto__ and the built-in objects; make it clear. Then we'll analyze the __proto__ property a little bit.
The third part, originally not in the scope of my writing, but see many articles on the web in succession, the use of a variety of methods. So come on, object.create () The benefits of this approach.
1. Function prototypes 1.1. Function-specific prototype properties
The so-called unique in the title refers to the only function that has the prototype attribute, and the ECMAScript standard stipulates that each function has its own prototype (prototype).
So what is the prototype of this function and what does it do?
- What is the prototype of the function?
Proof in code that a function prototype is an object.Console.log (typeof Object.prototype); "Object", where the object () function is used. Console.log (object.prototype instanceof Object)//true
From the output above, we conclude that the prototype of the function is an object. So what are the attributes of the object itself?
We know that any object has the most basic method, such as toString (). valueof () ... Since the function prototype is an object type, it must also have these basic methods ...
So where do these methods come from? To figure this out, we have to start with the prototype of object ()!
The image above helps us to identify the prototype of the object () function, which has no properties of its own, but it has some very basic methods which are useful for the moment. But for now, remember one point: a function prototype is an object. Because only by knowing the basic point, the following discussion is meaningful.
- What's the use of function prototypes?
Just knowing that the function prototype is an object is just the beginning, because what we want to know is: What is the prototype object of the function, and why should we design this stuff!!
Looking at the following code, we followed the code to analyze:
var object = new Object (); New an Object Console.log (Object.ToString ()); Output This object, the output of the Firefox console [Obejct Object]
There's a very strange phenomenon here ... object objects do not have the ToString () function, so why not error when outputting? Ok! Take a look at the following picture:
In object, which has a __proto__ property, where does this property come from? ...... Wait a minute...... Is there any striking similarity between the value of __proto__ and the value of Object.prototype? Is it a coincidence or is it that they are the same object?!! Let's test it out:
var object = new Object (); Console.log (Object.__proto__==object.prototype); True.
The fact proves once again that there are not so many coincidences in the world!! Object.__ptoto__ and Object.prototype really point to the same object.
Now we have solved a problem, that is object.tosring () This function, the real source is object.prototype. So why does object objects have access to the methods in Object.prototype ... To answer this question, two things need to be clarified:
First, what happens when new Object () occurs?
Second: What does this attribute of __proto__ play?
To understand the above two problems, we still need to analyze the program
When the sentence was executed, the interpreter did three things for us:
(1). Open up some memory space to object;
(2). Point the This pointer to object (for the time being, the this pointer will also open a single question for later). Ok. Now I know what's the use of new;
(3). Add an object to a built-in property property, and the values of __proto__ and built-in properties are always equal;
When new object () is known, the interpreter helps us add a built-in property to the object, and then solves the second problem, what is the use of built-in properties [[__proto__]]?
Look at the code below.var object = new Object (), var proto1 = {};p roto1.name = ' Zhang San ' object.__proto__ = Proto1;console.log (object.name); Zhang San var proto2 = {};p roto2.name = ' John Doe ' object.__proto__ = Proto2;console.log (object.name); John doe
In the above example, object has not changed, but its attribute __proto__ is the object that points to. According to the above example, we can conclude that the object is accessible to the variables owned by the object to which the attribute __proto__ points, and is used as if it were its own property.
Summing up the above, we can draw the conclusion that:
Each function has a prototype of its own, the essence of which is an object, when the function is used as a constructor (that is, the new call), the generated instance will have a built-in property, when the object is accessed, if the corresponding attribute is not found in the instance, it will be based on the built-in properties, Finds the object that the built-in property points to, and then returns undefined if it is not found. (Error in strict mode).
1.2. Constructor property of function prototype prototype
When creating a new function, there is a constructor attribute in the prototype of this function, so does this attribute have any meaning in existence?
Look at the following section of code:
var person=function () {};console.log (Person.prototype.constructor); function constructor is a functional Console.log (Person.prototype.constructor===person);//true Person.prototype.constructor===person
The above code proves that the constructor property is real and the value of this property is initialized to the constructor itself. So what is the important point of this attribute? Then look at the following code:
var person = function () {};var xiaoming = new Person (), Console.log (xiaoming instanceof person); TruePerson.prototype.constructor = null; Console.log (xiaoming instanceof person); True
As can be concluded from the above example, the constructor attribute simply identifies which function the prototype belongs to, although the interpreter gives us the default, but is relatively less important, even if it is useless. For a function, it always looks like this when it's just created.
The fate of 1.3prototype---for inheritance
Some things are destined to happen at the moment you are born. Prototype was destined for his fate at the beginning of his birth. Let's talk about this so-called fate!!
According to part 1.1, we know the prototype of the function, which is assigned to the built-in properties of the instance when the function is instantiated. Suppose there are two classes A and B, the code is as follows:
The A function is as follows var a = function (a) { this.a = A;} A.prototype.geta = function () { return THIS.A;} The B function is as follows var B = function (A, B) { A.call (this, a);//Borrow a class constructor, very important point!!! this.b = b;} B.PROTOTYPE.GETB = function () { return this.b;}
A and B are two classes of constructors, and they are now in memory as shown in the structure:
Now, if we want to make Class B a subclass, how do we do that? First, we should realize that if B is a subclass of a, then B should be able to access the properties and methods in a. Parent Class A has attribute A and method Geta (), then subclass B should also have attribute a and can access method Geta (); If we can implement the structure shown, can we do Class B inheriting Class A?
In contrast, only the "__proto__" in B.prototype has been modified. Then everything happens naturally. In summary, subclass B does two things for inheriting a: Subclass B is passed A.call (); This step borrows the Class A's variables from A's constructor and modifies the "__proto__" in the prototype to access the functions in Class A. Think of here have to say a good great design. There are several n ways to implement inheritance, but be aware that if you consider the allocations in memory and the robustness of the efficiency and the program, then only one function can be done perfectly as shown in the diagram. This function is the object.create () function, the fate of this function is to implement inheritance.
Why do you say so, please look at the second part of slowly parsing!!
The difference between the 2.__proto__ property and the built-in property 2.1. Do you really understand __proto__ this attribute?
If you think you know this property well, consider the following questions.
1. What is the nature of this attribute? Accessor property or Data property?
2. Where does this attribute exist? Whether each object has or only one copy of the entire memory.
3. What does this attribute have to do with built-in properties?
If you're confused about the last question above, or if you think __proto__ is a built-in attribute, then it's time to take a moment to see the three.
2.1.1. Proving that 1:__proto__ is an accessor attribute
Look at the following section of code:
var descriptor=object.getownpropertydescriptor (Object.prototype, "__proto__"); Console.log (descriptor); Output Result:
Configurable |
True |
Enumerable |
False |
Get |
function () {[native code]} |
Set |
function () {[native code]} |
If you see the above output, have you accepted that __proto__ is an accessor property .... If you don't believe it. Then look, it's just the beginning of your worldview!!!
2.1.2. Proving that the 2:__proto__ attribute only saves one copy in memory
We know configurable=true from the output of proof 1, which tells us that this object can be deleted ... Here's a look at the code:
var object={};var result=delete Object.__proto__;console.log (result); Trueconsole.log (typeof object.__proto__)//object.
Please answer? Why does the display delete succeed, typeof object.__proto__ or Output object?
Ok!! To understand this thoroughly, we insert some knowledge of the delete operator.
ECMAScript: The delete operator removes references to previously defined object properties or methods, and the delete operator cannot delete properties and methods that are not defined by the developer.
So what happens when the delete works?
Delelte operation if you want to have three conditions for normal operation: 1, this property is written by us, that is, the property exists. 2. Delete the property or method of an object. 3. This property can be deleted at configuration time, i.e. (configurable=true).
So, in the example above, the return value is true. Does it conform to the three criteria above?
For 1, this property is accessible, so it proves that the attribute exists.
For 2,__proto__ is an attribute of an object.
For 3: Because of configurable=true, so it is also in line.
Ok! above the three points are consistent with the return value equal to true, the deletion or failure! Because there is another case where deleting a property that does not exist at all on the object will also return true!
var object = {};
Object.prototype.x={};var result = delete Object.x;console.log (result); True.console.log (object.x);//object
See, these two examples are similar to the output results? Because the __proto__ property exists on the prototype on the object, the object can be accessed. However, you cannot delete the property. If you want to delete this property, delete it on the object.prototype. This guarantee can be removed successfully.
To confirm this, let's look at
var object={};console.log (typeof object.__proto__); Objectdelete Object.prototype.__proto__;console.log (typeof object.__proto__); Undefined delete succeeded.
We can find that after Object.prototype delete the __proto__ property. It cannot be accessed on an object. This is because, therefore, the object has a common prototype Object.prototype. Delete __proto__ on this, then all objects do not have this __proto__ attribute.
This proves that only one copy of the __proto__ attribute is stored in memory and that the attribute is defined on the Object.prototype object.
2.1.3. What does this attribute have to do with built-in properties?
To some extent, __proto__ is always equal to the built-in properties of the object if it exists. And in the last article we also point out that changing the direction of __proto__ can also change the direction of the built-in properties. So, if you stubbornly think of __proto__ as a built-in object, that's understandable.
But please remember two points:
1. The built-in objects are not visible, but the built-in objects always exist.
2.__proto__ if present, then its value is the built-in object, but this __proto__ does not always exist.
If you must think that __proto__ is a built-in object, you can, but make sure two points: do not use the __proto__ attribute anywhere in the program. Or, if you must use the __proto__ attribute, make sure you never modify the __proto__!! in the Object.prototype.
If you cannot guarantee these two points, please stay away from __proto__. Because, once someone does not abide by the agreement, the harm of this bug is too expensive. For example, the following ...
var A = function () {}a.prototype.say = function () { return ' hello ';} var B = function () {}//subclass inherits the parent class function extend (subclass, superclass) { var object = { }; object.__proto__ = Superclass.prototype; Subclass.prototype = object; SubClass.prototype.constructor = Subclass;} Extend (B, A); b Inherit A
The above is a piece of code that has no problem ... But if there is a small white user, on one day executed the following sentence code,
var A = function () {}a.prototype.say = function () { return ' hello ';} var B = function () {}function extend (subclass, superclass) { var object = { }; object.__proto__ = Superclass.prototype; Subclass.prototype = object; SubClass.prototype.constructor = Subclass;} Delete object.prototype.__proto__; or other extend (b, A); var B = new B (); B.say (); Typeerror:b.say is not a function error ... If this is the mistake, debugging will certainly make you want to cry without tears. So, if you want to write a good program, please stay away from __proto__.
2.2.object.create () was born
When there is no hero, so zeros fame! The prevalence of JavaScript today can be said to be the portrayal of this statement. Object.create () is also so, in the inheritance is not we do not use it, but after excluding the use of __proto__, in addition to using this function, we have no other better choice.
How is this function defined in this function?
object.create function (JavaScript)
Creates an object that has the specified prototype and optionally contains the specified property.
Object.create (prototype, descriptors)
Parameters
-
- Prototype
-
-
Necessary. the object to use as a prototype. can be null.
-
- Descriptors
-
Optional. a JavaScript object that contains one or more property descriptors.
A Data property is a property that can be obtained and can be set to a value.The Data property descriptor containsValue attribute, andWritable,Enumerable andConfigurable characteristics.If the last three attributes are not specified, they default tofalse. The accessor property invokes the user-supplied function whenever the value is retrieved or set. The Accessor property descriptor contains the set attribute and/or the get attribute. For more information, see Object.defineproperty Functions (JavaScript).
This is the definition of this function in the list, let me give an example to illustrate how to use this function!!!
var A = function (name) { this.name = name;}; A.prototype.getname = function () { return This.name}var Returnobject = Object.create (A.prototype, { name: { Value: ' Zhangsan ', configurable:true, enumerable:false, writable:true }});
After the above code has finished running, returnobject in-memory structure:
Take a look at the diagram above, the last diagram in analogy 1.3, as follows:
Discover is not, strikingly similar ... So, know Objece.create () of the strong bar!! As we have analyzed, the following diagram is the perfect state to achieve inheritance, and object.create () is a function designed to do this, professionally for inheritance.
Here is a section of the code using the Object.create () function to implement subclasses inheriting the parent class;
The subclass inherits the parent class, which executes the delete object.prototype.__proto__, and the code continues to function correctly.
function extend (subclass, superclass) { var prototype=object.create (superclass.prototype);
SubClass.prototype.constructor = subclass; }
var A = function () {
}
A.prototype.say = function () {
return ' Hello ';
}
var B = function () {
}
Extend (B, A);
var B = new B ();
B.say (); Hello
Ok! I know that you can implement inheritance in n multiple ways, but keep in mind that you should not use the __proto__ attribute when inheriting, because it is not as reliable as you think. If you want to get a prototype of an object, then this method can be done, object.getprototypeof. Corresponding to this is the Object.setprototypeof method.
You may also say that the Object.setprototypeof method can be inherited away from the __proto__. If you were to see the source code, would you say that?
object.setprototypeof = object.setprototypeof | | function (obj, proto) { Obj.__proto_ _ = Proto; It is also used to __proto__. return obj; }
Summarize:
The whole article, from prototype, analyzes the type and function of the function prototype (which everyone is talking about).
In the second part, we analyze __proto__, the results, built-in properties and __proto__ are not the same thing at all. __proto__ This property is not reliable. Aside from that, this property is a non-standard attribute, so the hidden bug can kill people, so when writing a program, remember, cherish life, stay away from __proto__.
In the end, we talk a little bit about the benefits of inheriting with object.create (). This part, it is difficult to speak clearly, need to slowly understand.
In the next article, we will analyze why we say everything in JS is an Object!
JavaScript Series----Object-oriented JavaScript