原型与原型链
每一个JavaScript
对象(null除外)都和另一个对象相关联,“另一个对象”就是原型,每一个对象都从原型继承属性。
原型
首先你需要知道prototype
和__proto__
的含义,以及它们区别与关系。
1 每一个函数都有一个prototype
原型属性,prototype
是一个指针,它指向这个函数的原型对象,同时prototype
属性也是一个对象。
2 每一个JavaScript
对象(null除外)都有一个__proto__
属性,__proto__
指向它构造函数的prototype
;
所以__proto__
就是用来连接实例与构造函数的原型对象的属性。
请看下面代码
Person = function() {}; //创建一个函数
Person.prototype.name = '小明'; //在函数的原型上添加name属性
var children = new Person(); //创建一个实例对象
console.log(children.name); //打印实例对象的name属性:小明
在上面的例子中,children
对象中并没有name
属性,但能打印出小明。
因为children
找不到name
,就会从children
的原型__proto__
中去找,而children.__proto__
指向Person.prototype
接上面的代码
console.log(Person.prototype); //打印Person.prototype
console.log(children.__proto__); //打印children.__proto__
console.log(Person.prototype === children.__proto__); //比较它们两个
从打印结果来看children.__proto__
和Person.prototype
相等,这就证实了对象的__proto__
都指向它构造函数的prototype
。
那么,就可以说children
的原型就是Person.prototype
。
那什么是原型链呢?
首先加入下面的代码
Object.prototype.text = '我是Object的text'; //在Object上添加新属性
console.log(children.text); //在children上找text属性
在本例中当children
试图查找text
时,children
中不存在这个值,它就会通过children.__proto__
去查找它构造函数的Person.prototype
的值;
如果构造函数中也没有这个值,就会通过Person.__proto__
去查找Object.prototype
中的值,像这样通过原型__proto__
一层层向上查找的过程中形成的一条链,就叫做原型链。
再补充一条:Object.prototype
对象没有原型,Object.prototype.__proto__
的值为null
//所以以下代码将打印null
console.log(Object.prototype.__proto__);
本文完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript原型与原型链</title>
</head>
<body>
<script>
Person = function() {}; //创建一个构造函数
Person.prototype.name = '小明'; //添加属性name
var children = new Person(); //创建一个实例对象
console.log(children.name); //打印:小明
console.log(Person.prototype);
console.log(children.__proto__);
console.log(Person.prototype === children.__proto__);
Object.prototype.text = '我是Object的text';
console.log(children.text);
console.log(Object.prototype.__proto__);
</script>
</body>
</html>