Learning JavaScript with me prototype prototype and prototype chain _javascript tips

Source: Internet
Author: User
Tags access properties instance method hasownproperty

Used JavaScript students are sure to prototype thunderclap piercing, but this is what it is a beginner mixed, only know that the function will have a prototype attribute, you can add a function for instance access, the other is not clear, recently read some The JavaScript Advanced program design, finally unveiled its mysterious veil.

Each function has a prototype property that refers to a reference to an object called a prototype object that contains methods and properties shared by the function instance, which means that the function is used as a constructor call (called with the new operator). Newly created objects inherit properties and methods from the prototype object. Unlike the traditional object-oriented language, JavaScript's inheritance mechanism is based on prototypes, not class classes.

1, private variables, functions
in specific said prototype before saying a few related dongdong, can better understand the design intention of prototype. Before you know the JavaScript prototype chain, it's important to understand the scope chain of JavaScript. The function scope of JavaScript, the variables and functions defined within the function, if they do not provide an external interface, then the external will not be accessible, that is, into private and private functions.

function Obj () {
 var a=0;//private variable
 var fn=function () {//Private function

 }
}

So that variable A and function fn cannot be accessed outside of the function object obj, they become private and can only be used within obj, even though instances of the function obj still do not have access to these variables and functions

var o=new Obj ();
Console.log (O.A); Undefined
console.log (O.FN);//undefined

2, static variables, functions

When you define a function, you pass "." The properties and functions that are added to it are still accessible through the object itself, but their instances are not accessible, and such variables and functions are called static variables and static functions, and the students who have used Java and C # are well aware of the static meaning.

function Obj () {}
 obj.a=0//static variable
 obj.fn=function () {//static function 
}

console.log (OBJ.A);//0
Console.log (typeof Obj.fn); function

var o=new Obj ();
Console.log (O.A); Undefined
console.log (typeof O.fn);//undefined

3. Instance variables, functions

In object-oriented programming, in addition to some library functions, we still want to define some attributes and methods at the same time as the object definition, which can be accessed after instantiation, and JavaScript can do so

function Obj () {
 this.a=[];//instance variable
 this.fn=function () {//instance method 
 }
}

console.log (typeof obj.a ); Undefined
console.log (typeof Obj.fn);//undefined

var o=new Obj ();
Console.log (typeof o.a); Object
Console.log (typeof O.fn);//function

This can achieve the above purpose, however

function obj () {
 this.a=[];//instance variable
 this.fn=function () {//instance method

 }
}

var o1=new Obj ();
O1.a.push (1);
o1.fn={};
Console.log (o1.a); [1]
Console.log (typeof O1.fn);//object
var o2=new Obj ();
Console.log (o2.a); []
Console.log (typeof O2.fn);//function

The above code runs exactly as expected, but at the same time it also shows a problem, in the O1 modified A and FN, but not in the O2, because the array and function are objects, is a reference type, which shows that the properties and methods in O1 and O2 properties and methods, although the same name but not a reference, Instead, a copy of the properties and methods defined for the Obj object.

This has no problem with attributes, but it's a big problem for the method, because the method is doing exactly the same function, but there are two copies, if a function object has thousands and instance methods, then each of its instances to maintain a copy of thousands of methods, which is obviously unscientific, this can be swollen do it? Prototype was born. Look at the meaning of the object first:

4, ordinary objects and function objects

In JavaScript, everything is the object! But the objects are also different. is divided into ordinary objects and function objects, object, function is JS self-contained functions object. The following examples illustrate

Function F1 () {};
 var F2 = function () {};
 var F3 = new Function (' str ', ' Console.log (str) ');

 var O3 = new F1 ();
 var O1 = {};
 var O2 =new Object ();

 Console.log (typeof Object); function
 Console.log (typeof function);//function
 Console.log (typeof O1);//object Console.log
 ( typeof O2); Object
 Console.log (typeof O3);//object
 Console.log (typeof F1);//function Console.log (typeof F2
 ); function
 Console.log (typeof F3);//function 

In the above example O1 O2 O3 is a normal object, F1 F2 is a function object. How to distinguish, in fact, is very simple, all the objects created by the new function () are function objects, others are ordinary objects. F1,f2, in the final analysis, is created by means of the new Function (). Function Object is also created by the New function ().

5. Prototype prototype

In JavaScript, objects contain predefined properties whenever an object (function) is defined. One of the properties of a function object is the prototype of the prototype object. Note: Ordinary objects do not have prototype, but have _ proto _ properties.

