原型和原型链理解
原型和原型链理解
原型和原型链理解
要知道:所有对象都是通过 ****new** 创建的**
原型
每个函数都有 prototype 属性 称之为原型,因为这个属性的值是个对象,也称之为 原型对象
作用:
- 存放一些属性和方法,共享给实例对象使用
- 在 javascript 中实现继承(ES5)
ES6中增加了 class 类,使用
extends关键字实现继承
**proto:每个对象都有一个 **proto 属性,这个属性指向它的原型对象
例:
1
2
3
const arr = new Array(1, 2, 3)
arr.sort() // 排序
arr.reverse() // 反转
我们通过 new Array() 这个构造函数创建了一个数组 arr,为什么 arr 这个数组可以使用 sort、reverse 等方法呢,其实就是因为我们原型的存在。
分析:
array 构造函数也是一个函数,只要是函数它就会有一个原型(Array.prototype)
在 JS 中,这个原型已经挂载了很多方法(我们在查一些数组的方法时候 在mdn站中前面都加上了 prototype,这些方法都是挂载在构造函数的原型身上),也就是说原型本身就有这些方法
通过构造函数生成实例 arr,arr 就可以使用 prototype 原型身上这些方法(上面说到 每个对象都有一个 proto 属性,这个属性指向它的原型对象)所以就有 arr 的 proto 等价 Array.prototype(arr.proto** **=== Array.prototype),
原型链
1
2
3
4
5
6
7
8
9
10
11
function Person() {
console.log(1)
}
Person.prototype.name = 'bob'
let person = new Person()
// person.__proto__ 指向 Person.prototype
console.log(person.__proto__, person.__proto__ === Person.prototype) // {name: "bob", [[Prototype]]: Object} true
// person.__proto__.__proto__ 指向Object.prototype
console.log(person.__proto__.__proto__) // {}
// 下面 Object.prototype 指向了 null
console.log(person.__proto__.__proto__.__proto__) // null
分析上图:
我们创建一个构造函数叫 Person,只要是函数他就有一个 prototype(原型:共享一些属性和方法);
然后通过 new 创建了一个对象实例 person,只要是对象他就有一个 __proto__ (指向上面这个原型)
所以我这个 person 对象就可以使用这个原型身上的一些属性和方法了,如果这个原型里面没有这些属性和方法,它就会接着往上一层去找(因为 prototype 也是对象,只要是对象就有一个 __proto__ 指向了更上一级,此时找到最大的对象 Object 的原型)
由于 Object.prototype 也是一个对象,那这个对象里面也有 __proto__ ,所以再往上面找,这时候发现已经没有了 所以就返回了 null。
通过 __proto__ 一层层的去找原型,当前原型身上没有 我再到更高一级上面的这个原型身上去找,如果还没有找到再往上照,直到返回结果或 null 为止,那这条线路就称之为 原型链。
总结:
对象都有一个 proto 属性,这个属性指向它的原型对象,原型对象也是对象,也有 proto 属性 指向原型对象的原型对象,这样一层层形成的**链式结构称为原型链,**最顶层找不到则返回null。

