JavaScript: Classes and Prototypes

來源:互聯網
上載者:User

"Prototypal inheritance" is a key feature of JavaScript.

What's prototype?

Every JavaScript object has a second JavaScript object(or null, but this is rare.) associated with it. This second object is known as a prototype, and the first object inherits properties from the prototype.

How to designate prototype for one object?
All objects created by ojbect literals (as below shown) have the same prototype object, and we can refer to this prototype object in JavaScript code as Object.prototype. 
var point = {x:0, y:0};

Objects created using the new keyword and a construtor invocation use the value of the prototype property of the constructor function as their prototype.
So the object created by new Object() inherits from Object.prototype just as the object created by {} does. Similarly, the object created by new Array() uses Array.prototype as its prototype, and the object created by new Date() uses Date.prototype as its prototype.

objects created with Object.create() use the first argument to that function(which may be null)as their prototype.

How to inherit?
Object.prototype is one of the rare objects that has no prototype:it does not inherit any properties. Other prototype objects are normal objects that do have a prototype.
All of the built-in constructors(and most user-defined constructors)have a prototype that inherits from Object.prototype. For example, Date.prototype inherits properties from Object.prototype, so a Date object created by new Date() inherits properties from
both Date.prototype and Object.prototype. This linked series of prototype objectsis known as a prototype chain.

JaveScript has the ability to create a new object with an arbitrary prototype. That's to say the ability to create an "heir" for any object.

How to query the prototype of an object?
Every object has associated prototype, class, and extensible attributes.
In ECMAScript 5, you can query the prototype of any object by passing that object to Object.getPrototypeOf(). In ECMAScript 3, there is other workarround.


The connection between prototypes and constructors.

objects created with Object.create() use the first argument to that function(which may be null)as their prototype.

Example: A Range class using a constructor.

//This is a constructor function that initializes new Range objects.
//Note that it does not create or return the object. It just initializes this.
function Range(from, to) {
    //Store the start and end points (state) of this new range object.
    //There are noninherited properties that are unique to this objects.
    this.from = from;
    this.to = to;
}

//All Range objects inherit from this object.
//Note that the property name must be "prototype" for this to work.
//In fact, every function automatically (by default) has a prototype property. 
//The value is an object that has a single constructor property. The value of the contructor property is the function object. 
Range.prototype = {
    constructor: Range, //Explicitly set the constructor back-reference
    includes: function(x) {return this.from <= x && x <= this.to;},
    foreach: function(f) {
        for(var x = Math.ceil(this.from); x <= this.to; x++)
            f(x);
    },
    toString: function() {
        return "("+this.from+"..."+this.to+")";
    }
};

The above code overwrites the predefined Range.prototype object with an object of its own.

Another common technique is to use the predefined prototype object with its constructor property, and add methods to it one at a time.
Range.prototype.include = ...;
Range.prototype.foreach = ...;
Range.prototype.toString = ...;

//Here are example uses of a range object
var r = new Range(1,3);
r.include(2);
r.foreach(console.log);
console.log(r);
-----------------------------------------------
The new object is automatically created before the constructor is called, and it is accessible as the this value. The Range() constructor merely has to initialize this.

Inheritance.
Suppose you assign to the property x of the object o. If o already has an own(noninherited) property named x, then the assignment simply changes the value of this existing property. Otherwise, the assignment creates a new property named x on the object o. If
o previously inherithed the property x, that inherited property is now hidden by the newly created own property with the same name.

The inheritance occurs when querying properties but not when setting them is a key feature of JavaScript. This allows us to selectively override inherited properties.

原型串連在更新時是不起作用的。當我們對某個對象做出改變時,不會觸及到該對象的原型。
原型串連只有在檢索值的時候才被用到。如果我們嘗試去擷取對象的某個屬性值,且該對象沒有此屬性名稱,那麼JavaScript會試著在原型對象中擷取屬性值。如果那個原型對象也沒有該屬性,那麼再從它的原型中尋找,依次類推,直到該過程最都到達終點Object.prototype。如果想要的屬性完全不存在於原型鏈中,那麼結果就是undefined值。這個過程稱為委託。

JaveScript's prototype-based inheritance mechanism is dynamic: an object inherits properties from its prototype, even if the properties of the prototype change after the object is created. This means that we can augment JavaScript
classes simply by adding new methods to their prototype objects.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.