theydy / notebook

记录读书笔记 + 知识整理,vuepress 迁移中 https://theydy.github.io/notebook/
0 stars 0 forks source link

JavaScript 面向对象 #4

Open theydy opened 5 years ago

theydy commented 5 years ago

JavaScript 面向对象

JavaScript 中类的实现

JS 中类的实现有两种方式。

  1. 构造函数模拟类
function A () {
  this.name = 'name';
}
  1. ES6 Class 关键字
class A () {
  constructor () {
    this.name = 'name';
  }
}

创建对象的3种方法

  1. 字面量创建
var o1 = {name: '01'};
  1. new 调用构造函数创建
var o2 = new A();
  1. Object.create 方法创建
var o3 = Object.create(A);

实现new 运算符

var thisNew = function (func) {
  var o = Object.create(func.prototype);
  // 创建一个继承至func.prototype 的新对象 o
  var k = func.call(o);
  // 执行构造函数,把执行时的this 指向新对象 o。
  if (typeof k === 'object') {
    o = k;
  }
  // 如果构造函数返回的是一个对象,这个对象会取代新对象 o。
  return o;
}

实现继承的 5 种方式

构造函数实现继承
function A () {}

function B () {
  A.call(this);
}

优点:可以实现多继承

缺点:只继承了父类在构造函数中的属性,无法继承父类原型上的方法

原型链实现继承
function A () {}

function B () {}

B.prototype = new A();
B.prototype.constructor = B;

优点:可以继承父类的属性和方法

缺点:无法实现多继承;如果父类的属性是引用类型的,一个子类改变这个引用类型,所有的子类都会改变

组合继承
function A () {}

function B () {
  A.call(this);
}

B.prototype = new A();
B.prototype.constructor = B;

组合继承由构造函数继承和原型链继承组合实现

寄生组合继承
function A () {}

function B () {
  A.call(this)
}

B.prototype = Object.create(A.prototype)
B.prototype.constructor = B

寄生组合继承其实就是组合继承的优化

ES6 class extends 关键字继承

class A {
  constructor () {}
}

class B extends A {
  constructor () {
    super(this)
  }
}

ES5/ES6 的继承除了写法以外还有什么区别

  1. class 声明内部会启用严格模式
  2. class 的所有方法都不可枚举
  3. class 的所有方法都没有原型对象 prototype
  4. class 必须使用 new 调用