JavaScript: Classes and Prototypes

"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.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值