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>