Reading time "JavaScript Advanced Programming" II: Object-oriented

Source: Internet
Author: User
Tags hasownproperty

Then the last progress, began to look at the 6th chapter.

The 6th Chapter object-oriented programming

  Understanding objects

The simplest way to create a custom object is to create an instance of an object and then add properties and methods to it.

var person = new Object ();p erson.name = ' xxx ';p Erson.say = function () {alert (this.name);} Equivalent to the object literal var person = {name: ' xxx ', say:function () {alert (this.name);}}

There are two types of properties in ECMAScript: Data Property accessor Properties

The Data property contains the location of a data value that can be read and written in this location. To modify the properties default attribute, you must use the object.defineproperty() method defined by ECMAScript 5. This method receives 3 parameters: the object where the property resides, the name of the property, and a Descriptor object (configurable, enumerable, writable, value).

var person = {};object.defineproperty (person, "name", {    writable:false,    value: "Nicholas"}); alert ( Person.name); Nicholasperson.name = "Michael"; alert (person.name); Nicholas//object.defineproperty (person, "name", {    configurable:false,    value: "Nicholas"});

The accessor property does not contain a data value and contains a pair of getter setters. Accessor properties cannot be defined directly and must be defined using DefineProperty ().

Properties of the Read attribute

The Getownpropertydescriptor () method in ECMAScript 5 can get the descriptor of the property. This method receives 2 parameters: the object where the property resides, and the name of the property to read the descriptor.

  Creating objects 

Although the object constructor or object literal can create a single object, there are drawbacks: creating many objects with the same interface creates a lot of duplicate code.

1. Factory mode 

Factory mode function Createperson (name, age, Job) {    var o = new Object ();    O.name = name;    O.age = age;    O.job = job;    O.sayname = function () {        alert (this.name);    };        return o;} var person1 = Createperson ("Nicholas", "Software Engineer"), var person2 = Createperson ("Greg", "Doctor");p Erson1. Sayname ();   "Nicholas" Person2.sayname ();   "Greg"

2. constructor Mode

constructor mode function person (name, age, Job) {    this.name = name;    This.age = age;    This.job = job;    This.sayname = function () {        alert (this.name);    };    } var person1 = new Person ("Nicholas", "Software Engineer"), var person2 = new Person ("Greg", "Doctor");p Erson1.sayna Me ();   "Nicholas" Person2.sayname ();   "Greg"

    Constructors should start with a capital letter, and non-constructors should start with a lowercase letter.

To create a new instance, you must use the new operator.

General Experience 4 steps:

1). Create a new object

2). Assigns the scope of the constructor to the new object (this points to the new object)

3). Execute the code in the constructor (add properties, methods to the new object)

4). Returns the new object

The new object created has a constructor (constructor) property that points to the constructor for that new instance.

    The instanceof operator is used to detect object types.

Constructoralert (Person1.constructor = = person);  Truealert (Person2.constructor = = person);  True//instanceofalert (Person1 instanceof Object);  Truealert (person1 instanceof person);  Truealert (Person2 instanceof Object);  Truealert (person2 instanceof person);  True

Constructors are also normal functions, and any function that is called by the new operator can be used as a constructor.

The new operator calls Var person as a constructor = new person ("Nicholas", "Software Engineer");p erson.sayname ();   "Nicholas"//as normal function call person ("Greg", "Doctor");  Adds to Windowwindow.sayname ();   

3. prototype mode

    Each newly created function has a prototype (prototype) attribute, which is a pointer to an object that is used to contain properties and methods that can be shared by all instances of a particular type.

Prototype mode function person () {}person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function () {    alert (this.name);}; var person1 = new Person ();p erson1.sayname ();   "Nicholas" var person2 = new Person ();p erson2.sayname ();   "Nicholas" alert (person1.sayname = = person2.sayname);  True

Understanding prototype Objects

    Whenever a new function is created, a prototype property is created for the function based on a specific set of rules, which points to the prototype object of the function. By default, all prototype objects automatically get a constructor property that contains a pointer to the function where the prototype property is located.

