在ES6之前,并没有引入类的概念;所以对象不是基于类进行创建的,而实通过构造函数(一种特殊的函数)来定义对象和它们的特征;
创建对象的三种方式:
- 对象字面量
var person = {name:'',age:''}
-
new Object({})
-
自定义构造函数,用来初始化对象,即为对象成员变量赋值,与new操作符一起使用。
- new在内存中创建一个新的空对象
- 让this指向这个对象
- 执行构造函数里的代码,给这个新的对象添加属性和方法
- 返回这个新的对象(所以构造函数里不用return返回对象,因为new操作符已经完成了这个动作)
对象中的实例成员和静态成员:
- 静态成员,在构造函数本身上添加的成员,只能通过构造函数访问
- 实例成员,只能通过实例化的对象来访问
构造函数中存在的浪费内存问题:不同实例对象中的函数,都会各自开辟一片内存空间来保存,但实际上,这个函数是一样的,开辟内存会浪费时间,也会浪费内存空间,可以通过原型对象解决。
- 每一个构造函数都有一个特殊的属性--prototype,指向另一个对象(原型对象),而这个对象的所有属性和方法都会被构造函数所拥有;--可以把不变的方法定义对原型对象上,这样所有的实例对象都可以共享这个方法,从而实现节省内存的目的!
- 那么实例化对象是如何访问到原型对象中的属性和方法的?----系统会在实例对象身上自动添加一个属性__proto__(称为对象原型),指向构造函数中的原型对象prototype;(实际上两者等价)只要是对象,就会有__proto__属性,指向其原型对象(Object的prototype原型对象的原型为null)
- 原型对象(对象原型)的一个属性constructor:指向对象的构造函数,也可以通过这个属性修改对象的构造函数
- 构造函数中和构造函数的原型对象中的this,指向的都是实例对象;
- 原型链的查找规则:(对象成员的查找机制)
- 当访问一个对象的属性或方法时,首先查找这个对象本身有没有这个属性;
- 若没有,则查找它的原型;(也就是实例对象的__proto__指向的原型对象prototype)
- 若没有,则查找原型对象的原型(Object的原型对象)
- 依次类推,一直找到Object原型对象的原型为止(null)
- (就近原则应用属性)
- 当访问一个对象的属性或方法时,首先查找这个对象本身有没有这个属性;