JS高程知识点总结-6(面向对象)

一、对象的概念
1、js中对象:无序属性的集合,键值对,其内部属性(无法直接访问)有:数据属性和访问器属性;
数据属性的4个特性(描述符):
  [[Configurable]]:决定能否修改删除属性,默认true;
  [[Enumerable]]:决定是否可枚举(能否用for-in返回),默认true;
  [[Writable]]:属性值能否修改,默认true;
  [[Value]]:保存属性值,默认undefined;
 修改属性必须用Object.defineProperty()方法,接收三个参数:对象名,属性名,特性名称;
 Configurable只能修改一次;删除属性要使用delete(propertyName)方法;
访问器属性(不包含数据值,包含一对getter/setter函数),其4个特性(描述符):
  [[Configurable]]:决定能否修改删除属性,默认true;
  [[Enumerable]]:决定是否可枚举(能否用for-in返回),默认true;
  [[Get]]:读函数,默认undefined;
  [[Set]]:写函数,默认undefined;
 访问器属性必须用Object.defineProperty()方法定义(P141);
2、ES5定义多个属性的方法:Object.defineProperties(),接收两个对象,第一个是要修改和添加属性的对象,第二个是属性集合;
  注:在调用Object.defineProperty()和Object.defineProperties()方法时,
  如果不指定,那Configurable、Enumerable、Writable特性的值均默认为false;
3、获取属性描述符:Object.getOwnPropertyDescriptor()方法,接收两个参数,对象名和属性名,
  根据属性的类型(数据属性和访问器属性),获取其对应的描述符;

二、对象的定义
1、工厂模式:封装属性和方法接口,创建多个相似对象,缺点是,无法对知道生成的对象类型;
2、自定义构造函数模式:
  自定义构造函数(构造函数首字母必须大写,普通函数小写),用new操作符调用;缺点是每个方法在每个实例上都要创建一遍,即函数不能复用;
3、原型模式(P148):
 3.1、概念
    Person:构造函数;Person.prototype:原型对象;Person.prototype.constructor:指向Person;
   通过构造函数的prototype属性,在其原型对象上定义实例的信息;构造函数的prototype属性指向原型对象;
   原型对象自动获得constructor(构造函数)属性,指向构造函数,
   使用构造函数生成的实例具有[[Prototype]](_proto_)属性,指向构造函数的prototype属性(即原型对象);
   使用Person.prototype.isPrototypeOf(实例)方法来检测某个对象是否是实例的原型对象;
   ES5 使用Object.getPrototypeOf(实例)来获取实例的原型对象;
   使用hasOwnProperty()方法来检测属性是否存在于实例本身;
 3.2、in操作符:
   单独使用:不论是实例属性还是原型属性,均返回true;
   for-in:返回所有可枚举属性(包括原型和实例属性),包括屏蔽了原型中不可枚举属性的实例属性(IE8及之前版本不适用);
   ES5新增替换for-in方法:
      Object.keys():返回所有可枚举的实例属性;
      Object.getOwnPropertyNames():返回所有实例属性;
  默认情况下,原生constructor属性不可枚举;
4、现在默认使用自定义构造函数模式和原型模式组合的方式定义对象;构造函数用于定义实例属性,原型模式定义方法和共享的属性。
5、寄生构造函数模式:
   形式与工厂模式基本一致,不过其使用new操作符,并且包装函数使用的是构造函数;
   无返回值时默认返回新对象实例,在构造函数末尾加上return语句,可以重写返回值;
6、稳妥构造函数模式:
   不使用new操作符调用构造函数,构造函数内部不使用this;

三、继承
1、OO语言一般有两种继承:接口继承(继承方法签名)和实现继承(继承实际的方法),JS中函数没有签名,只支持实现继承,由原型链实现;
2、原型链:
   让一个构造函数的原型等于另一个对象的实例,则该原型也有_proto_属性,指向对应对象的原型,如此重复就形成了原型链,
3、原型链实现继承带来的两个问题:
  1、引用类型值带来的问题,超类型的实例属性由于原型链的存在变成了子类型的原型属性,从而被子类型的所有实例共享;
  2、创建子类型实例时,无法向超类型构造函数传递参数;
 所以,一般不单独使用原型链;
4、借用构造函数:在子类型构造函数的内部调用超类型构造函数(call()、apply()方法),可传参;解决上述两个问题;
  新引入的问题:导致方法都在构造函数中定义,无法实现函数复用;所以不常用这种方法;
5、组合继承
  用原型链实现对原型属性和方法的继承,用构造函数实现对实例属性的继承;使每个实例有自己的属性,并且实现函数复用;
6、原型式继续:基于一个对象创建新对象,传入的对象作为构造函数的原型,相当于对该对象做浅复制;
  ES5新增Object.create()方法实现原型式继承,接受两个参数:作为对象原型的对象(可选)和为新对象定义额外属性的对象;
  第二个参数与Object.defineProperties()的第二个参数的格式一致,每个属性都由其描述符定义的;
7、寄生式继承:
  创建封装继承过程的函数,将其复制给新对象(调用了实现原型式继承的函数),对新对象做增强(增加其属性和方法),然后返回新对象;
  这种方式存在的问题和构造函数模式一致,无法实现函数复用,效率低。
8、寄生组合式继承:
  组合继承是最常用的继承模式,但是这两种模式下,会两次调用超类型构造函数,第一次是创建子类型原型时;第二次是在子类型构造函数内部;

  因此衍生寄生组合式继承,借用构造函数来继承属性,通过原型链的混成形式来继承方法;

其实质就是在定义子类型原型时,采用寄生式继承方式,而不使用超类型的构造函数,










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值