-
前言
突然间被办公室的一个java小哥哥问到:小前哥,js中的原型链是啥,你能给我描述一下嘛?脑子好像突然失灵,不知道从哪个方便要给小哥哥讲这个问题,最后找了一个自认为不错的文章发给他看(哈哈,此处有小哥哥的大白眼)。小哥哥的大白眼让我觉得自己是时候要自救一波基础知识了,决定从基础开始我的前端自救之路了。。
要明白js中原型和原型链,我们首先必须要知道几个概念
-
正文
-
构造函数:在 JavaScript中,用new关键字来调用的函数,称为构造函数。构造函数首字母一般大写。
function Animal(){ }
//这就是一个最简单的构造函数
- prototype : 每个 函数 都有一个prototype属性,这里是函数,它是构造函数的原型对象
;
- constructor 原型对象上的一个指向构造函数的属性
- 实例对象:实例对象通过构造函数进行创建。
var pig = new Animal()
//通过new关键字,我们就创建了一个实例对象
__proto__
: 每个对象都有这个私有属性,这里是对象,JavaScript中,一切皆是对象,函数也是对象,所以函数也有这个属性。它指向构造函数的原型对象- 原型与实例
function Animal() {}
Animal.prototype.name = 'Peiqi';
var pig = new Animal();
console.log(pig.name) //Peiqi
console.log(pig.age) // undefined
pig.name = 'Jony';
pig.age = 18
console.log(pig.name) // Jony
delete pig.name;
console.log(pig.name) // Peiqi
console.log(pig.age) // 18
这里我们可以看出,pig.name先开始从pig对象中查找,找到的时候返回了Jony,找不就从pig的原型_proto_即Animal.prototype中找。
-
原型链
JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。换句话说:每个实例对象( object )都有一个私有属性(称之为 __ proto __ )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( __ proto __ ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

在这里
function Animal(){}
var pig = new Animal();
console.log(pig.__proto__ == Animal.prototype)
pig.__proto__ == Animal.prototype
Animal.prototype.constructor == Animal
pig.__proto__.__proto__.constructor == Object
Object.prototype.constructor == Object
pig.__proto__ .__proto__ == Object.prototype
原型链最终指向null
pig.__proto__·__proto__.__proto__ == null
下面看另外一个例子
var o = {a: 1};
// o 这个对象继承了 Object.prototype 上面的所有属性
// o 自身没有名为 hasOwnProperty 的属性, hasOwnProperty 是 Object.prototype 的属性
// 因此 o 继承了 Object.prototype 的 hasOwnProperty
// Object.prototype 的原型为 null
// 原型链如下:
// o ---> Object.prototype ---> null
var a = ["yo", "whadup", "?"];
// 数组都继承于 Array.prototype
// (Array.prototype 中包含 indexOf, forEach 等方法)
// 原型链如下:
// a ---> Array.prototype ---> Object.prototype ---> null
function f(){
return 2;
}
// 函数都继承于 Function.prototype
// 原型链如下:
// f ---> Function.prototype ---> Object.prototype ---> null
最后我们可以看出:
1. 原型存在的意义就是组成原型链:引用类型皆对象,每个对象都有原型,原型也是对象,也有它自己的原型,一层一层,组成原型链。
2. 原型链存在的意义就是继承:访问对象属性时,在对象本身找不到,就在原型链上一层一层找。说白了就是一个对象可以访问其他对象的属性。
3. 继承存在的意义就是属性共享:好处有二:一是代码重用,字面意思;二是可扩展,不同对象可能继承相同的属性,也可以定义只属于自己的属性。