1. 类
1.1. 可以使用new关键字来创建对象的模板, 我们叫做类。
Object
String
Boolean
Number
Array
Function
function MyFn(){}
1.2. 类有prototype(原型)属性:
document.write(Object.prototype + "<br />");
document.write(String.prototype + "<br />");
document.write(Boolean.prototype + "<br />");
document.write(Number.prototype + "<br />");
document.write(Array.prototype + "<br />");
document.write(Function.prototype + "<br />");
document.write(MyFn.prototype + "<hr />");
2. 对象
2.1. 在JavaScript中类也是对象, 我们姑且叫做类对象:
Object
String
Boolean
Number
Array
Function
function MyFn(){}
2.2. 我们创建的对象:
function MyFn(){}
var obj = new Object();
var easyObj = {};
var str = new String();
var bool = new Boolean();
var num = new Number();
var arr = new Array();
var easyArr = [];
var fun = new Function();
var myFn = new MyFn();
2.3. 对象有__proto__属性:
document.write(Object.__proto__ + "<br />");
document.write(String.__proto__ + "<br />");
document.write(Boolean.__proto__ + "<br />");
document.write(Number.__proto__ + "<br />");
document.write(Array.__proto__ + "<br />");
document.write(Function.__proto__ + "<br />");
document.write(MyFn.__proto__ + "<hr />");
document.write(obj.__proto__ + "<br />");
document.write(easyObj.__proto__ + "<br />");
document.write(str.__proto__ + "<br />");
document.write(bool.__proto__ + "<br />");
document.write(num.__proto__ + "<br />");
document.write(arr.__proto__ + "<br />");
document.write(easyArr.__proto__ + "<br />");
document.write(fun.__proto__ + "<br />");
document.write(myFn.__proto__ + "<hr />");
2.3. 我们归结JavaScript有2种对象, 一种是我们创建的对象, 一种是类对象。
3. 类对象的constructor属性
3.1. 类对象的constructor属性是对创建对象的函数的引用。
3.2. 类对象的constructor属性, 指向了Function的构造器函数。因此我们可以说, String、Boolean、Number、Array、Function, 以及我们自定义的MyFn都是有函数创建的。
document.write(Object.constructor + ', ' + (Object.constructor === Function) + "<br />");
document.write(String.constructor + ', ' + (String.constructor === Function) + "<br />");
document.write(Boolean.constructor + ', ' + (Boolean.constructor === Function) + "<br />");
document.write(Number.constructor + ', ' + (Number.constructor === Function) + "<br />");
document.write(Array.constructor + ', ' + (Array.constructor === Function) + "<br />");
document.write(Function.constructor + ', ' + (Function.constructor === Function) + "<br />");
document.write(MyFn.constructor + ', ' + (MyFn.constructor === Function) + "<hr />");
4. __proto__属性
4.1. __proto__属性是对创建对象的类的原型的引用。
4.2. 类对象的__proto__属性, 指向了Function类的原型。
4.3. 我们创建的对象的__proto__属性, 指向了它对应类的原型。
document.write(Object.__proto__ + ', ' + (Object.__proto__ === Function.prototype) + "<br />");
document.write(String.__proto__ + ', ' + (String.__proto__ === Function.prototype) + "<br />");
document.write(Boolean.__proto__ + ', ' + (Boolean.__proto__ === Function.prototype) + "<br />");
document.write(Number.__proto__ + ', ' + (Number.__proto__ === Function.prototype) + "<br />");
document.write(Array.__proto__ + ', ' + (Array.__proto__ === Function.prototype) + "<br />");
document.write(Function.__proto__ + ', ' + (Function.__proto__ === Function.prototype) + "<br />");
document.write(MyFn.__proto__ + ', ' + (MyFn.__proto__ === Function.prototype) + "<hr />");
document.write(obj.__proto__ + ', ' + (obj.__proto__ === Object.prototype) + "<br />");
document.write(str.__proto__ + ', ' + (str.__proto__ === String.prototype) + "<br />");
document.write(bool.__proto__ + ', ' + (bool.__proto__ === Boolean.prototype) + "<br />");
document.write(num.__proto__ + ', ' + (num.__proto__ === Number.prototype) + "<br />");
document.write(arr.__proto__ + ', ' + (arr.__proto__ === Array.prototype) + "<br />");
document.write(fun.__proto__ + ', ' + (fun.__proto__ === Function.prototype) + "<br />");
document.write(myFn.__proto__ + ', ' + (myFn.__proto__ === MyFn.prototype) + "<hr />");
4.4. 我们创建的对象的__proto__属性上有constructor属性, constructor属性是对创建对象的函数的引用。
document.write(obj.__proto__.constructor + ', ' + (obj.__proto__.constructor === Object) + "<br />");
document.write(str.__proto__.constructor + ', ' + (str.__proto__.constructor === String) + "<br />");
document.write(bool.__proto__.constructor + ', ' + (bool.__proto__.constructor === Boolean) + "<br />");
document.write(num.__proto__.constructor + ', ' + (num.__proto__.constructor === Number) + "<br />");
document.write(arr.__proto__.constructor + ', ' + (arr.__proto__.constructor === Array) + "<br />");
document.write(fun.__proto__.constructor + ', ' + (fun.__proto__.constructor === Function) + "<br />");
document.write(myFn.__proto__.constructor + ', ' + (myFn.__proto__.constructor === MyFn) + "<hr />");
5. 类的prototype(原型)属性
5.1. 类的prototype(原型)属性都是自己的。Object、String、Boolean、Number、Array、Function, 以及我们创建的类MyFn的原型都是不一样的。但是String、Boolean、Number、Array、Function, 以及我们创建的MyFn都继承了Object的原型。Object的原型是原型链的最顶端。
5.2. prototype属性是对象。对于Function类, 它的typeof Function.prototype返回的是function, 但实际上是对象, 因为函数本身就是特殊的对象。
document.write(Object.prototype + ', ' + typeof Object.prototype + "<br />");
document.write(String.prototype + ', ' + typeof String.prototype + "<br />");
document.write(Boolean.prototype + ', ' + typeof Boolean.prototype + "<br />");
document.write(Number.prototype + ', ' + typeof Number.prototype + "<br />");
document.write(Array.prototype + ', ' + typeof Array.prototype + "<br />");
document.write(Function.prototype + ', ' + typeof Function.prototype + "<br />");
document.write(MyFn.prototype + ', ' + typeof MyFn.prototype + "<hr />");
5.3. prototype上有2个跟原型链相关的重要属性constructor和__proto__。这也符合我们之前的规则, 因为prototype是对象, 所以它有__proto__属性。
6. prototype.constructor属性是对类的构造器函数的引用。
document.write(Object + ', ' + Object.prototype.constructor + "<br />");
document.write(String + ', ' + String.prototype.constructor + "<br />");
document.write(Boolean + ', ' + Boolean.prototype.constructor + "<br />");
document.write(Number + ', ' + Number.prototype.constructor + "<br />");
document.write(Array + ', ' + Array.prototype.constructor + "<br />");
document.write(Function + ', ' + Function.prototype.constructor + "<br />");
document.write(MyFn + ', ' + MyFn.prototype.constructor + "<hr />");
7. prototype.__proto__属性
7.1. 正如我们之前所讲的__proto__属性, 指向创建对象的类的原型。不管prototype是哪个类的属性, prototype是对象, 它是由Object类创建的对象, 因此所有类(不包括Object本身)的prototype.__proto__属性都指向Object.prototype。
7.2. Object.prototype.__proto__的值是null, 也印证了Object.prototype是原型链的最顶层。
document.write((String.prototype.__proto__ === Object.prototype) + "<br />");
document.write((Boolean.prototype.__proto__ === Object.prototype) + "<br />");
document.write((Number.prototype.__proto__ === Object.prototype) + "<br />");
document.write((Array.prototype.__proto__ === Object.prototype) + "<br />");
document.write((Function.prototype.__proto__ === Object.prototype) + "<br />");
document.write((MyFn.prototype.__proto__ === Object.prototype) + "<br />");
document.write((Object.prototype.__proto__) + "<br />");
8. 例子
8.1. 代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>原型链</title>
<meta charset="utf-8" />
</head>
<body>
<script type="text/javascript">
function MyFn(){}
var obj = new Object();
var str = new String();
var bool = new Boolean();
var num = new Number();
var arr = new Array();
var fun = new Function();
var myFn = new MyFn();
document.write("类有prototype(原型)属性: <br />");
document.write(Object.prototype + ', ' + typeof Object.prototype + "<br />");
document.write(String.prototype + ', ' + typeof String.prototype + "<br />");
document.write(Boolean.prototype + ', ' + typeof Boolean.prototype + "<br />");
document.write(Number.prototype + ', ' + typeof Number.prototype + "<br />");
document.write(Array.prototype + ', ' + typeof Array.prototype + "<br />");
document.write(Function.prototype + ', ' + typeof Function.prototype + "<br />");
document.write(MyFn.prototype + ', ' + typeof MyFn.prototype + "<hr />");
document.write("对象有__proto__属性: <br />");
document.write(Object.__proto__ + ', ' + (Object.__proto__ === Function.prototype) + "<br />");
document.write(String.__proto__ + ', ' + (String.__proto__ === Function.prototype) + "<br />");
document.write(Boolean.__proto__ + ', ' + (Boolean.__proto__ === Function.prototype) + "<br />");
document.write(Number.__proto__ + ', ' + (Number.__proto__ === Function.prototype) + "<br />");
document.write(Array.__proto__ + ', ' + (Array.__proto__ === Function.prototype) + "<br />");
document.write(Function.__proto__ + ', ' + (Function.__proto__ === Function.prototype) + "<br />");
document.write(MyFn.__proto__ + ', ' + (MyFn.__proto__ === Function.prototype) + "<br /><br />");
document.write(obj.__proto__ + ', ' + (obj.__proto__ === Object.prototype) + "<br />");
document.write(str.__proto__ + ', ' + (str.__proto__ === String.prototype) + "<br />");
document.write(bool.__proto__ + ', ' + (bool.__proto__ === Boolean.prototype) + "<br />");
document.write(num.__proto__ + ', ' + (num.__proto__ === Number.prototype) + "<br />");
document.write(arr.__proto__ + ', ' + (arr.__proto__ === Array.prototype) + "<br />");
document.write(fun.__proto__ + ', ' + (fun.__proto__ === Function.prototype) + "<br />");
document.write(myFn.__proto__ + ', ' + (myFn.__proto__ === MyFn.prototype) + "<hr />");
document.write("类对象有constructor属性: <br />");
document.write(Object.constructor + ', ' + (Object.constructor === Function) + "<br />");
document.write(String.constructor + ', ' + (String.constructor === Function) + "<br />");
document.write(Boolean.constructor + ', ' + (Boolean.constructor === Function) + "<br />");
document.write(Number.constructor + ', ' + (Number.constructor === Function) + "<br />");
document.write(Array.constructor + ', ' + (Array.constructor === Function) + "<br />");
document.write(Function.constructor + ', ' + (Function.constructor === Function) + "<br />");
document.write(MyFn.constructor + ', ' + (MyFn.constructor === Function) + "<hr />");
document.write("我们创建的对象的__proto__属性上有constructor属性: <br />");
document.write(obj.__proto__.constructor + ', ' + (obj.__proto__.constructor === Object) + "<br />");
document.write(str.__proto__.constructor + ', ' + (str.__proto__.constructor === String) + "<br />");
document.write(bool.__proto__.constructor + ', ' + (bool.__proto__.constructor === Boolean) + "<br />");
document.write(num.__proto__.constructor + ', ' + (num.__proto__.constructor === Number) + "<br />");
document.write(arr.__proto__.constructor + ', ' + (arr.__proto__.constructor === Array) + "<br />");
document.write(fun.__proto__.constructor + ', ' + (fun.__proto__.constructor === Function) + "<br />");
document.write(myFn.__proto__.constructor + ', ' + (myFn.__proto__.constructor === MyFn) + "<hr />");
document.write("类prototype(原型)上的constructor属性: <br />");
document.write(Object.prototype.constructor + ', ' + (Object.prototype.constructor === Object) + "<br />");
document.write(String.prototype.constructor + ', ' + (String.prototype.constructor === String) + "<br />");
document.write(Boolean.prototype.constructor + ', ' + (Boolean.prototype.constructor === Boolean) + "<br />");
document.write(Number.prototype.constructor + ', ' + (Number.prototype.constructor === Number) + "<br />");
document.write(Array.prototype.constructor + ', ' + (Array.prototype.constructor === Array) + "<br />");
document.write(Function.prototype.constructor + ', ' + (Function.prototype.constructor === Function) + "<br />");
document.write(MyFn.prototype.constructor + ', ' + (MyFn.prototype.constructor === MyFn) + "<hr />");
document.write("类prototype(原型)上的__proto__属性: <br />");
document.write(Object.prototype.__proto__ + "<br />");
document.write(String.prototype.__proto__ + ', ' + (String.prototype.__proto__ === Object.prototype) + "<br />");
document.write(Boolean.prototype.__proto__ + ', ' + (Boolean.prototype.__proto__ === Object.prototype) + "<br />");
document.write(Number.prototype.__proto__ + ', ' + (Number.prototype.__proto__ === Object.prototype) + "<br />");
document.write(Array.prototype.__proto__ + ', ' + (Array.prototype.__proto__ === Object.prototype) + "<br />");
document.write(Function.prototype.__proto__ + ', ' + (Function.prototype.__proto__ === Object.prototype) + "<br />");
document.write(MyFn.prototype.__proto__ + ', ' + (MyFn.prototype.__proto__ === Object.prototype) + "<br />");
</script>
</body>
</html>
8.2. 效果图