一、如何理解面向对象
面向对象的语言有一个标志,即拥有类的概念,它可以抽象实例对象的公共属性与方法,基于类可以创建任意多个实例对象,一般具有封装、继承、多态的特性!但JS中对象与纯面向对象语言中的对象是不同的,ECMA标准定义JS中对象:无序属性的集合,其属性可以包含基本值、对象或者函数。可以简单理解为JS的对象是一组无序的值,其中的属性或方法都有一个名字,根据这个名字可以访问相映射的值(值可以是基本值/对象/方法)。
在类语言中,对象基于模板来创建,首先定义一个类作为对现实世界的抽象,然后由类来实例化对象;js(ES5)本身是没有class类型的,但是每个函数都有一个prototype
属性。prototype
指向一个对象,当函数作为构造函数时,prototype
则起到类似class
的作用。比如用原型模式创建对象,只需要在构造函数的原型上面定义属性和方法,那么所有实例都可以共享原型对象上的属性和方法,因为他们内部都有一个__proto__
属性,指向了原型对象。
二、如何理解原型和原型链
我们创建的每个函数都有一个prototype
属性,这个属性是一个指向原型对象指针,原型对象里包含着所有实例共享的属性和方法。同时原型对象里也有一个constructor
指回了其对应的构造函数。
每个对象实例都会在其内部初始化一个__proto__
属性,它是一个指向prototype
(原型对象)的指针,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会通过__proto__
去prototype
里找这个属性,这个prototype
又会有自己的__proto__
指向自己的原型对象, 于是就这样一直找下去,形成了原型链的概念。
原型链实现的是对属性的查找,一直顺着原型链查找到Object对象
,如果没查到返回undefined
,还有值得注意的一点就是,所有对象里的__proto__
都是对原型对象的一个引用,而不是副本,所以当我们修改原型时,与之相关的对象也会继承这一改变。