抽象点,万物皆对象(js作为一个弱类型的脚本语言,在语言设计之处就定下万物皆对象来支撑js的一系列特性,也方便了低级语言来解释运行js(null除外)。在js的世界里也不例外,一切皆对象。面向对象的程序(OOP)的基本思想是:用虚拟对象去构建现实世界的模型,简化对象的概念,提供出对象的功能(api),以供人们去使用访问。
对象具有属性proto,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法。
在其他面向对象语言如java, 用class的概念去描述一个对象,但是在js中,class并不完全是一个对象,跟像是一个对象的模板。
当一个对象需要从class中创建出来时,class的构造函数就会运行创建这个实例,这种创建对象的过程就是
实例化对象
。js常被描述成一种基于原型的语言,即每一个对象拥有一个原型方法。对象以其为原型为模板、从原型继承方法和属性。原型对象也可能有原型,并从中继承方法和属性,一层层以此类推。这种关系被称为
原型链
。实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是自己本地的,另一种继承原型(prototype)的。所有的实例对象共享同一个prototype对象,那么从外界看起来,prototype对象就好像是实例对象的原型,而实例对象则好像"继承"了prototype对象一样,
这一点参考阮大神的JavaScript继承机制的设计思想。原型的作用是共享数据节省空间
,大多数情况下,proto可以理解为“构造器的原型”,即proto===constructor.prototype,但是通过 Object.create()创建的对象有可能不是.
总结
原型对象/构造函数/实例
- 原型对象:构造函数的prototype属性指向的对象
- 构造函数: 创建对象的一种方式(函数对象)
- 实例:构造函数创建出来的一个对象
- constructor: 一个属性,仅对象独有,指向构造函数
- _ proto_: 一个隐式属性,函数和对象都有,指向该函数/对象的原型对象
prototype可以给给函数 添加共享(继承)方法、属性,而_proto_是查找某函数或者对象的原型链的方式
原型链
- 属性查找:从实例本身一层层向上查找,直到访问到对象的原型。
- 属性修改:只会修改实例对象本身的属性,如果不存在,则进行添加该属性,如果需要修改该原型的属性时,则可以用例如 Vue.prototype.xxx = xxx; 但是这样会造成所有继承Vue的实例属性发生改变。