1. 例子
1.1. 代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>模拟原型链</title>
</head>
<body>
<script type="text/javascript">
// 对应语言本身的Object
function MyObject(){
this.__myproto__ = MyObject.myprototype;
}
// 对应语言本身的String
function MyString(){
this.__myproto__ = MyString.myprototype;
}
// 对应语言本身的Boolean
function MyBoolean(){
this.__myproto__ = MyBoolean.myprototype;
}
// 对应语言本身的Number
function MyNumber(){
this.__myproto__ = MyNumber.myprototype;
}
// 对应语言本身的Array
function MyArray(){
this.__myproto__ = MyArray.myprototype;
}
// 对应语言本身的Function
function MyFunction(){
this.__myproto__ = MyFunction.myprototype;
}
// 我们自定义的类对象MyFn
function MyFn(){
this.__myproto__ = MyFn.myprototype;
}
// 1.1. constructor属性是对创建对象的函数的引用。
// 1.2. 类对象的constructor属性, 指向了Function的构造器函数。因此我们可以说, String、Boolean、Number、Array、Function, 以及我们自定义的MyFn都是有函数创建的对象。
MyObject.myconstructor = MyFunction;
MyString.myconstructor = MyFunction;
MyBoolean.myconstructor = MyFunction;
MyNumber.myconstructor = MyFunction;
MyArray.myconstructor = MyFunction;
MyFunction.myconstructor = MyFunction;
MyFn.myconstructor = MyFunction;
// 2.1. 类的prototype(原型)属性都是自己的。Object、String、Boolean、Number、Array、Function, 以及我们创建的类MyFn的原型都是不一样的。但是String、Boolean、Number、Array、Function, 以及我们创建的MyFn都继承了Object的原型。Object的原型是原型链的最顶端。
// 2.2. prototype属性是对象。对于Function类, 它的typeof Function.prototype返回的是function, 但实际上是对象, 因为函数本身就是特殊的对象。
// 2.3. prototype上有2个跟原型相关的重要属性constructor和__proto__。这也符合我们之前的规则, 因为prototype是对象, 所以它有__proto__属性。
// 3. prototype.constructor属性是对类的构造器函数的引用。
// 4.1. 正如我们之前所讲的__proto__属性, 指向创建对象的类的原型。不管prototype是哪个类的属性, prototype是对象, 它是由Object类创建的对象, 因此所有类(不包括Object本身)的prototype.__proto__属性都指向Object.prototype。
// 4.2. Object.prototype.__proto__的值是null, 也印证了Object.prototype是原型链的最顶层。
MyObject.myprototype = {myconstructor: MyObject, __myproto__: null, myHasOwnProperty: function(){}, myIsPrototypeOf: function(){},
myPropertyIsEnumerable: function(){}, myToLocaleString: function(){}, myToString: function(){}, myValueOf: function(){}};
MyString.myprototype = {myconstructor: MyString, __myproto__: MyObject.myprototype, myToString: function(){}, myValueOf: function(){}};
MyBoolean.myprototype = {myconstructor: MyBoolean, __myproto__: MyObject.myprototype, myToString: function(){}, myValueOf: function(){}};
MyNumber.myprototype = {myconstructor: MyNumber, __myproto__: MyObject.myprototype, myToLocaleString: function(){}, myToString: function(){}, myValueOf: function(){}};
MyArray.myprototype = {myconstructor: MyArray, __myproto__: MyObject.myprototype, myToLocaleString: function(){}, myToString: function(){}};
// 匿名函数
var niming = function(){};
niming.myconstructor = MyFunction;
niming.__myproto__ = MyObject.myprototype;
MyFunction.myprototype = niming;
MyFn.myprototype = {myconstructor: MyFn, __myproto__: MyObject.myprototype};
// 5.1. __proto__属性是对创建对象的类的原型的引用。
// 5.2. 类对象的__proto__属性, 指向了Function类的原型。
// 5.3. 使用new关键字创建的对象的__proto__属性, 指向了它对应类的原型。
MyObject.__myproto__ = MyFunction.myprototype;
MyString.__myproto__ = MyFunction.myprototype;
MyBoolean.__myproto__ = MyFunction.myprototype;
MyNumber.__myproto__ = MyFunction.myprototype;
MyArray.__myproto__ = MyFunction.myprototype;
MyFunction.__myproto__ = MyFunction.myprototype;
MyFn.__myproto__ = MyFunction.myprototype;
var obj = new MyObject();
var str = new MyString();
var bool = new MyBoolean();
var num = new MyNumber();
var arr = new MyArray();
var fun = new MyFunction();
var myFn = new MyFn();
document.write("类有prototype(原型)属性: <br />");
document.write(MyObject.myprototype + ', ' + typeof MyObject.myprototype + "<br />");
document.write(MyString.myprototype + ', ' + typeof MyString.myprototype + "<br />");
document.write(MyBoolean.myprototype + ', ' + typeof MyBoolean.myprototype + "<br />");
document.write(MyNumber.myprototype + ', ' + typeof MyNumber.myprototype + "<br />");
document.write(MyArray.myprototype + ', ' + typeof MyArray.myprototype + "<br />");
document.write(MyFunction.myprototype + ', ' + typeof MyFunction.myprototype + "<br />");
document.write(MyFn.myprototype + ', ' + typeof MyFn.myprototype + "<hr />");
document.write("对象有__proto__属性: <br />");
document.write(MyObject.__myproto__ + ', ' + (MyObject.__myproto__ === MyFunction.myprototype) + "<br />");
document.write(MyString.__myproto__ + ', ' + (MyString.__myproto__ === MyFunction.myprototype) + "<br />");
document.write(MyBoolean.__myproto__ + ', ' + (MyBoolean.__myproto__ === MyFunction.myprototype) + "<br />");
document.write(MyNumber.__myproto__ + ', ' + (MyNumber.__myproto__ === MyFunction.myprototype) + "<br />");
document.write(MyArray.__myproto__ + ', ' + (MyArray.__myproto__ === MyFunction.myprototype) + "<br />");
document.write(MyFunction.__myproto__ + ', ' + (MyFunction.__myproto__ === MyFunction.myprototype) + "<br />");
document.write(MyFn.__myproto__ + ', ' + (MyFn.__myproto__ === MyFunction.myprototype) + "<br /><br />");
document.write(obj.__myproto__ + ', ' + (obj.__myproto__ === MyObject.myprototype) + "<br />");
document.write(str.__myproto__ + ', ' + (str.__myproto__ === MyString.myprototype) + "<br />");
document.write(bool.__myproto__ + ', ' + (bool.__myproto__ === MyBoolean.myprototype) + "<br />");
document.write(num.__myproto__ + ', ' + (num.__myproto__ === MyNumber.myprototype) + "<br />");
document.write(arr.__myproto__ + ', ' + (arr.__myproto__ === MyArray.myprototype) + "<br />");
document.write(fun.__myproto__ + ', ' + (fun.__myproto__ === MyFunction.myprototype) + "<br />");
document.write(myFn.__myproto__ + ', ' + (myFn.__myproto__ === MyFn.myprototype) + "<hr />");
document.write("类对象有constructor属性: <br />");
document.write(MyObject.myconstructor + ', ' + (MyObject.myconstructor === MyFunction) + "<br />");
document.write(MyString.myconstructor + ', ' + (MyString.myconstructor === MyFunction) + "<br />");
document.write(MyBoolean.myconstructor + ', ' + (MyBoolean.myconstructor === MyFunction) + "<br />");
document.write(MyNumber.myconstructor + ', ' + (MyNumber.myconstructor === MyFunction) + "<br />");
document.write(MyArray.myconstructor + ', ' + (MyArray.myconstructor === MyFunction) + "<br />");
document.write(MyFunction.myconstructor + ', ' + (MyFunction.myconstructor === MyFunction) + "<br />");
document.write(MyFn.myconstructor + ', ' + (MyFn.myconstructor === MyFunction) + "<hr />");
document.write("我们创建的对象的__proto__属性上有constructor属性: <br />");
document.write(obj.__myproto__.myconstructor + ', ' + (obj.__myproto__.myconstructor === MyObject) + "<br />");
document.write(str.__myproto__.myconstructor + ', ' + (str.__myproto__.myconstructor === MyString) + "<br />");
document.write(bool.__myproto__.myconstructor + ', ' + (bool.__myproto__.myconstructor === MyBoolean) + "<br />");
document.write(num.__myproto__.myconstructor + ', ' + (num.__myproto__.myconstructor === MyNumber) + "<br />");
document.write(arr.__myproto__.myconstructor + ', ' + (arr.__myproto__.myconstructor === MyArray) + "<br />");
document.write(fun.__myproto__.myconstructor + ', ' + (fun.__myproto__.myconstructor === MyFunction) + "<br />");
document.write(myFn.__myproto__.myconstructor + ', ' + (myFn.__myproto__.myconstructor === MyFn) + "<hr />");
document.write("类prototype(原型)上的constructor属性: <br />");
document.write(MyObject.myprototype.myconstructor + ', ' + (MyObject.myprototype.myconstructor === MyObject) + "<br />");
document.write(MyString.myprototype.myconstructor + ', ' + (MyString.myprototype.myconstructor === MyString) + "<br />");
document.write(MyBoolean.myprototype.myconstructor + ', ' + (MyBoolean.myprototype.myconstructor === MyBoolean) + "<br />");
document.write(MyNumber.myprototype.myconstructor + ', ' + (MyNumber.myprototype.myconstructor === MyNumber) + "<br />");
document.write(MyArray.myprototype.myconstructor + ', ' + (MyArray.myprototype.myconstructor === MyArray) + "<br />");
document.write(MyFunction.myprototype.myconstructor + ', ' + (MyFunction.myprototype.myconstructor === MyFunction) + "<br />");
document.write(MyFn.myprototype.myconstructor + ', ' + (MyFn.myprototype.myconstructor === MyFn) + "<hr />");
document.write("类prototype(原型)上的__proto__属性: <br />");
document.write((MyObject.myprototype.__myproto__) + "<br />");
document.write(MyString.myprototype.__myproto__ + ', ' + (MyString.myprototype.__myproto__ === MyObject.myprototype) + "<br />");
document.write(MyBoolean.myprototype.__myproto__ + ', ' + (MyBoolean.myprototype.__myproto__ === MyObject.myprototype) + "<br />");
document.write(MyNumber.myprototype.__myproto__ + ', ' + (MyNumber.myprototype.__myproto__ === MyObject.myprototype) + "<br />");
document.write(MyArray.myprototype.__myproto__ + ', ' + (MyArray.myprototype.__myproto__ === MyObject.myprototype) + "<br />");
document.write(MyFunction.myprototype.__myproto__ + ', ' + (MyFunction.myprototype.__myproto__ === MyObject.myprototype) + "<br />");
document.write(MyFn.myprototype.__myproto__ + ', ' + (MyFn.myprototype.__myproto__ === MyObject.myprototype) + "<br />");
</script>
</body>
</html>
1.2. 效果图