The prototype object is actually a normal object (except Function.prototype, which is a function object, but it is very special, and he has no prototype attribute (previously said that the function object has the prototype attribute)). Look at the following example:

 Function F1 () {};
 Console.log (F1.prototype)//f1{}
 Console.log (typeof f1.prototype)//object Console.log
 (typeof Function.prototype)//Function, this special
 Console.log (typeof object.prototype)//Object
 Console.log (typeof Function.prototype.prototype)//undefined

From the output of the Console.log (F1.prototype)//f1 {}, it can be seen that F1.prototype is an instance object of F1 (this is the prototype object of F1). When F1 is created, it creates an instance object and assigns it to its prototype, and the basic process is as follows:

 var temp = new F1 ();
 F1. Prototype = temp;

Therefore, the Function.prototype why is the function object is solved, the above mentioned that all new function () produces the object is the function object, therefore Temp1 is the function object.

var temp1 = new Function ();
 Function.prototype = Temp1;

What is the prototype object used for? The primary role is for inheritance. For example:

var person = function (name) {
 this.name = name
};
Person.prototype.getName = function () {return
 this.name;/This points to the prototype object person ==>person.name
}
var XPG = new Person (' Xiaopingguo ');
Xpg.getname (); Xiaopingguo

As you can see from this example, by setting the properties of a function object to Person.prototype, the normal object that comes out of the person instance (in the example: XPG) Inherits this property. Concrete is how to achieve the inheritance, it is necessary to talk about the following prototype chain.

In depth: Whenever you create a new function, you create a prototype property (also an object) for the function based on a specific set of rules, and by default the prototype property (object) obtains a constructor (constructor) property, which is a pointer to the function where the prototype property is located, some around, writing code, and above!

function person () {

}

According to the figure above, you can see that the person object automatically obtains the Prototyp property, and prototype is also an object that automatically obtains a constructor property that points to the person object.

When a constructor is invoked to create an instance, an internal pointer (many browsers with the pointer name _ proto _) is included in the instance to point to the prototype of the constructor, which exists between the instance and the prototype of the constructor, not between the instance and the constructor.

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

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

var person1=new person (' Byron ');
var person2=new person (' Frank ');

The instance of person Person1 contains the Name property and automatically generates an _ proto _ property that points to the prototype of the person who can access the Printname method defined within the prototype, presumably this way:

Write section program test to see prototype properties, methods are able to share

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

Person.prototype.share=[];

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

var person1=new person (' Byron ');
var person2=new person (' Frank ');

Person1.share.push (1);
Person2.share.push (2);
Console.log (Person2.share); [1,2]

Sure In fact, when the code reads a property of an object, it performs a search, the target is a property of the given name, the search begins with the object instance, returns if it is found in the instance, and if not, finds prototype. If it is still not found, continue to recursively prototype the prototype object until it is found, returning an error if recursion to object is still not present. Similarly, if you define a property or function with the same name as prototype in the instance, the prototype property or function is overwritten. --This is the prototype chain of JavaScript.

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

Person.prototype.share=[];

var person=new person (' Byron ');
person.share=0;

Console.log (Person.share); 0; not in the prototype []

6. Prototype chain

JS in the creation of objects (whether ordinary objects or function objects), there is a built-in attribute called _ proto _, used to point to the object of the creation of its prototype object prototype. In the example above

Copy Code code as follows:
Console.log (xpg.__ proto __ = = = Person.prototype)//true

Similarly, the Person.prototype object also has the _ proto _ property, which points to the prototype of the function object that created it

Copy Code code as follows:
Console.log (person.prototype.__ proto __=== Object.prototype)//true

Continue, Object.prototype object also has _ proto _ property, but it is special, null

Copy Code code as follows:
Console.log (object.prototype.__ Proto __)//null

This is a chain of _ proto _ strung up until Object.prototype._ proto _ is called a prototype chain. The following figure:

Attribute lookup in prototype chain:
When looking up an object's properties, JavaScript traverses the prototype chain up until it finds the property of the given name, until the lookup reaches the top of the prototype chain-that is, object.prototype-but still does not find the specified attribute, it returns Undefined, let's look at an example:

 function foo () {
 This.add = function (x, y) {return
 x + y;
 }
}

Foo.prototype.add = function (x, y) {return
 x + y + N
}

Object.prototype.subtract = function (x, y) {return
 xy;
}

var f = new Foo ();
Alert (F.add (1, 2)); The result is 3, rather than
alert (f.subtract (1, 2));//The result is 1.

Run through code, we found that subtract is installing what we call upward lookup to get results, but the add way is a little different, which is what I want to emphasize is that attributes find their attributes first, if no more prototypes, no more, go up, has been inserted into the prototype of object, so at some level, efficiency is also a problem when traversing a property in a for-in statement.

One more thing we need to be aware of is that we can assign any type of object to the prototype, but not the value of the atomic type, for example, the following code is invalid:

