JS object-oriented and prototype

Source: Internet
Author: User
Tags hasownproperty

Creating objects

Create an object, and then give the object new properties and methods.

var box = new Object (); Create an Object

Box.name = ' Lee '; Create a Name property and assign a value

Box.age = 100; Create an Age property and assign a value

Box.run = function () {//Create a run () method and return a value

Return this.name + this.age + ' running ... ';

};

Alert (Box.run ()); Values for output properties and methods


The above creates an object and creates properties and methods, and this in the Run () method represents the Box object

Itself. This is the most basic method of JavaScript to create objects, but there is a disadvantage, want to create a similar object, it

Will generate a lot of code.

var box2 = box; Get a quote from box

Box2.name = ' Jack '; Changed the Name property directly

Alert (Box2.run ()); Using Box.run () to find the name also changed

var box2 = new Object ();

Box2.name = ' Jack ';

Box2.age = 200;

Box2.run = function () {

Return this.name + this.age + ' running ... ';

};

Alert (Box2.run ()); This avoids being confused with box, thus maintaining independence

To solve the problem of several similar object declarations, we can use a method called Factory mode, which

is to solve the problem that the instantiated object produces a lot of duplication.

function CreateObject (name, age) {//functions that are instantiated in a centralized format

var obj = new Object ();

Obj.name = name;

Obj.age = age;

Obj.run = function () {

Return this.name + this.age + ' running ... ';

};

return obj;

}

var box1 = CreateObject (' Lee ', 100); First Instance

var box2 = CreateObject (' Jack ', 200); A second instance

Alert (Box1.run ());

Alert (Box2.run ()); Remain independent

Factory mode solves the problem of repeating instantiation, but there is one problem, which is to identify the problem, because there is no

Figure out exactly which object they are.

Alert (typeof Box1); Object

Alert (box1 instanceof Object); True

Constructors (construction methods) can be used in ECMAScript to create specific objects. Type in Object pair

Like.

function Box (name, age) {//constructor mode

THIS.name = name;

This.age = age;

This.run = function () {

Return this.name + this.age + ' running ... ';

};

}

var box1 = new Box (' Lee ', 100); New Box ()

var box2 = new Box (' Jack ', 200);

Alert (Box1.run ());

Alert (box1 instanceof Box); Clearly identified him from the Box

The method of using constructors solves the problem of duplicate instantiation and solves the problem of object recognition, but the problem

Yes, there is no new Object (), why can I instantiate Box (), where does this come from?

Methods that use constructors, and methods that use Factory mode, they differ as follows:

1. The constructor method does not display the creation object (new object ());

2. Assign properties and methods directly to the This object;

3. There is no Renturn statement.

Constructor methods have some specifications:

1. The function name and instantiation construct name are the same and uppercase, (PS: not mandatory, but it helps to distinguish between constructors and

normal function);

2. Create an object from a constructor, you must use the new operator.

Now that you can create an object from a constructor, where does this object come from, where is new object ()

Executed? The following procedures are performed:

1. When the constructor is used and the new constructor (), the new Object () is executed in the background;

2. The scope of the constructor is given to the new object (that is, the object created by new object), and this in the function body

Represents the object that is a new object ().

3. Execute the code within the constructor;

4. Returns the new object (returned directly from the background).

For the use of this, this is actually a reference to the current scope object. If this is the global scope, the

The Table window object, if in the constructor body, represents the object declared by the current constructor.

var box = 2;

alert (This.box); Global, representing window

The only difference between constructors and normal functions is that they are called in different ways. However, the constructor is also a function

Number, it must be called with the new operator, otherwise it is a normal function.

var box = new Box (' Lee ', 100); Constructed mode call

Alert (Box.run ());

Box (' Lee ', 20); Normal mode call, invalid

var o = new Object ();

Box.call (o, ' Jack ', 200)//Object Impersonation Call

Alert (O.run ());

The question of the method (or function) inside the constructor is discussed, first, whether the following two instantiated properties or methods are

such as

var box1 = new Box (' Lee ', 100); Consistent delivery

var box2 = new Box (' Lee ', 100); Ditto

Alert (Box1.name = = Box2.name); True, the value of the property is equal

Alert (Box1.run = = Box2.run); False, the method is actually a reference address

Alert (box1.run () = = Box2.run ()); True, the value of the method is equal because the argument is consistent

The method (or function) in the constructor can be replaced with the new function () method, resulting in the same effect, and more

