原型与继承
1. 初识原型
let arr = ['yuanxing']
console.log(arr) // Array(1)
console.log(arr.__proto__) // Array(0)
console.log(arr.__proto__.__proto__) // Object
let obj = {}
console.log(obj) // Object
console.log(obj.__proto__) // Object
从以上的输出结果可以看出,我们通过字面量定义的数组 arrr 的 __proto__是数组的方法,而再一次打印__proto__则得到 Object。
我们通过字面量定义的空数组,它的__proto__为 Object
2. 原型对象
每个对象都有一个原型 prototype对象,通过函数创建的对象也将拥有这些原型对象。原型是一个指向对象的指针。
- 可以将原型理解为对象的父亲,对象从原型对象继承过来属性
- 原型就是对象除了是某个对象的父母外并没有什么特别之处
- 所有函数的原型默认是Object的实例,所以可以使用 toString/toValues/isPrototypeOf 等方法
- 使用原型对象为多个对象共享属性和方法
- 如果对象本身不存在的属性和方法将到原型上查找
- 使用原型可以解决:通过构建函数创建对象时复制多个函数造成的内存占用问题
- 原型包含 constructor 属性,指向构造函数
- 对象包含 proto 指向他的原型对象
下例使用的就是数组原型对象的 concat 方法完成的连接操作
let arr = ["a",b"];
console.log(arr.concat("c"));
默认情况下创建的对象都有原型
3. 对象方法和原型方法的优先级
let obj = {
show() {
console.log('我是对象自己拥有的方法show')
},
render() {
console.log('我是对象自己拥有的方法render')
},
}
obj.__proto__.show = function () {
console.log('我是原型里面的方法show')
}
obj.show()
obj.render()
console.log(obj)
console.dir(obj.__proto__)
程序的运行结果:
由运行结果可知对象 obj 里面定义的自己的方法优先级会比原型里面的方法优先级高。