function Foo () {}
foo.prototype = 1;//invalid

7. Differences between constructors, instances, and prototype objects

An instance is created from a constructor function. The instance is created with the constructor attribute (pointing to the constructor) and the proto attribute (pointing to the prototype object).

There is a prototype property in the constructor, which is a pointer to its prototype object.

There is also a pointer (constructor property) within the prototype object pointing to the constructor: Person.prototype.constructor = person;

Instances can access properties and methods defined on a prototype object.

Here Person1 and Person2 are examples, and prototype is their archetypal object.

One more chestnut:

<script type= "Text/javascript" >
 function Animal (name)//accumulating constructor
 {
 this.name = name;//Setting object Properties
 }

 Animal.prototype.behavior = function ()///Prototype Add behavior method
 to the base class constructor { 
 alert ("This is a" +this.name);
 }

 var Dog = new Animal ("Dog");//Create Dog object
 var Cat = new Animal ("cat");//Create Cat Object

 dog.behavior ();// Call behavior Method Cat.behavior () directly through the Dog object,
 //output "This is a Cat

 " alert (dog.behavior==cat.behavior);//output true;
</script>

8, the use of the prototype

prototype use mode 1:
Before using prototypes, we need to make small changes to the code:

 var Calculator = function (decimaldigits, tax) {
 this.decimaldigits = decimaldigits;
 This.tax = tax;
 };