When a custom constructor is created, its prototype object only obtains the constructor property by default, and the other method inherits from object. when the constructor is called to create a new instance, the inside of the instance contains a pointer (internal property [[prototype]]) that points to the constructor's prototype object. (in some browsers this property is __proto__ )

      

Instance of person: Person1, Person2, these 2 instances all contain an internal property (in some browsers: __proto__), which points to person.prototype. (In other words, this internal property is not directly related to the constructor)

   You can use the isprototypeof() method to determine whether this relationship exists between objects (instance internal properties [[[prototype]] points to constructor prototypes)

    

Alert (Person.prototype.isPrototypeOf (Person1));  Truealert (Person.prototype.isPrototypeOf (Person2));  True

Use the hasOwnProperty () method to detect whether a property exists in an instance or exists in a prototype.

Detection attribute function person () {}      Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function () {    alert (this.name);}; var person1 = new Person (), var person2 = new Person (), Alert (Person1.hasownproperty ("name"));  Falsealert ("name" in Person1);  Trueperson1.name = "Greg"; alert (person1.name);   "Greg" –from Instancealert (Person1.hasownproperty ("name"));  Truealert ("name" in Person1);  Truealert (person2.name);   "Nicholas" –from Prototypealert (Person2.hasownproperty ("name"));  Falsealert ("name" in Person2);  Truedelete Person1.name;alert (person1.name);   "Nicholas"-From the Prototypealert (Person1.hasownproperty ("name"));  Falsealert ("name" in Person1);  True

Judging prototype Properties function Hasprototypeproperty (object, name) {    return!object.hasownproperty (name) && (name in object);} var person = new person ();        Alert (Hasprototypeproperty (person, "name"));  Trueperson.name = "Greg"; alert (Hasprototypeproperty (person, "name"));  

When using the for-in loop, the return is all the enumerable properties that can be accessed through the object, including the properties of the instance, the properties of the prototype. To get all the enumerable instance properties of an object, you can use the Object.keys () method in ECMAScript 5. This method receives an object that returns an array of strings that contain enumerable properties.

Property enumeration Function Person () {}person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function () {    alert (this.name);}; var keys = Object.keys (Person.prototype); alert (keys);   "Name,age,job,sayname" var person1 = new Person ();p erson1.name = ' xxx ';p erson1.age = 50;var Person1keys = Object.keys (PE Rson1); alert (Person1keys);  

This can be extended:

if (! object.create) {object.create = function (o) {function F () {}f.prototype = O;return new F ();}} if (! Object.keys) {Object.keys = function (o) {var k = [], p;for (P in O) {if (Object.prototype.hasOwnProperty.call (o,p)) {K.push ( p);}} return k;}}

Simpler prototype Syntax

function person () {}      Person.prototype = {    name: "Nicholas",    age:29,    job: "Software Engineer",    Sayname:function () {        alert (this.name);    }}; var friend = new person (); alert (friend instanceof Object);  Truealert (friend instanceof person);  Truealert (Friend.constructor = = person);  Falsealert (Friend.constructor = = Object);  True

    The dynamic nature of prototypes

    Since the process of finding values in a prototype is a search, any changes made to the prototype object can be immediately reflected from the instance, immediately after the instance is created and the prototype is changed.

The dynamics of the prototype function person () {}    Person.prototype = {    Constructor:person,    name: "Nicholas",    age:29,    job: "Software Engineer",    sayname:function () {        alert (this.name);    }}; var friend = new person (); Person.prototype.sayHi = function () {    alert ("HI");}; Friend.sayhi ();  

If you override the entire prototype object, the pointer in the instance is severed (the call constructor adds a pointer to the original prototype [[prototype]]) to the original prototype.

Rewrite the prototype function person () {}var friend = new person ();      Person.prototype = {    Constructor:person,    name: "Nicholas",    age:29,    job: "Software Engineer", C16/>sayname:function () {        alert (this.name);    }}; Friend.sayname ();   Error

 

    Prototypes of native objects

    The importance of prototype patterns is not only in creating custom types, but in all native reference types, but also in prototype mode. All native reference types (Object, Array, String ...) Methods are defined on the prototype of their constructors.

Native object of the prototype alert (typeof Array.prototype.sort);         "Function" alert (typeof String.prototype.substring);   "function" String.prototype.startsWith = function (text) {    return this.indexof (text) = = 0;}; var msg = "Hello world!"; Alert (Msg.startswith ("Hello"));  True

Problem with prototype mode

     The prototype pattern omits the process of passing initialization parameters to the constructor, causing all instances to get the same property value by default. all the attributes in the prototype are shared by many instances, and the instances generally have their own attributes.  

Prototype problem function person () {}person.prototype = {    Constructor:person,    name: "Nicholas",    age:29,    job: " Software Engineer ",    friends: [" Shelby "," Court "],    sayname:function () {        alert (this.name);    }}; var person1 = new Person (), var person2 = new Person ();p Erson1.friends.push ("Van"); alert (person1.friends)    ; "Shelby,court,van" alert (person2.friends);    "Shelby,court,van" alert (person1.friends = = = Person2.friends);  True

4. combining the constructor pattern with the prototype mode

  The most common way to create custom types is by combining the constructor pattern with the prototype pattern. constructors are used to define instance properties, and prototype patterns are used to define methods and shared properties. such a combination, each instance has its own instance of the attribute, but also share the reference to the method, the maximum memory savings.

Combination constructor pattern and prototype mode function person (name, age, Job) {    this.name = name;    This.age = age;    This.job = job;    This.friends = ["Shelby", "Court"];} Person.prototype = {    Constructor:person,    sayname:function () {        alert (this.name);    }}; var person1 = new Person ("Nicholas", "Software Engineer"), var person2 = new Person ("Greg", "Doctor");p Erson1.frien Ds.push ("Van"); alert (person1.friends);    "Shelby,court,van" alert (person2.friends);    "Shelby,court" alert (person1.friends = = = Person2.friends);  Falsealert (Person1.sayname = = = Person2.sayname);  True

This combination of constructors and prototypes is currently the most widely accepted method of creating custom types. This is a default pattern that is used from a defined type.

5. Dynamic Prototyping mode

     The dynamic prototype pattern encapsulates all information in a constructor, while preserving the advantages of using constructors and prototypes while initializing prototypes in constructors.

Dynamic prototype mode function person (name, age, Job) {//attribute this.name = Name;this.age = Age;this.job = job;//method if (typeof this.sayname! = "function") {    Person.prototype.sayName = function () {        alert (this.name);}    ;}} var friend = new Person ("Nicholas", "Software Engineer"); Friend.sayname ();

Using the dynamic prototype pattern, you cannot rewrite the prototype using object literals.

6. Parasitic constructor mode

   7. Secure Constructor Mode

  Inherited   

Many OO languages support two types of inheritance: interface inheritance, implementation inheritance. Interface inheritance inherits only the method signature, and the implementation inherits the actual method. Interface inheritance cannot be implemented in ECMAScript because the function is not signed. So ECMAScript only supports the implementation of inheritance, the implementation of inheritance is mainly based on the prototype chain to achieve.

1. prototype chain

The basic idea of a prototype chain is to have a reference type inherit the properties and methods of another reference type using the prototype .

  Constructor, prototype, instance relationship: Each constructor has a prototype object, and the prototype object contains a pointer to the constructor ( constructor ), and the instance packages an internal pointer to the prototype object ( [[prototype]] __ Proto__ ).

If you make the prototype object equal to an instance of another type, the prototype object will contain a pointer to another prototype, and another prototype contains a pointer to another constructor. If another prototype is another type of example, this relationship is still established, such a level of progression, constitutes an example and prototype chain. This is the basic concept of the so-called prototype chain.

Prototype chain//supertypefunction supertype () {    this.property = true;} SuperType.prototype.getSuperValue = function () {    return this.property;};/ /subtypefunction subtype () {    this.subproperty = false;} inherited the Supertypesubtype.prototype = new Supertype (); SubType.prototype.getSubValue = function () {    return this.subproperty;};/ /instancevar instance = new subtype (); alert (Instance.getsupervalue ());   true//the relationship between the prototype and the instance 1alert (instance instanceof Object);      Truealert (instance instanceof supertype);   Truealert (instance instanceof subtype);     true//the relationship between prototype and instance 2alert (Object.prototype.isPrototypeOf (instance));    Truealert (SuperType.prototype.isPrototypeOf (instance)); Truealert (SubType.prototype.isPrototypeOf (instance));   True

Prototype chain diagram

All reference types inherit Object, and this inheritance is implemented through the prototype chain.

  

Subtype Inherits Supertype, Supertype inherits the object. When Instance.tostring () is called, it is actually called the ToString () method saved in Object.prototype.

Prudent method of definition

Subtypes sometimes need to rewrite a method in a superclass, or add a method that does not exist in the superclass, and the code that adds the method to the prototype chain must be placed after the statement that replaced the prototype.

Problems with the prototype chain

The problem with the prototype chain is function supertype () {    this.colors = ["Red", "Blue", "green"];} Function subtype () {}subtype.prototype = new supertype (); var Instance1 = new subtype (); Instance1.colors.push ("Black"); alert (instance1.colors);    "Red,blue,green,black" var instance2 = new subtype (); alert (instance2.colors);    "Red,blue,green,black"

The Subertype constructor defines a colors property, subtype inherits an instance of Supertype through the prototype chain, so Subtype.prototype becomes an instance of Supertype and has its own colors property. All subtype instances share this property. Changes to the instance1.colors will also be reflected through instance2.colors.

When you create an instance of a subtype, you cannot pass parameters to a super-type constructor. There is actually no way to pass parameters to a superclass's constructor without affecting all object instances.

2. borrowing Constructors

  3. Combining Inheritance

  4. prototype Inheritance-' modern ' no-Class inheritance mode

function Object (o) {function F () {}f.prototype = O;return new F ();} if (! object.create) {object.create = function (o) {function F () {}f.prototype = O;return new F ();}}

ECMAScript added the Object.create () method to normalize the stereotype inheritance. This method introduces two parameters: an object that is used as a prototype for a new object, and an object that defines additional properties for the new object. In the case of passing in a parameter, the Object.create () and the Object () methods are similar.

5. Parasitic Inheritance

6. Parasitic combined inheritance

function Object (o) {function F () {} f.prototype = O; return new F ();   function Inheritprototype (subtype, supertype) {var prototype = object (Supertype.prototype);               Create Object prototype.constructor = subtype;                 Augment object subtype.prototype = prototype;    Assign Object}function supertype (name) {this.name = name; This.colors = ["Red", "Blue", "green"];} SuperType.prototype.sayName = function () {alert (this.name);};    Function subtype (name, age) {Supertype.call (this, name); This.age = age;} Inheritprototype (subtype, supertype); SubType.prototype.sayAge = function () {alert (this.age);};  var Instance1 = new Subtype ("Nicholas"); Instance1.colors.push ("Black"); alert (instance1.colors);      "Red,blue,green,black" Instance1.sayname ();       "Nicholas"; Instance1.sayage ();  29var Instance2 = new Subtype ("Greg"); alert (instance2.colors);     "Red,blue,green" Instance2.sayname ();   "Greg"; Instance2.sayage (); 27

In this example, it only invokes the Supertype constructor once, avoiding the creation of unnecessary properties on Subtype.prototype. The prototype chain also remains intact, and the instanceof and isprototypeof () are used normally. It is generally believed that parasitic combined inheritance is the most ideal way to inherit the reference type.

  The 6th chapter mainly introduces the object-oriented related knowledge. Create objects: Factory mode, constructor mode, prototype mode, combined use of constructor mode and prototype mode ... Implementation of inheritance: prototype, parasitic, parasitic combined ... This chapter requires a profound The solution, is the JS can go farther of the important foundation.

Reading time "JavaScript Advanced Programming" II: Object-oriented

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.