一,对象的定义 Everything is object (万物皆对象) 对象是单个事物的抽象。 对象是一个容器,封装了属性(property)和方法(method) ECMAScript-262 把对象定义为:无序属性的集合,其属性可以包含基本值、对象或者函数 二,什么是面向对象 面向对象不是新的东西,它只是过程式代码的一种高度封装,目的在于提高代码的开发效率和可维护性。 面向对象编程 —— Object Oriented Programming,简称 OOP ,是一种编程开发思想。它将真实世界各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟。 三,面向对象的特征 1,封装 2,继承 3,多态 四,面向对象与面向过程 1,面向过程就是亲力亲为,事无巨细,面面俱到,步步紧跟,有条不紊 2,面向对象就是找一个对象,指挥得结果 面向对象将执行者转变成指挥者 面向对象不是面向过程的替代,而是面向过程的封装 五,创建对象的三种方法 字面量形式 系统构造函数Object 自定义构造函数 创建一个实例对象,必须使用 new 操作符。以这种方式调用构造函数会经历以下 4 个步骤: 创建一个新对象 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象) 执行构造函数中的代码 返回新对象 实例对象中的constructor属性 对象的 constructor 属性最初是用来标识对象类型的 可以通过实例的 constructor 属性判断实例和构造函数之间的关系 注意:这种方式不严谨,推荐使用 instanceof 操作符,后面学原型会解释为什么 六,对象的原型 内存浪费问题 使用构造函数带来的最大的好处就是创建对象更方便了,但是其本身也存在一个浪费内存的问题 对于每一个实例对象,如果我们在一个实例对象的内部创建一个属性,值为函数。假如创建两个对象,属性名也许一致,看似都是一模一样的内容,但是其实每一次生成一个实例,都会多占用一些内存,如果实例对象很多,会造成极大的内存浪费。为了解决内存浪费问题,引入原型 基本解决对象数据共享(把公用属性值定义在外部) Javascript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。 任何函数都具有一个 prototype 属性,该属性是一个对象。 构造函数的 prototype 对象默认都有一个 constructor 属性,指向 prototype 对象所在函数。 通过构造函数得到的实例对象内部会包含一个指向构造函数的 prototype 对象的指针 __proto__。 实例对象可以直接访问原型对象成员。 总结: 任何函数都具有一个 prototype 属性,该属性是一个对象 构造函数的 prototype 对象默认都有一个 constructor 属性,指向 prototype 对象所在函数 通过构造函数得到的实例对象内部会包含一个指向构造函数的 prototype 对象的指针 __proto__ 所有实例都直接或间接继承了原型对象的成员 为什么实例对象可以访问原型对象中的成员? 先在自己身上找,找到即返回 自己身上找不到,则沿着原型链向上查找,找到即返回 如果一直到原型链的末端还没有找到,则返回undefined 原生对象的原型即系统构造函数 Object.prototype Function.prototype Array.prototype String.prototype Number.prototype Date.prototype 利用自调用函数把局部变量变为全局变量 好处 1,避免变量污染 2,把对象暴露给window已提升 函数是有参数的,我们可以通过把window对象传入而解决