The prototype of the Calculator object is then set by assigning the object literal to the prototype property of the Calculator object.

 Calculator.prototype = {
  add:function (x, y) {return
  x + y;
  },

  subtract:function (x, y) {return
  x -y;
  }
 ;
 Alert ((New Calculator ()). Add (1, 3));

We can then call the Add method to compute the result after the new Calculator object.

prototype use mode 2:
The second way is to assign a value by using an expression that is immediately executed by the function when the prototype is assigned, that is, the following format:

Copy Code code as follows:
Calculator.prototype = function () {} ();

Its benefits are already known in the previous item, that is, can encapsulate private function, through the form of return to expose a simple use of the name, to achieve public/private effect, the modified code is as follows:

Calculator.prototype = function () {
 add = function (x, y) {return
  x + y;
 },

 subtract = function (x, y) { return
  x-y;
 }
 return {
  add:add,
  subtract:subtract
 }
} ();

Alert ((New Calculator ()). Add (11, 3));

In the same way, we can call the Add method to compute the result after the new Calculator object.

Step-by-Step statement:
When using the prototype, one of the limitations is to set the prototype object at once, and let's say how to set each property of the prototype.

var basecalculator = function () {
 //) declares a decimal number for each instance
 this.decimaldigits = 2;
Use prototypes to extend

BaseCalculator.prototype.add = function (x, y) {return
 x + y;
}

to Basecalculator; BaseCalculator.prototype.subtract = function (x, y) {return x-
 y;
};

Declares a Basecalculator object that initializes an attribute decimaldigits of a decimal number and then sets 2 functions through the prototype property, add (X,y) and subtract (x,y), respectively. Of course you can also use any of the 2 ways mentioned earlier, our main goal is to see how to set the Basecalculator object to the real calculator prototype.

var basecalculator = function () {
 this.decimaldigits = 2;
};

Basecalculator.prototype = {
 add:function (x, y) {return
 x + y;
 },
 subtract:function (x, y) {
 return X-y;
 }
;

Rewrite prototype:

In the use of Third-party JS class libraries, often sometimes they define the prototype method is not to meet our needs, but also inseparable from this class library, so this time we need to rewrite their prototype of one or more attributes or function, We can do this by continuing to declare the same add code in the form of overriding the Add function before overwriting the code as follows:

Overlay the previous Calculator Add () function 
Calculator.prototype.add = function (x, y) {return
 x + y + this.tax;
};

var calc = new Calculator ();
Alert (Calc.add (1, 1));

In this way, we can calculate the result is more than the original tax value, but one thing to note: that the rewrite code needs to put in the end, so as to overwrite the previous code.

9. hasOwnProperty function

hasOwnProperty is a Object.prototype method, and it's a good thing to judge whether an object contains custom attributes rather than attributes on the prototype chain, because hasOwnProperty is JavaScript The only function that handles attributes but does not look for a prototype chain.

Modify Object.prototype
Object.prototype.bar = 1; 
var foo = {goo:undefined};

Foo.bar; 1
' bar ' in Foo;//True

foo.hasownproperty (' Bar ');//False
Foo.hasownproperty (' goo ');//True

Only hasOwnProperty can give the correct and expected results, which is useful when traversing the properties of an object. There is no other way to exclude attributes from the prototype chain, rather than to define the properties on the object itself.

But there is a disgusting place: JavaScript does not protect hasOwnProperty from being illegally occupied, so if an object happens to have this attribute, you need to use an external hasownproperty function to get the correct result.

var foo = {
 hasownproperty:function () {return
 false;
 },
 bar: ' Here is Dragons '
};

Foo.hasownproperty (' Bar '); Always returns false

//using the hasOwnProperty of the {} object and setting it up to Foo
{}.hasownproperty.call (foo, ' Bar ');//True

hasOwnProperty is the only available method when checking for the existence of a property on an object. At the same time, when traversing an object using a for-in loop, the recommendation always uses the hasOwnProperty method, which avoids the interference caused by the extension of the prototype object, let's take a look at the example:

Modify Object.prototype
Object.prototype.bar = 1;

var foo = {Moo:2};
for (var i in foo) {
 console.log (i);//Output two properties: Bar and Moo
}

We can't change the behavior of the for in statement, so the only way to filter the results is to use the hasOwnProperty method, as follows:

The foo variable is for
(var i in foo) {
 if (Foo.hasownproperty (i)) {
 console.log (i);//moo
 }
}

This version of the code is the only correct way to spell it. Since we used hasownproperty, we only output moo this time. If you do not use hasOwnProperty, this code may have an error when the native object prototype (such as Object.prototype) is extended.

Summary: Recommend using hasOwnProperty, do not make any assumptions about the environment in which the code is run, and do not assume that the native object has been extended

10, expand

_ Ptoto _ Properties

_ Ptoto _ Property (ie browser does not support) is a pointer to a prototype object, its role is to point to the stereotype property constructor, through these two properties, you can access the properties and methods in the prototype.

Object instances in JavaScript are essentially composed of a series of properties, in which there is an internal invisible special Property--_ Proto _, the value of which points to the prototype of the object instance, and an object instance has only one prototype.

function Box () {//uppercase, representing the constructor
 Box.prototype.name = "TRIGKIT4";//prototype attribute
 Box.prototype.age = "n";
 Box.prototype.run = function ()//prototype method
 {return 
 this.name + this.age + ' studying ';
 }
}

var box1 = new Box ();
var box2 = new Box ();
alert (box1.constructor);//construct property, you can get the constructor itself,
   //function is positioned by the prototype pointer, and then get the constructor itself

_ Proto _ Property and prototype property of the difference

Prototype is a proprietary attribute in a prototype object.
_ proto _ is an implicit property of ordinary objects, in new time, will point to the object prototype;
_ Ptoto _ is actually an attribute of an entity object, and prototype is a property of the constructor. _ Ptoto _ can only be used in the study or debugging environment.

The execution process of the prototype pattern

1. Find the property or method in the constructor instance first, and if so, return immediately.
2. If an instance of the constructor is not, go to its prototype object and, if so, return immediately

of the prototype object

function Box () {//uppercase, representing the constructor
 Box.prototype.name = "TRIGKIT4";//prototype attribute
 Box.prototype.age = "n";
 Box.prototype.run = function ()//prototype method
 {return 
 this.name + this.age + ' studying ';
 }
}

var box1 = new Box ();
alert (box1.name);//trigkit4, the value in the prototype
box1.name = "Lee";
alert (box1.name);//lee, on the principle of

var box2 = new Box ();
alert (box2.name);//trigkit4, the value of the prototype, has not been box1 modified

of the constructor

function Box () {   
 this.name = "Bill";
}

Box.prototype.name = "TRIGKIT4";//prototype attribute
Box.prototype.age = "n";
Box.prototype.run = function ()//prototype method
{return 
 this.name + this.age + ' studying ';
}

var box1 = new Box ();
alert (box1.name);//bill, the value in the prototype
box1.name = "Lee";
alert (box1.name);//lee, in principle.

In a comprehensive way, tidy up:

function person () {};

Person.prototype.name = "TRIGKIT4";
Person.prototype.say = function () {
 alert ("Hi");
}

var p1 = new Person ();//prototype is the prototype object of P1 and P2
var p2 = new Person ();//p2 is an instantiated object with a __proto__ attribute inside it pointing to the person's prototype

Console.log (P1.prototype);//undefined, this property is an object that cannot be accessed
console.log (person.prototype);//person
Console.log (Person.prototype.constructor)//The prototype object also has a pointer (constructor attribute) pointing to the constructor
Console.log (p1.__proto__); /This property is a pointer to the prototype prototype object
P1.say ()//instance can access to the properties and methods defined on the prototype object

    • constructor. prototype = Prototype Object
    • Prototype object. constructor = Constructor (template)

-Prototype object. isPrototypeOf (Instance object) to determine if the prototype of an instance object is not the current object.

The above is the entire content of this article, I hope to help you learn.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.