Note:
A. All the code in this article is tested in the chrome browser. We recommend that you install a chrome browser;
B. This article complies with the fifth edition of ECMA-262 specifications
C. The output in this article uses the console. log function. Press F12 to enter the debugging mode and view the console output;
D. Source Code URL
E. Reprinted with the source.
1. What is an object?
Javascript itself does not have the concept of a class. It only has the concept of an object, except for the basic types (string, number, boolean, null, undefined, even functions are objects.
So what is an object ?! Objects in javascript are similar to a set of key-value pairs. You can even operate on objects in javascript as follows:
Var myDog = new Object ();
MyDog ["name"] = "Odie ";
MyDog ["color"] = "Yellow ";
Console. log (myDog ["name"]);
Console. log (myDog ["color"]);
The effects of object creation in this way are the same:
Var myDog = new Object ();
MyDog. name = "Odie ";
MyDog. color = "Yellow ";
Console. log (myDog. name );
Console. log (myDog. color );
Obviously, the second access method is more convenient. this method is usually used only when the attribute name of the object we access is not determined (such as json data. of course, if you think of a wonderful property name like "hello world" (with spaces), you must create an object using a key-value pair.
2. How to create an object?
ExampleA:
// It is simple and convenient to create objects using the literal method. It can be considered as a shorthand for the exampleB method.
Var myDog = {name: "Odie", color: "Yellow "};
ExampleB:
// Use the new operator to create an object and then append the property.
Var myDog = new Object ();
MyDog. name = "Odie ";
MyDog. color = "Yellow ";
In js, if you do not have any attribute for the assignment operation, you will create one. This method is already used in Topic 1. in exampleA, attributes can be appended. The biggest difference between A and B is the method of creating an object (the main difference is in the first line), not the append attribute. it is worth noting that this is only true when values are assigned. If you perform an access operation, it will not be created (remember this, it is important in the following topics ).
Simple Verification:
Var myDog = {name: "Odie", color: "Yellow "};
Console. log (myDog. age); // undefined
For (var pro in myDog) {console. log (pro) ;}// name, color, no age
ExampleC:
// A rarely used method
Var myDog = Object. create (new Object ());
MyDog. name = "Odie ";
MyDog. color = "Yellow ";
This method is rarely used. It is difficult to explain its purpose here. Leave it to the end.
In fact, there are still differences in the three methods of object creation: A, B, and C. It is hard to say here, leave it behind.
ExampleD:
// If it is a simple object, it seems that exampleA is the most convenient, but when you want to create a complex object, or a large number of similar objects, you should consider the following method.
Function Dog (name, color ){
This. name = name;
This. color = color;
}
Var myDog = new Dog ("Odie", "Yellow ");
Wait. Why is a new function ?! Anyone who has learned other OO languages will be surprised. As I said before, javascript has no class concept at all. Let's output the built-in objects and dates in the browser:
Console. log (Object );
Console. log (Date );
Results In chrome:
Function Object () {[native code]}
Function Date () {[native code]}
Results In firefox:
[Object Function]
[Object Function]
The truth is that Object and Date are not called classes, but functions! In javascript, the object is created using "new function (parameter. we call this function as a constructor. exampleB and exampleD are in the same way. They only use their own constructor in exampleD.
So what happened in the Process of "new Constructor (parameter ?!
1. Create a new object // implicit reference of the object "_ proto _" pointing to the "prototype" of the constructor (ignore the latter sentence first );
2. Point the constructor's "this" to a new object;
3. Execute the constructor (initialize and add attributes to the new object );
4. Return this object.
After the preceding steps, a new object is created.
What is the difference between constructors and other functions ?!
The only difference is that you need to use the new keyword to call constructors, but there is no difference in syntax. All functions have prototype and this references, constructor only uses uppercase letters for definition, and remembers to use the new keyword when calling the constructor. However, it depends on self-consciousness. javascript itself does not have the syntax to specify which function is the constructor. you do not need the new keyword to call the constructor (non-strict mode) or a new common function will not report an error. Of course, the result is naturally not what you want (what will happen later ).
What is this ?!
This is a reference within a function. Similar to other OO languages, it points to the object where the function data is executed. All functions have such a reference.
What is an object for Data Execution ?!
It is not very easy to describe this thing. It can be understood as the object under which the function runs (or not very understandable). Let's just give an example.
// Output your own thisfunction log_this () {console. log (this);} // initialize window. onload = function () {// example_onelog_division ("example_one"); log_this (); // window object // example_two suppose you have a btn button document. getElementById ("btn "). onclick = log_this; // click --> dom object // example_threelog_division ("example_three"); var temp ={}; // The method for creating an object in exampleA. logThis = log_this; // The function is also an object. You can add the function attribute to the object. The above onclick listens to the callback function, which is similar to temp. logThis (); // Object}
This time I understand it. Where does this point? It depends on the runtime environment. this points to its runtime environment object. In the one example, it points to window, two points to the dom object, and three points to the custom object. therefore, if you do not need to call the new constructor, the property will be added to the window. // digress. In strict mode, an error will be reported.
How do I define object functions ?!
You can:
function Dog(name, color) {this.name = name;this.color = color;this.sayName = function(){console.log(this.name);};}
As mentioned above, function is also an object, which is equivalent to adding a sayName attribute of the function type to the object during the execution of the constructor, but there is a problem in doing so, A new function object is created every time you execute the constructor. Obviously, all the Dog objects share a sayName function. based on the current knowledge, you can naturally do this:
function Dog(name, color) {this.name = name;this.color = color;this.sayName = sayName;}function sayName() {console.log(this.name);}
A global function of sayName is defined here, so that a new sayName function will not be created every time the constructor is executed. to define multiple functions for an object, you need to define multiple global functions. when you want to define multiple objects, the number of global functions will pop up and become uncontrollable.
3. prototype !!!!!
Fortunately, you can use the prototype object of the function to view the following code:
function Dog(name, color) {this.name = name;this.color = color;}Dog.prototype.sayName = function() {console.log(this.name);};var myDog = new Dog("Odie", "Yellow");myDog.sayName();//Odie
Again, function is also an object (except for objects of basic types ). in javascript, each function has a prototype object. so, "Dog. prototype. sayName = function (){...}; "This method adds a function object named sayName to Dog's ptototype.
Success ?!,
In the above Code, how does the new object myDog point to the sayName function of the prototype of Dog (a bit around ?!
Remember what happened in the Process of "new Constructor (parameter ?!
1. Create a new object with the implicit reference "_ proto _" pointing to the "prototype" of the constructor ";
2. Point the constructor's "this" to a new object;
3. Execute the constructor (initialize and add attributes to the new object );
4. Return this object.
Next we will explain the last half of the ignored sentences.
Each object has an implicit prototype reference pointing to its constructor (assigned a value during construction ).
What is implicit reference? You cannot see it. You cannot use myDog. prototype (in firefox and chrome, you can use myDog. _ proto ). but you can use its attributes! Therefore, you can use "myDog. sayName ();" to call the sayName function of prototype of the constructor Dog.
What if the object attributes and the prototype attributes of the object's constructor have the same name ?!
Naturally, the object's attributes are accessed first. every time you access an object's attributes, you first search for the object itself. If it does not, then you can find whether the prototype object indicated by _ proto _ has this attribute.
What if no ?!
Will not stop! Don't forget, prototype is also an object, it also has a _ proto _ implicit reference, it will continue to search for this reference... search... search... search until the _ proto _ reference points to null.
In the above example, it quickly points to null.
Var myDog = new Dog ("Odie", "Yellow ");
Console. log (myDog. _ proto __);
Console. log (myDog. _ proto _. _ proto __);
Console. log (myDog. _ proto __);
Results In chrome:
Dog {say: function} // more details
Object {}
Null
Results In firefox:
[Object Object]
[Object Object]
Null
It is the chained search mechanism like javascript that makes inheritance possible (here Dog inherits the Object). This will be explained later.
Prototype in javascript implements the object sharing mechanism. All objects created by the same constructor have a recessive pointer to the prototype of the constructor, then, we use the javascript access attribute search mechanism to achieve sharing. this is similar to the static variables and static functions of classes in other OO languages. since functions are shared through prototype, attributes can also be shared.
Function Dog (name, color) {this. name = name; this. color = color;} Dog. prototype. sayName = function () {console. log (this. name) ;}; Dog. prototype. kind = "Dog"; var myDog = new Dog ("Odie", "Yellow"); var youDog = new Dog ("Oalive", "Black "); // read the console from an object. log (myDog. kind); // Dogconsole. log (youDog. kind); // Dog // but the prototype attribute myDog cannot be modified through the object. kind = "cat"; console. log (myDog. kind); // catconsole. log (youDog. kind); // dog
The above Code defines a kind attribute of prototype. You can see that you can directly access this attribute through an object, but cannot modify it through an object.
Why ?!
As mentioned above, each object has a implicit reference pointing to prototype, which you cannot find. "_ proto _" is only supported by chrome and firefox browsers, it is not a javascript standard (in a back step, even if it is a standard, you should modify myDog1. _ proto __. kind = "dog "). the reason why you can access global attributes through objects is determined by the javascript search mechanism. When you access an attribute, you cannot find it, the prototype indicated by the implicit reference to the object continues to be found.
When talking about objects at the beginning, I specifically emphasized that when accessing an object's attributes, if not, I would not append an attribute to the object, the last half is that it will continue to search for the prototype object it points. this is how javascript processes Access attributes.
The value assignment operation does not involve this search process. If not, an attribute is directly appended! Therefore, myDog1.kind = "dog"; this appends a kind attribute to myDog1. When myDog1 accesses the kind attribute, it finds this attribute on its own and naturally does not continue searching.
How can we modify the prototype attribute?
Who has prototype "normal" reference? -- function -- that is, constructor.
Dog. prototype. kind = "dog ";
It can also be like this, but _ proto _ is not a standard. Even if it is, it is not recommended to write like this:
MyDog1. _ proto _. kind = "dog ";
A. B .C differences between the three object creation methods
ExampleA:
// It is simple and convenient to create objects using the literal method. It can be considered as a shorthand for the exampleB method.
Var myDog = {name: "Odie", color: "Yellow "};
ExampleB:
// Use the new operator to create an object and then append the property.
Var myDog = new Object ();
MyDog. name = "Odie ";
MyDog. color = "Yellow ";
ExampleC:
// A rarely used method
Var myDog = Object. create (new Object ());
MyDog. name = "Odie ";
MyDog. color = "Yellow ";
The only difference between A and B is that, in A browser, A creates an Object without calling the Object constructor.
C. I didn't explain it before. This method is very different from A. B.
First, describe the Object. create (prototype, descriptors) function, which can create an object of the specified prototype, the prototype parameter is the specified prototype that you want to add to the created object // ignore the following parameters (optional ).
"Var myDog = Object. create (new Object (); "is to create an Object based on the Object instance, that is, the Hidden Pointer of the created Object points to the instance of the Object.
The process is similar:
Function (proto ){
Fucntion F (){};
F. prototype = proto;
Return new F ();
}
Output myDog's _ proto __;
Console. log (myDog. _ proto _); // Object {}
Console. log (myDog. _ proto _. _ proto _); // Object {}
Console. log (myDog. _ proto _); // null
Why are the first two objects "Object {}"? Because this is based on the prototype of the Object instance, myDog's _ proto _ points to the Object instance, the instance actually points to the prototype of the Object.
If so:
Var myDog = Object. create (Object. prototype );
Just sum
Var myDog = new Object ();
Yes.
Prototype links
CF --> constructZ restart? Http://www.bkjia.com/kf/ware/vc/ "target =" _ blank "class =" keylink "> keys/K/keys + IENGubnU7LXEyrXA/keys + Csq1z98gLS0 + INX9s6PS/keys + keys/O5ss/keys + ckNGcLG + response/WtcTByy48YnI + response/LL/response + Cjxicj4Kyc/response + Cjxicj4K0vK0yyzKx7/response + response "Odie ", "Yellow ");
Console. log (myDog. constructor );
How can we prove that constructor is a prototype attribute rather than an object of myDog1 ?!
The Object has a hasOwnProperty (name) function to judge:
Console. log (myDog. hasOwnProperty ("constructor"); // false
Console. log (myDog. hasOwnProperty ("hasOwnProperty"); // false, hasOwnProperty is the prototype function of the Object.
Console. log (myDog. hasOwnProperty ("sayName"); // false, This is the prototype function of Dog.
Console. log (myDog. hasOwnProperty ("name"); // This is your own property.
4 inheritance
Javascript objects can be divided into two parts: their own attributes and the attributes shared from prototype.
To implement inheritance in javascript, You need:
1. The sub-constructor also constructs the attributes constructed by the parent constructor during execution;
2. inherit the shared attribute of the parent constructor-point the implicit reference _ proto _ of the prototype object of the sub-constructor to the prototype of the parent constructor. Based on the javascript search mechanism, the prototype of the parent class can be shared;
Javascript has no class and only objects. If you have to move closer to other OO languages, you can replace the parent constructor with the parent class.
Construct the properties of the parent Constructor
If you can pass this directly to the parent constructor during the Sub-constructor construction process, just run the parent constructor once.
Javascript does provide such a method, that is, the function object call function.
Call function usage
Remember this reference of the function-that is, the reference of the object in which the function is executed (it can be called the reference of the function runtime environment or the context reference of the function). Use the call function, you can specify the object pointed to by this reference when the function is running.
Call (thisObj, arg0, arg1 ....);
ThisObj is the object you want to specify for the function runtime.
Arg0, arg1.... is optional and is the real parameter during function runtime.
Use the call function to inherit the attributes of the parent constructor:
// Parent constructor function SuperType (name) {this. name = name;} // subconstructor function SubType (name, age) {SuperType. call (this, name); // call the parent constructor this. age = age;} var sub = new SubType ("js", 20); console. log (sub. name); // jsconsole. log (sub. age); // 20console. log (sub. hasOwnProperty ("name"); // trueconsole. log (sub. hasOwnProperty ("age"); // true
The first half is implemented in this way. so easy, right.
Inherits the shared attributes of the parent constructor.
Do you still remember the create FUNCTION -- create an object of the specified prototype -- you can specify the implicit reference (_ proto _) of the created object to the object.
Create an implicit reference to the prototype object pointing to the parent constructor:
Var obj = Object. create (SuperType. prototype );
What is this ?!
Isn't that the prototype object of the sub-constructor we want !!
// Parent constructor function SuperType (name) {this. name = name;} SuperType. prototype. sayName = function () {console. log (this. name) ;}// subconstructor function SubType (name, age) {SuperType. call (this, name); // call the parent constructor this. age = age;} SubType. prototype = Object. create (SuperType. prototype); SubType. prototype. sayAge = function () {console. log (this. age);} var sub = new SubType ("js", 20); console. log (sub. name); // jsconsole. log (sub. age); // 20sub. sayName (); // jssub. sayAge (); // 20console. log (sub. constructor); // function SuperType {...}
Ah, how does prototypetype of sub point to SuperType ?!
From the beginning, the sub itself does not have the constructor attribute, and it is found from its prototype;
Its prototype is modified -- "Object. create (SuperType. prototype)", and this Object does not have a constructor. continue to search for its prototype;
That is, SuperType. prototype. Its constructor points to SuperType.
It's okay. Just make a small change.
SubType. prototype = Object. create (SuperType. prototype );
SubType. prototype. constructor = SubType;
Console. log (sub. constructor); // function subType {...}
You only need to add a constructor attribute to SuperType. prototype.
Inheritance is complete ~