JavaScript所有对象都继承自Object类。
属性
constructor属性 从javascript1.1开始,每个对象都有这个属性,它指向用来初始化改对象的构造。
<script type="text/javascript"> var testFun = function () { var obj = new Object(); var str = ""; str += "\r\nconstructor : "; str += obj.constructor; str += "\r\ntypeof obj.constructor : "; str += typeof(obj.constructor); alert(str); /** constructor : function Object() { [native code] } //Object内部实现是函数 typeof obj.constructor : function */ } </script>
javascript内部实现了很多函数,如Object,Date都是函数由Function得到的。
prototype属性 对该对象的对象原型的引用。对于所有的类,它默认返回Object对象的一个实例。
<script type="text/javascript"> function testFun () { function foo(a, b, c) { return a * b * c; } var str = ""; str += "foo params length : " + foo.length; str += "\r\ntypeof foo.constructor : " + (typeof foo.constructor); str += "\r\ntypeof foo.call : " + (typeof foo.call); str += "\r\ntypeof foo.apply : " + (typeof foo.apply); str += "\r\ntypeof foo.prototype : " + (typeof foo.prototype); str += "\r\ntypeof Object.prototype : " + (typeof Object.prototype); alert(str); /** foo params length : 3 typeof foo.constructor : function typeof foo.call : function typeof foo.apply : function typeof foo.prototype : object typeof Object.prototype : object */ } </script>
JavaScript中的每个对象都会包含另一个对象的引用,这个引用对应的对象被称为前面那个对象的原型(prototype)。
比如A对象包含了对B对象的引用(B0),B0对应的对象B称为对象A的原型。
由于原型本身也是一个对象,因此它也会包含对它的原型的引用。这样就形成了一条对象链,这条链终止于内建的Object类的原型(Object.prototype),然而却不能像访问普通属性那样直接访问某个对象的原型。
当要读取某个对象的属性时,JavaScript将会在该对象中寻找这个属性。如果没有找到,JavaScript就会在该对象的原型中继续寻找,如果还找不到,就继续找原型的原型,依次进行下去,直到找到这个属性或者已经找到了这条链的尽头。
JavaScript为每一个类型(Type--Object是一个类型,new Object()定义了一个对象)都提供了一个prototype属性,将这个属性指向一个对象,这个对象就成为了这个类型的“原型”,这意味着由这个类型所创建的所有对象都具有这个原型的特性。
另外,JavaScript的对象是动态的,原型也不例外,给prototype增加或者减少属性,将改变这个类型的原型,这种改变将直接作用到由这个原型创建的所有对象上。当创建一个对象时,它的原型引用也就设置好了,而且在这个对象的生命周期内,这个引用都不会再更改。
原型与类型的关系要求一个类型在一个时刻只能有一个原型。对于JavaScript来说,这个限制有两层含义,第一是每个具体的JavaScript类型有且仅有一个原型(prototype),在默认的情况下,这个原型是一个Object对象(注意不是Object类型)。第二是,这个对象所属的类型,必须是满足原型关系的类型链。
由于在JavaScript中有两种创建对象的方法,所以也有两种设置对象的原型引用的方法。首先,每个由对象常量创建的对象都会将其原型引用指向内建类型Object的Object对象。
var obj1 = {}; var obj2 = {}; var obj3 = new Object(); //obj1、obj2、obj3具有相同的原型对象
第二种情况下,每个由关键字new加上构造函数而创建的对象,同时将构造函数的prototype对象指派给新创建的对象,成为该对象内置的原型对象。
var p = {}; function SomeConstructor () { //...... } SomeConstructor.prototype = p; SomeConstructor.prototype.constructor = SomeConstructor; alert(p.constructor); var obj1 = new SomeConstructor(); var obj2 = new SomeConstructor(); //obj1、obj2具有相同原型对象p //p的原型引用指向内置对象Object的原型对象
类的继承在JavaScript中是通过构建原型链来模拟的。
类实例是通过调用构造函数来产生的。
实现类的继承
<script type="text/javascript"> /** 定义一个形状类:Shape,通过原型对象添加两个方法 */ function Shape () { this.color = -1; } Shape.prototype.setColor = function (color) { this.color = color; } Shape.prototype.getColor = function () { return this.color; } Shape.prototype.area = function () { alert("计算面积"); } /** 定义一个类Circle,通过原型对象添加三个方法 */ function Circle () { this.radius = 0; } Circle.prototype = new Shape(); Circle.prototype.constructor = Circle; //注意此处 Circle.prototype.setRadius = function (radius) { this.radius = radius; } Circle.prototype.getRadius = function () { return this.radius; } Circle.prototype.area = function () { return Math.PI * this.radius * this.radius; //tjis不可省略 } /** 通过构造函数Circle创建对象 */ var circle1 = new Circle(); circle1.setRadius(3); alert(circle1.area()); /** 当希望查看或设置圆的颜色的时候可以通过setColor(color)和getColor()来设置或查看 但是Circle类本身并没有定义setColor/getColor方法,此时就会调用Shape的方法,实现继承 */ alert(circle1.getColor()); </script>