对象的定义
无序属性的集合,其属性可以包含基本值、对象或函数。可以将对象想象成散列表,即一组名值对,值可以是数据或是函数
属性设置
采用Object.defineProperty() 方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性,并返回这个对象。
Object.defineProperty(obj, prop, descriptor)
- obj 需要定义属性的对象。
- prop 需被定义或修改的属性名。
- descriptor 需被定义或修改的属性的描述符。
属性主要分为两种: 数据属性和访问器属性
configurable: 当且仅当该属性的configurable为true时,该属性才能够被改变,也能够被删除,默认为false。
enumerable: 当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中,默认为false。
value: 该属性对应的值。可以是任何有效的JavaScript值(数值,对象,函数等),默认为undefined。
writable: 当且仅当该属性的writable为true时,该属性才能被赋值运算符改变,默认为false。
|
|
get: 一个给属性提供getter的方法,如果没有getter则为undefined。该方法返回值被用作属性值。默认为undefined。
set: 一个给属性提供setter的方法,如果没有setter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为undefined。
|
|
构造函数
调用构造函数会经历的四个步骤,此前在this的文章中已经讲过,这里再复习一下:
- 创建一个新的
对象
- 将构造函数的作用域赋给新对象(this就指向这个新对象了)
- 执行构造函数中的代码(添加属性)
- 返回新的对象
看下面的代码:
|
|
原型模式
使用构造函数模式,我们发现构造函数中的每个对象方法都要在实例上重新创造一遍,都new Function(),可用原型模式解决,它的好处在于可以让所有实例共享它包含的属性与方法.
与原型有关的重要方法
isPrototypeOf()
object1.isPrototypeOf(object2)
object1是否在object2的原型链中
Object.getPrototypeOf()(ES5)
Object.getPrototypeOf(object)
返回指定方法的原型
Object.prototype.hasOwnProperty()
obj.hasOwnProperty(prop)
用来判断某个对象是否含有指定的自身属性
in
in操作符可以单独使用或在for-in循环中使用,无论属性存在于实例还是原型中,但必须为可遍历的
Object.keys()(ES5)
返回一个由给定对象的所有可枚举自身属性的属性名组成的数组
Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor(obj, prop)
返回指定对象上一个自有属性对应的属性描述符
多个实例共享所保存的属性和方法的基本原理:当读取某个对象的某个属性时,都会进行一次搜索,先从本身实例开始,若在实例中找到改名字的属性,则返回,若没有找到,则继续搜索,指针指向原型对象,但是要注意,这样可能会产生实例对象屏蔽原型对象的情况发生.
|
|
重整原型函数,封装原型的功能,但会出现一些问题
|
|
解决方法:
|
|
继承
ECMAScript只支持实现继承,主要依靠原型链来完成
A需要继承B,既然A.prototype与B.prototype相连接
A.prototype = B.prototype 是完全错误,js是引用复制,后续扩展B.prototype对A产生影响
A.prototype = new B() 如果函数B有一些副作用,就会产生一些影响
`A.prototype = Object.create(B.prototype)` or ES6中,也可使用`Object.setPrototypeOf(A.prototype, B.prototype)`
|
|
如果Person函数中有赋值的变量,使用new Person()给Student的原型后就会发生共享,我们还需要借用构造函数来实现对实例对象的继承,即(寄生)组合继承模式,原型属性和方法通过原型链来继承,实例属性通过构造方法来继承:
|
|
总之原型链是这样的: 实例本身属性与方法(在构造函数中或自己定义赋值) -> 父类的原型属性与方法 -> 父类的父类的原型属性与方法 -> … -> object.prototype -> null。
除了本身的属性与方法外,其它都是要与其它实例共享的,如果改变原型链上的方法会影响其它实例,如果定义了与原型链一样的属性或方法,原型链上的方法将会被屏蔽。