ITEEDU

javascript面向对象设计-对象和原型浅析

基本类型和对象

javascript中有三种基本数据类型,字符串(string),数值(number),布尔值(boolean),其余全是对象。

alert(typeof 'asdf');//string
alert(typeof 22);//number
alert(typeof true);//boolean
alert(typeof new function(){});//object

基本数据类型在需要时会自动包装成对象类型,完成后再拆装为基本类型。

包装过程:

alert(typeof new String('asdf'));//object
alert(typeof new Number(22));//object
alert(typeof new Boolean(true));//object
将对象转换为基本类型则是通过这样的方式:通过调用对象的valueOf()方法来取得对象的值,如果和上下文的类型匹配,则使用该值。如果valueOf取不到值的话,则需要调用对象的toString()方法,而如果上下文为数值型,则又需要将此字符串转换为数值。

对象的原型

每个对象都有一个__proto__属性,这个属性指向另一个对象。__proto__属性指向的对象为拥有__proto__属性对象的原型。由于原型也是对象,所以它也有原型,这样就成了一个链结构叫原型链。原型链最终一个原型的__proto__会指向null。
var obj=new function(){};
alert(obj.__proto__.__proto__.__proto__);//null
alert(obj.__proto__);//[object Object]
alert(obj.__proto__.__proto__);//[object Object]
函数对象的__proto__属性
function func(){var a=1;return 'adf';};
alert(typeof func);//function
alert(func instanceof Function);//true
alert(func.__proto__.__proto__.__proto__);//null
alert(func.__proto__);//function(){}
alert(typeof func.__proto__);//function
alert(func.__proto__ instanceof Function);//false
alert(func.__proto__.__proto__);//[object Object]

函数的__proto__属性很奇怪,是function类型但不是Function实例。

调用对象上的一个方法,由于方法在JavaScript对象中是对另一个函数对象的引用,因此解释器会在对象中查找该属性,如果没有找到,则在其内部对象__proto__属性上搜索,由于__proto__属性与对象本身的结构是一样的,因此这个过程会一直回溯到发现该属性,则调用该属性,否则,报告一个错误。

对象的原型是怎么来的

__proto__属性是在new操作中产生的。

var p = new ClassA ();

以上创建对象过程可以用以下过程模拟:

var p = {};
ClassA.apply(p);
p.__proto__= ClassA.prototype;

也就是说对象的原型是其构造函数的prototype属性。这样就很好理解用原型实现继承的过程了。

构造函数的prototype是用其创建的对象的原型。