在JavaScript中,typeof是测试对象的类型,只会测试出对象属于哪种内置类型,无法测试自定义类型。也就是所有自定义类型都会返回object。
而obj instanceof sometype(obj 指对象,sometype指的是类型),是测试obj的原型链中是否有sometype类型。所以通过错误的改变prototype的值会使得instanceof得出的结构不合理。
<script> var num = 10; document.write("typeof num:"+typeof num+"<br/>"); var onum = Number(10); document.write("typeof onum:"+typeof onum+"<br/>"); var str = "1010"; document.write("typeof str:"+typeof str+"<br/>"); var ostr = String("1010"); document.write("typeof ostr:"+typeof ostr+"<br/>"); var bol = true; document.write("typeof bol:"+typeof bol+"<br/>"); var obol = true; document.write("typeof obol:"+typeof obol+"<br/>"); var dat = new Date(); document.write("typeof dat:"+typeof dat+"<br/>"); var func = new Function('x','y',"return x+y;"); document.write("typeof func:"+typeof func+"<br/>"); var myconstructor = function Person(){}; document.write("typeof myconstructor:"+typeof myconstructor+"<br/>"); var myobj = new myconstructor(); document.write("typeof myobj:"+typeof myobj+"<br/>"); </script>结果:
typeof num:number typeof onum:number typeof str:string typeof ostr:string typeof bol:boolean typeof obol:boolean typeof dat:object typeof func:function typeof myconstructor:function typeof myobj:object这说明元构造器的类型为:function
//案例一 var Person = function(){}; var obj = new Person(); document.write((obj instanceof Person) +"<br/>"); document.write((obj instanceof Object) +"<br/>"); document.write(obj.__proto__ +"<br/>"); document.write(Person.constructor+"<br/>"); document.write(obj.constructor+"<br/>"); document.write((obj.constructor === Person)+"<br/>");结果:
true true [object Object] function Function() { [native code]} function (){} true
//案例二 var other = function(){}; Person.prototype = new other(); document.write((obj instanceof Person) +"<br/>"); document.write((obj instanceof Object) +"<br/>"); document.write((obj instanceof other) +"<br/>"); document.write(obj.__proto__ +"<br/>"); document.write(obj.constructor+"<br/>");结果:
false true false [object Object] function (){}
//案例三 obj.__proto__ = new other(); document.write((obj instanceof Person) +"<br/>"); document.write((obj instanceof Object) +"<br/>"); document.write((obj instanceof other) +"<br/>"); document.write(obj.__proto__ +"<br/>");结果:
false true true [object Object]下面我们就来具体分析这三个案例:
{
this.prototype = {constructor:this}; //{}表示一个Object构造的空对象
var prototype = Function.prototype; //内部{Prototype}属性,不能改变
this.__proto__ = prototype; //内部属性的外部访问方式,
this.constructor = this; // 默认的,也是合理的值
}
var obj = new Person();
这句发生了什么呢?我们也用伪代码来解释一下:生成普通对象obj
{ var prototype = Person.prototype; this.__proto__ = prototype; this.constructor = Person; }按此来说,在案例一中:
//function类型 Person.__proto__=== Function.prototype; //object类型, 默认情况下每个构造器内部都有一个Object的实例对象,供所有子类共享,这就是所有对象都默认继承object的实例的原因 Person.prototype === obj.__proto__ ; //验证每个自定义类型都默认继承自一个Object实例object Person.prototype.__proto__ = Object.prototype; //每个对象的构造器为构造它的函数对象 Person.constructor === Function; Function.constructor === Function; //说明Function由自己构造,自举性 obj.constructor === Person; //从中可以看出prototype告诉构造器,你构造的对象应该继承谁 //__proto__可以告诉我们该对象继承自谁。其次我们可以看出:
//Function 的自举性 Function.prototype === Function.prototype; Function.__proto__ === Function.prototype; Function.constructor === Function; //Object由Function构造 Object.prototype === Object.prototype; Object.__proto__ === Function.prototype; Object.constructor === Function; Function.prototype.__proto__ === Object.prototype; //说明Object.prototype是万物之源而obj对象呢,也有着这些特性,不过它是普通对象,没有公开属性prototype:
//普通对象特性 obj.__proto__ === Person.prototype; obj.constructor === Person;我们再来看看Object.prototype:
//元对象
Object.prototype === Object.prototype; //对象的祖宗,根
Object.prototype.__proto__ === null; //祖先没有祖先,单位了系统完备,其内部仍然有{Prototype}属性,置为null,合理。
Object.prototype.constructor === Object; //祖先按理说是没有构造器的,但为了说明祖先仍然属于Object的实例,就这么做。
接着我们再看看Function.prototype:
//元构造器 Function.prototype === Function.prototype; //由Function构造出来的对象的原型 Function.prototype.__proto__ === Object.prototype; //对象Function.prototype的原型为Object.prototype Function.prototype.constructor === Function; //对象Function.prototype是由构造器Function构造的,实际上并非如此,但是为了Function.prototype的类型是Function也就这么设计了。
1.一切都是对象
在Js中一切都是对象,而几乎所有对象都由构造器产生。不过有一个例外,所有对象的基础(元对象):Object.prototype,他不是由构造器产生,而是由Js引擎实现。它不同于java的Object——那是一个类,而Js中的Object.prototype仅仅是一个对象,它不能作为构造器。这来来讲就好比西方人类最初也只有两个人作为祖先——亚当和夏娃。但是在Js中只有一个没有构造功能的Object.prototype那么如何基于这个原型来构造子对象呢,这就需要下面讲到的元构造器——Function.prototype。
2.Object.prototype不是由构造器产生
3.Function.prototype由自己构造,但是却是继承自Object.prototype
4.继承只是继承对象,所谓对象A继承自B,说明对象A维护者对象B的引用
5.函数对象中的__proto__才是指明该函数对象作为对象时继承自谁,或者说维护了哪个对象的引用
6.函数对象中有个特别的特性prototype,这是普通对象所不具有的,这是函数对象作为构造器时的特性,它指明了该构造器作为”伪类“时的内部数据结构,他是一个引用类型。由该构造器构造出来的对象都维护着prototype所引用的对象的引用
事实上C/C++可以实现类似的功能,点击这里看看C/C++实现Js原型继承模式:C/C++实现Js原型继承机制