1.什么是原型
(1)首先我们要明白一件事:原型存在于对象中。
接下来解释一下什么:在js中,每个构造函数内部都有一个属性,属性的值是一个对象,里面包含了构造函数所有实例共享的属性和方法。 当我们通过构造函数创建一个对象时,对象中有一个指针,它指向构造函数的值,我们称这个指针为原型。 或者用另一种简单但难以理解的方式来说:js中的对象有一个特殊的[[]]内置属性,它实际上就是原型。
(2)理解原型:每个构造函数都有一个指向原型对象的指针(.),
每个原型对象都有一个指向构造函数的指针()
构造函数创建的实例有一个指针()指向原型对象
构造函数 new() new Array() 数组。
原型对象有一个指向构造函数的指针
参见示例
console.log(Object.prototype.constructor === Object);//true
var obj = {
name: 'zhangsan'
};
console.log(obj.__proto__ === Object.prototype);//true
console.log(obj.__proto__.toString());
console.log(obj.__proto__.valueOf());
// 实例调用的方法就是从原型对象中继承来
console.log(obj.toString() === Object.prototype.toString())
console.log(obj.hasOwnProperty() === Object.prototype.hasOwnProperty());
看图就明白了:
2.什么是原型链
首先看例子
function Animal() {
this.legNum = 4
}
Animal.prototype.run = function () {
console.log('prototype, i am running')
}
//这里只是为了方便,实际上并不推荐将属性值挂载到原型上
//因为存在喜闻乐见的引用类型问题
Animal.prototype.color = 'yellow'
const a1 = new Animal()
console.log(a1.color) //yellow
它只是在()构造函数中定义,但是我们通过a1的实例获取颜色,结果也得到了。 这是为什么? 在js中获取对象的属性时,首先要检查对象本身是否具有该属性,如果有则直接使用。 但如果没有,它就会去对象的原型中查找。
综合例子分析:a1实例上没有color属性,所以找到a1的原型,而a1的原型包含run方法和color属性,所以找到并返回原型上color的值。 如果还不存在,就会寻找a1原型对象的原型,逐层查找。 一般来说,原型链的末端是 。 ,所以这就是为什么新创建的对象可以使用()等方法。
所以原型链是由原型组成的搜索链
注意:我们在开发时要注意不要通过实例对象改变其构造函数的原型对象,这样会影响通过构造函数生成的其他实例对象。