面向对象
对象的属性
数据属性:[[Configurable]](可否delete或修改属性特性)、[[Enumerable]](可否被for-in)、[[Writable]](可否修改)、[[Value]]
访问器属性: [[Configurable]]、[[Enumerable]]、[[Get]]、[[Set]],
修改属性: 使用Object.defineProperty( 对象,属性名,描述符对象 )来定义, 或者Object.defineProperties()一次定义多个 属性
读取属性特性:Object.getOwnPropertyDescriptor(对象,属性名),返回描述符对象
对象的创建
工厂模式:函数内new Object(),并为对象添加属性,并return该对象。缺点是无法知道对象类型
构造函数模式:函数内不显式地创建对象,直接将属性和方法赋值给this对象,不需return。这是因为new操作符帮忙完成了这些任务。new操作符调用构造函数会经过:var obj = new Object(),obj.__proto__=Fn.prototype,Fn.call(obj),return obj,这四个步骤,且对象的constructor属性会指向构造函数。缺点是每个实例相同方法内存空间没有复用。
原型模式:让实例共享属性和方法。每个函数都有prototype属性,每个对象(包括函数)都有__proto__属性指向它的构造函数的原型对象(instanceof 的判断依据),而原型和对象实例都有constructor属性指向构造函数。如下图:
但是最好不要用__proto__属性,可以用isPrototypeOf方法来判断原型是否是对象对应的原型,getPrototypeOf来获取对象的原型。对象属性的读顺序:先实例,后沿着原型链。不能修改原型中的属性。检测属性是否存在于实例而不是原型中:hasOwnProperty()。确定:无法传参。所以可以和构造函数结合使用。
寄生构造函数模式:工厂模式+new形式,构造函数中return对象会重写调用构造函数时返回的值,不能用instanceof。
稳妥构造函数模式:不用this和new,不能直接访问属性。
继承
函数的继承
原型链继承:SubType.prototype = new SuperType(),这时SubType的实例和原型的constructor属性都指向了SuperType,缺点是共享属性和不能传参
借用构造函数:function SubType(){SuperType.call(this,arguments);},缺点是无法函数复用
组合继承:两者结合,缺点是会调用两次超类型构造函数
寄生组合式继承:利用借用构造函数来继承属性,原型链继承方法。即把直接使用原型链继承的new改为,使用临时性没有属性的构造函数来指向超类型构造函数原型,再使用原型链继承来只继承构造函数的原型上的方法,而不重复继承超类型构造函数内定义的属性
对象的继承
原型式继承:function object(o){function F(){};F.prototype = o;return new F();}利用临时性构造函数,ES5使用Object.create()实现,参数是被继承的对象和新对象的描述符对象。
寄生式继承:利用函数封装继承过程并在内部增强对象。