在JavaScript中,typeof是测试对象的类型,只会测试出对象属于哪种内置类型,无法测试自定义类型。也就是所有自定义类型都会返回object。
而obj instanceof sometype(obj 指对象,sometype指的是类型),是测试obj的原型链中是否有sometype类型。所以通过错误的改变prototype的值会使得instanceof得出的结构不合理。
结果:
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) +"
");
document.write((obj instanceof Object) +"
");
document.write(obj.__proto__ +"
");
document.write(Person.constructor+"
");
document.write(obj.constructor+"
");
document.write((obj.constructor === Person)+"
");
结果:
true
true
[object Object]
function Function() { [native code]}
function (){}
true
//案例二
var other = function(){};
Person.prototype = new other();
document.write((obj instanceof Person) +"
");
document.write((obj instanceof Object) +"
");
document.write((obj instanceof other) +"
");
document.write(obj.__proto__ +"
");
document.write(obj.constructor+"
");
结果:
false
true
false
[object Object]
function (){}
//案例三
obj.__proto__ = new other();
document.write((obj instanceof Person) +"
");
document.write((obj instanceof Object) +"
");
document.write((obj instanceof other) +"
");
document.write(obj.__proto__ +"
");
结果:
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原型继承机制