Prove that they are ultimately judged by the reference address, uniqueness.

function Box (name, age) {//new function () uniqueness

THIS.name = name;

This.age = age;

This.run = new Function ("return this.name + this.age + ' run ... ');

}

We can guarantee the consistency of the reference address by using a method that binds the same function outside the constructor, but this

Law is not necessary, just deepen learning to understand:

function Box (name, age) {

THIS.name = name;

This.age = age;

This.run = run;

}

function run () {//Call through outside to ensure consistent reference address

Return this.name + this.age + ' running ... ';

}

Although the global function run () is used to solve the problem of guaranteeing a consistent reference address, this approach brings

A new problem, the this in the global is the box itself when the object is called, and when it is called as a normal function,

This also represents window.

Prototype

Each function we create has a prototype (prototype) attribute, which is an object whose purpose is to

Contains properties and methods that can be shared by all instances of a particular type. Logically, it can be understood: prototype through

The prototype object of the object that was created by invoking the constructor. The benefits of using prototypes allow all object instances to share the

Contains the properties and methods. That is, instead of defining object information in the constructor, you can directly

Added to the prototype.

function Box () {}//Declare a constructor

Box.prototype.name = ' Lee '; Adding attributes to a prototype

Box.prototype.age = 100;

Box.prototype.run = function () {//Add method in prototype

Return this.name + this.age + ' running ... ';

};

Compare the methods in the prototype to the same address:

var box1 = new Box ();

var box2 = new Box ();

Alert (Box1.run = = Box2.run); True, the reference address of the method remains consistent

We can detect whether a property exists in an instance by using the hasOwnProperty () method, or it can be judged by in

Whether an attribute exists in the instance or prototype. The combination of these two methods allows you to determine whether a property exists in the prototype.

function Isproperty (object, property) {//To determine if an attribute exists in the prototype

Return!object.hasownproperty (property) && (object);

}

var box = new box ();

Alert (Isproperty (box, ' name '))//true, if the prototype has

In order for properties and methods to better reflect the effects of encapsulation, and to reduce unnecessary input, the creation of prototypes can make

In the literal way:

function Box () {};

Box.prototype = {//Use the literal way

Name: ' Lee ', age:100, Run:function () {

Return this.name + this.age + ' running ... ';

}

};

Using constructors to create prototype objects and to create objects using literals is basically the same as using, but there are some areas

No, the literal creation method uses the constructor property not to point to an instance, but to an Object, the constructor creates

In the opposite way.

var box = new box ();

Alert (box instanceof box);

Alert (box instanceof Object);

Alert (box.constructor = = box); Literal way, returns false, otherwise, true

Alert (Box.constructor = = Object); Literal way, returns True, otherwise, false

If you want the constructor of the literal way to point to an instance object, you can do this:

Box.prototype = {

Constructor:box,//direct force pointing can be

};

PS: The literal way why does constructor point to Object? Because of the box.prototype={}, this notation actually

is to create a new object. Each time you create a function, you create it prototype, and the object

Gets the constructor property. So, the new object's constructor rewrite Box's original constructor, so it will

Point to the new object, and the new object does not specify a constructor, then it defaults to object.

The declaration of the prototype is sequential, so the rewritten prototype will cut off the previous prototype.

function Box () {};

Box.prototype = {//prototype has been rewritten

Constructor:box, Name: ' Lee ', age:100, Run:function () {

Return this.name + this.age + ' running ... ';

}

};

Box.prototype = {

Age = 200

};

var box = new box (); In this statement

Alert (Box.run ()); Box is just a prototype of the original statement.

Prototype objects can be used not only in the case of custom objects, but also in ECMAScript built-in reference types

To use this approach, and the built-in reference types themselves use prototypes as well.

alert (Array.prototype.sort); Sort is the prototype method of the Array type

alert (String.prototype.substring); SUBSTRING is the prototype method of String type

String.prototype.addstring = function () {//Add a method to the String type

Return this + ', was added! ‘; This represents the string that is called

};

Alert (' Lee '. addstring ()); Use this method

PS: Although it is particularly convenient to add methods to native built-in reference types, we do not recommend the use of this

Method. Because it can cause naming conflicts, it is not conducive to code maintenance.

Prototype schema creation object also has its own shortcomings, it omitted the constructor parameter initialization of the process, resulting in the lack of

The point is that the initialized values are consistent. And the biggest drawback of the prototype is its greatest advantage, that is sharing.

All properties in the prototype are shared by many instances, and sharing is appropriate for the function, for attributes that contain base values

It's also possible. However, if the property contains a reference type, there are some problems:

function Box () {};

Box.prototype = {

Constructor:box, Name: ' Lee ', age:100, family: [' father ', ' mother ', ' sister '],//Added an array property

Run:function () {

Return this.name + this.age + this.family;

}

};

var box1 = new Box ();

Box1.family.push (' elder brother '); Add ' brother ' alert (Box1.run ()) to the instance;

var box2 = new Box ();

Alert (Box2.run ()); The trouble of sharing, also has ' elder brother '

PS: Data sharing causes many developers to abandon the use of prototypes, since each instantiation of the data requires

Keep your own features, but not share them.

To solve the problem of constructing parameters and sharing, you can combine constructor + prototype mode:

function Box (name, age) {///do not share the use constructor

THIS.name = name;

This.age = age;

This. Family = [' father ', ' mother ', ' sister '];

};

Box.prototype = {//shared use prototype mode

Constructor:box, Run:function () {

Return this.name + this.age + this.family;

}

};

PS: This mixed mode is a good solution to the problem of the sharing of parameters and references. is a good way to create objects.

Prototype mode, regardless of whether you invoke a shared method in the prototype, it initializes the method in the prototype and

When declaring an object, the constructor + prototype part makes people feel weird, preferably by encapsulating constructors and prototypes

Come together. In order to solve this problem, we can use dynamic prototype mode.

function Box (name, age) {//encapsulates all information into the function body

THIS.name = name;

This.age = age;

if (typeof this.run! = ' function ') {//Initialize only on first call

Box.prototype.run = function () {

Return this.name + this.age + ' running ... ';

};

}

}

var box = new Box (' Lee ', 100);

Alert (Box.run ());

When the constructor is called for the first time, the run () method discovers that it does not exist and initializes the prototype. When the second call is

is not initialized, and the new object is created the second time, the prototype is no longer initialized. This and has been encapsulated, but also to achieve

The prototype method is shared, and the attributes remain independent.

if (typeof this.run! = ' function ') {

Alert (' first-time initialization '); For testing

Box.prototype.run = function () {

Return this.name + this.age + ' running ... ';

};

}

var box = new Box (' Lee ', 100); Create an object for the first time

Alert (Box.run ()); First time call

Alert (Box.run ()); Second call

var box2 = new Box (' Jack ', 200); Create object for the second time

Alert (Box2.run ());

Alert (Box2.run ());

PS: Using dynamic prototype mode, be aware that you can no longer use the literal way to rewrite the prototype, because it will

Cut off the connection between the instance and the new prototype.

The above explains the methods of object creation in various ways, if these methods do not meet the requirements, you can use an open

The initial pattern: the parasitic constructor.

function Box (name, age) {

var obj = new Object ();

Obj.name = name;

Obj.age = age;

Obj.run = function () {

Return this.name + this.age + ' running ... ';

};

return obj;

}

The parasitic constructor, in fact, is the Factory mode + constructor mode. This mode is more generic, but not sure

, it is not recommended to use this mode when the previously mentioned pattern is available.

Under what circumstances is it appropriate to use a parasitic constructor? Suppose you want to create a reference class with an extra method

Type. Since the previous description does not recommend direct String.prototype.addstring, it can be added by means of parasitic constructs.

function MyString (string) {

var str = new string (string);

str.addstring = function () {

Return this + ', was added! ‘;

};

return str;

}

var box = new MyString (' Lee '); Much more tedious than adding directly to the reference prototype

Alert (box.addstring ());

In some secure environments, such as prohibit the use of this and new, this is the constructor that does not use this,

The new here is to not use new when instantiating the constructor externally. This method of creation is called a secure constructor.

function Box (name, age) {

var obj = new Object ();

Obj.run = function () {

Return name + Age + ' running ... '; Direct printing of parameters can be

};

return obj;

}

var box = box (' Lee ', 100); Calling functions Directly

Alert (Box.run ());

PS: The safe constructor is similar to parasitic.



Inherited

Inheritance is a relatively central concept in object-oriented. Other Orthodox object-oriented languages can be implemented in two ways

Commitment: One is an interface implementation, and the other is inheritance. ECMAScript only supports inheritance, does not support interface implementations, and implements

The way you inherit depends on the prototype chain.

function Box () {//box construction

this.name = ' Lee ';

}

function Desk () {//desk construct

This.age = 100;

}

Desk.prototype = new Box (); Desc inherits the Box, through the prototype, forming the chain

var desk = new Desk ();

alert (desk.age);

alert (desk.name); Get the Inherited property

function Table () {//table construct

This.level = ' AAAAA ';

}

Table.prototype = new Desk (); Continuation of the prototype chain inheritance

var table = new Table ();

alert (table.name); Inherited Box and Desk.

In JavaScript, the inherited function is called a supertype (parent, base class, other language), inherited

A function is called a subtype (subclass, derived class). Inheritance also has previous problems, such as literal rewriting of prototypes that break relationships and make

A prototype of a reference type is used, and the subtype cannot pass parameters to the super-type.

In order to solve the problem of reference sharing and super type not being able to pass parameters, we use a technique called borrowing constructors, or

To address both of these issues by becoming an object masquerading (forgery, classic inheritance)

function Box (age) {

THIS.name = [' Lee ', ' Jack ', ' Hello ']

This.age = age;

}

function Desk (age) {

Box.call (this, age); Object impersonating, giving the super type a parameter

}

var desk = new Desk (200);

alert (desk.age);

alert (desk.name);

Desk.name.push (' AAA '); New data added, only for desk

alert (desk.name);

Although the borrowing of constructors solves just two kinds of problems, there is no prototype, and reuse is impossible to talk about. Therefore, we need to

To prototype chains + borrow a constructor's schema, this pattern becomes a composite inheritance.

function Box (age) {

THIS.name = [' Lee ', ' Jack ', ' Hello ']

This.age = age;

}

Box.prototype.run = function () {

return this.name + this.age;

};

function Desk (age) {

Box.call (this, age); Object Impersonation

}

Desk.prototype = new Box (); Prototype chain inheritance

var desk = new Desk (100);

Alert (Desk.run ());

There is also an inheritance pattern called: Prototype inheritance, which uses prototypes and creates new objects based on existing objects.

You do not have to create custom types as well.

function obj (o) {//pass a literal function

function F () {}//Create a constructor

F.prototype = O; Assigning a literal function to a prototype of a constructor

return new F (); Finally returns the instantiated constructor

}

var box = {//literal object

Name: ' Lee ', arr: [' elder brother ', ' sister ', ' sister ']

};

var box1 = obj (box); Passed

alert (box1.name);

Box1.name = ' Jack ';

alert (box1.name);

alert (Box1.arr);

Box1.arr.push (' parents ');

alert (Box1.arr);

var box2 = obj (box); Passed

alert (box2.name);

alert (Box2.arr); The reference type shares the

Parasitic inheritance combines the prototype + factory model to encapsulate the process of creating objects.

function Create (o) {//Encapsulation creation process

var f= obj (o);

F.run = function () {

return This.arr; Similarly, references are shared

};

return F;

}

Combined inheritance is the most commonly used inheritance mode for JavaScript, but there is also a small problem with combined inheritance, which is the super-

The type is called two times during use: once when a subtype is created, and another in the subtype constructor

Internal.

function Box (name) {

THIS.name = name;

This.arr = [' elder brother ', ' sister ', ' parents '];

}

Box.prototype.run = function () {

return this.name;

};

function Desk (name, age) {

Box.call (this, name); Call Box for the second time

This.age = age;

}

Desk.prototype = new Box (); Call Box for the first time

The above code is the previous combination of inheritance, then the parasitic combination inheritance, resolved the problem of two calls.

function obj (o) {

function F () {}

F.prototype = O;

return new F ();

}

function Create (box, desk) {

var f = obj (Box.prototype);

F.constructor = desk;

Desk.prototype = f;

}

function Box (name) {

THIS.name = name;

This.arr = [' elder brother ', ' sister ', ' parents '];

}

Box.prototype.run = function () {

return this.name;

};

function Desk (name, age) {

Box.call (this, name);

This.age = age;

}

Inprototype (Box, Desk); Inheritance is achieved through this

var desk = new Desk (' Lee ', 100);

Desk.arr.push (' elder sister ');

alert (Desk.arr);

Alert (Desk.run ()); Only methods are shared

var desk2 = new Desk (' Jack ', 200);

alert (Desk2.arr); Reference Problem Resolution


JS Object-oriented and prototype

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.