sakila1012 / blog

记录自己学习工作中的心得
10 stars 3 forks source link

ES6 构造函数 constructor 理解 #34

Open sakila1012 opened 5 years ago

sakila1012 commented 5 years ago

写在前面

之前会遇到 construct,现在在 ES6 的 constructor 中,对其认识也很模糊。 ES6 中的构造函数详解,其实在 ES5 中已经有类似的实现了,只是在 ES6 中换了一种实现方式。

ES5

在 ES5 中会像下面这样定义构造函数并生成实例的。

function Person(p) {
  this.name = p.name;
  this.age = p.age;
}

Person.prototype.say = function () {
  console.log(this.name, this.age)
}

// 通过 new 来创建一个实例
var xiaoming = {
  name: '小明',
  age: 12
}

var xm = new Person(xiaoming);
xm.say();

image

ES6

ES6 就不用再像上面那样写了,让 JavaScript 更接近其他语言的写法。比如上面这个,用 ES6 的类写法就像下面这样。

class Person {
  constructor (p) {
    this.name = p.name;
    this.age = p.age;
  }
  say () {
    console.log(this,name, this.age);
  }
}

// 不过在创建实例时还是沿用了 ES5 的写法,也是通过 new 关键字来创建

var xiaoming = {
  name: '小明',
  age: 12
}

const xm = new Person(xiaoming);
xm.say();

image

这里返回的是对象,跟 ES5 中有点不一样。 构造函数中创建的变量,函数等完全地拷贝一份到实例中,也就是说每个实例都会拥有一份构造函数中的变量和方法。相当于深度拷贝一份。而放在构造函数外的变量或者方法只属于 Person 类。但通过 Person 类创建的实例并使用这些变量和方法,因为实例可以通过原型链来调用这些方法。

prototype 对象的 constructor 属性指向类本身。

console.log(Person.prorotype.constructor === Person); // true

类内部默认使用严格模式。

constructor 方法是类的默认方法,通过 new 命令生成对象实例时会自动调用这个方法,类必须有 constructor 方法,如果一个类没有显式定义构造函数,那么一个空的 constructor 方法会自动添加到类中。类的默认方法都定义在 prototype 对象上,我们可以把新的方法添加到 prototype 。通过 Object.assign 方法可以很方便地一次向类中添加多个方法。

class Person {
  constructor (p) {
    this.name = p.name;
    this.age = p.age;
  }
  say () {
    console.log(this,name, this.age);
  }
}

// 不过在创建实例时还是沿用了 ES5 的写法,也是通过 new 关键字来创建

var xiaoming = {
  name: '小明',
  age: 12
}

const xm = new Person(xiaoming);
xm.say();

Object.assign(Person.prototype, {
  changeName () {
    this.name = '李四';
    console.log(this.name);
  },
  changeAge () {
    this.age = 18;
    console.log(this.age)
  }
})

xm.changeName() // '李四'
xm.changeAge() // 18