原型
历史原因
如果是一种简单的脚本语言,并不需要继承机制
但是js里面都是对象(万物皆对象),所以必须有一种机制,将对象全部联系起来
所以,Brendan Eich最后还是设计了继承,并借鉴了c++和java使用new命令生成实例
new构造函数生成的实例对象有一个缺点,无法共享属性和方法
所以引入了prototype属性,对象一旦创建,就会自动引入prototype的属性和方法
原型
MDN上解释:
- 当谈到继承时,JavaScript 只有一种结构:对象。
- 每个对象(object)都有一个私有属性(proto)指向另一个名为原型(prototype)的对象。
- 原型对象也有一个自己的原型,层层向上直到一个对象的原型为 null。
- 根据定义,null 没有原型,并作为这个原型链(prototype chain)中的最后一个环节。
原型就是给其他对象提供共享属性的对象
从数据结构的角度看,他就是一个单向链表
proto 访问的是隐式原型
prototype访问的是显示原型
原型链
当我们访问属性或方法时,先从自身查找,自身找不到则通过对象的__proto__属性一层 一层向上查找,直到找到Object的prototype为止,所构成的链式结构称为原型链
这里有一点需要注意的是,每个函数都有一个prototype属性,这个prototype的constructor指向这个函数
对象是怎么来的
本质上都是new出来的
对象字面量的写法:const obj = {}
是new Object()
的语法糖
还有,要搞懂,函数本质上就是可以被调用的对象
js的每个函数都有一个 prototype 属性,他指向原型对象;
每个对象都有一个 [[Prototype]] 属性,他也指向原型对象
两个特殊的对象null&Function
原型链末端的null,js引擎在处理的时候,会将其直接放到内存中
Function构造函数也是,所有的函数都来源于此,Function也会被js引擎直接放到内存中
并且它的隐式原型指向自身的显示原型
即Function.proto === Function.prototype