前端之旅:《JS高级编程》第6章 学习笔记

差不多用了一周时间才完成了第6章,感觉大脑开启了暴力模式

6.面向对象

属性

ES中有两种属性:数据属性和访问器属性

  • 数据属性有4个描述其行为的特性:
    • Configurable
    • Enumerable
    • Writable
    • Value
  • 访问器属性也有4个特性:
    • Configurable
    • Enumberable
    • Get
    • Set

ES5提供了Object.defineProperty()方法来修改属性默认的特性,Object.defineProperties()方法可以通过描述符一次定义多个属性,Object.getOwnPropertyDescriptor()方法可以获取给定属性的描述符。

创建对象

  • 工厂模式:在函数里面创建对象并初始化属性和方法,然后返回对象,创建对象直接调用函数即可。
  • 构造函数模式:将利用函数是对象的本质,在函数内直接对this进行初始化。缺点是对象的方法没有达到复用的目的
  • 原型模式:为了达到复用的目的,将对象属性和方法放进对象原型(object.prototype)中,这样每个对象就共享了属性和方法,而且每个实例可以定义自己专属的属性和方法,且会覆盖原型中的同名属性和方法。注意使用对象字面量语法会重写object.prototype,相当于是使用新对象覆盖了原型对象,导致某些引用关系丢失。这种模式的缺点是对原型对象中的引用类型的操作会共享给所有实例。
    利用原型对象可以为原生对象添加新方法或重写
  • 组合构造函数模式和原型模式:对不需要共享的属性或方法用构造函数来定义,需要共享的属性或方法写进原型对象(推荐)
  • 动态原型模式:和组合模式类似,只是它把所有信息封装在构造函数中,也在构造函数初始化原型(经检查有必要时)
  • 寄生构造函数模式:和工厂模式类似,只是在创建对象时不是直接调用函数,而是使用new关键字
  • 稳妥构造函数模式:和寄生模式类似,区别在:一是没有公共属性, 新创建对象的实例方法不引用this,二是不使用new操作符调用构造函数(这一点又和工厂模式类似)

一些有关的方法:

  • isPrototype()方法可以确定一个对象实例的原型,Object.getPrototypeOf()返回一个对象的原型
  • delete 操作符可以删除实例中定义的属性和方法。
  • in 操作符用来确认是否能够访问指定对象的指定属性
  • ES5中的Object.keys()可以获取对象上所有可枚举的实例属性,而Object.getOwnPropertyNames()方法可以获取所有实例属性,无论它是否可枚举

继承

  • 原型链:使用要继承自的父类型的实例覆盖子类型的原型。所有函数的默认原型都是Object的实例。该种继承方法的缺点:一是父类型的实例属性顺理成章的成了现在对象的原型属性;二是在创建子类型实例时,不能向父类型构造函数传递参数
  • 借用构造函数:方法是在子类型的构造函数内部调用父类型构造函数(用apply或call方法),这下可以传递参数了,但没有解决函数复用的问题,而且父类型的原型对象中的方法对子类型不可见。
  • 组合继承:将原型链和借用构造函数的技术组合到一块,其背后的思想是使用原型链实现对原型属性和方法的继承。其缺点是在构造函数中和用实例覆盖子类型的原型对象的过程中,调用了2次父类型的构造函数,导致父类型的实例属性有2份,1份在子类型原型对象中,1份在子类型实例中。
  • 原型式继承:它的实现思路是在函数内借助给定的参数(对象)覆盖函数中一个全新的对象的原型,然后返回这个全新的对象,利用该函数实现了继承,每个实例都可以对自己的属性和方法进行自定义。这个技术和原型继承的思路差不多,用对象实例去重写子类型的原型,只是它把步骤放到了函数里面,并且是返回了一个被更改过原型的空白对象。
    ES5的Object.create()方法规范化了原型式继承,它用来创建并返回一个继承后的子对象。
  • 寄生式继承:是和原型式继承紧密相关的一种方式,但是原型式继承返回的子类型没有任何自定义的属性和方法,所以寄生式继承是完成了二次封装,用来完善子类型的属性和方法。思路是创建一个函数,在函数中调用原型式继承中封装的步骤,然后定义子类型中应有的属性和方法。但是也没有解决方法复用的问题,相当于每个实例中都有一份自己的方法
  • 寄生组合式继承:通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。基本思路是:不必为了指定子类型的原型而调用父类型的构造函数,我们需要的只是父类型的原型对象的一个副本而已。只是利用一个中间对象的实例覆盖了子类型的原型对象,而在子类型的构造函数中又调用父类型构造函数以达到继承属性的目的。(最常用最常用)

有关方法:

  • instanceof 操作符可以测试实例与原型链中出现过的构造函数。isPrototypeOf()测试调用该方法的原型是否是这个实例(参数)的原型
avatar

神无

舍悟离迷,六尘不改。