构造函数

一、定义构造函数

Constructors 是创建对象的函数。

函数给这个新对象定义属性和行为。 可将它们视为创建的新对象的蓝图。

1
2
3
4
5
function Bird() {
  this.name = "Albert";
  this.color = "blue";
  this.numLegs = 2;
}

这个构造函数定义了一个 Bird 对象,

其属性 name、color 和 numLegs 的值分别被设置为 Albert、blue 和 2。

构造函数遵循一些惯例规则

  • 构造函数函数名的首字母大写,这是为了方便我们区分构造函数( constructors)和其他非构造函数。

  • 构造函数使用 this 关键字 来给它将创建的这个对象设置新的属性。
    在构造函数里面,this 指向的就是它新创建的这个对象。

  • 构造函数定义了属性和行为就可创建对象,而不是像其他函数一样需要设置返回值。


二、使用构造函数创建对象

1
2
3
4
5
6
7
function Bird() {
  this.name = "Albert";
  this.color  = "blue";
  this.numLegs = 2;
}

let blueBird = new Bird();

注意: 构造函数内的 this 总是指被创建的对象

注意: 通过构造函数创建对象的时候要使用 new 操作符
因为只有这样,JavaScript 才知道要给 Bird 这个构造函数创建一个新的实例:blueBird。
如果不使用 new 操作符来新建对象,那么构造函数里面的 this 就无法指向新创建的这个对象实例,从而产生不可预见的错误。
现在 blueBird 这个实例就继承了Bird 构造函数的所有属性,

由构造函数创建的实例也和其他对象一样,它的属性可以被访问和修改:

1
2
3
4
5
6
blueBird.name; // Albert
blueBird.color; // blue
blueBird.numLegs; // 2

blueBird.name = 'Elvira';
blueBird.name; // Elvira

三、扩展构造函数以接收参数

注意到没有:所有通过Bird 构造函数创建出来的实例 Birds 都自动的取名为 Albert,颜色都是蓝色,还都有两条腿。

如果想要新创建出来的小鸟们拥有不同的名字和颜色要怎么办呢?

当然,手动的去修改每一个小鸟实例自己的属性也是可以实现的,只是会增加很多无谓的工作量

1
2
3
let swan = new Bird();
swan.name = "Carlos";
swan.color = "white";

假如写了一个程序来追踪一个鸟舍里面的几百只甚至几千只不同的小鸟。

将会花费很多时间去创建所有的小鸟实例并给它们的属性一一修改为不同的值。

为了减轻创建不同 Bird 对象的工作量,可以给你的 Bird 设置为可以接收参数的构造函数

1
2
3
4
5
function Bird(name, color) {
  this.name = name;
  this.color = color;
  this.numLegs = 2;
}

然后将值通过参数的方式传递给 Bird 构造函数来定义每一个唯一的小鸟实例:

1
let cardinal = new Bird("Bruce", "red"); 

这给 Bird 的 name 和 color 属性分别赋值为 Bruce 和 red 色。

但 numLegs 属性仍然设置为 2。 cardinal 有以下这些属性:

1
2
3
cardinal.name // Bruce
cardinal.color // red
cardinal.numLegs // 2

这样一来构造函数就变得很灵活了。

现在可以在创建每个 Bird 实例时直接定义属性,这是 JavaScript 构造函数非常实用的用法之一。

它们根据共同或相似的属性和行为将对象归纳为一组,并能够自动的创建各自实例。


四、使用 instanceof 验证对象的构造函数

凡是通过构造函数创建出的新对象,这个对象都叫做这个构造函数的 instance

JavaScript 提供了一种很简便的方法来验证这个事实,那就是通过 instanceof 操作符

instanceof 允许将对象构造函数之间进行比较,根据对象是否由这个构造函数创建的返回 true 或者 false

1
2
3
4
5
6
7
8
9
let Bird = function(name, color) {
  this.name = name;
  this.color = color;
  this.numLegs = 2;
}

let crow = new Bird("Alexis", "black");

crow instanceof Bird; // true

如果一个对象不是使用构造函数创建的,那么 instanceof 将会验证这个对象不是构造函数的实例:

1
2
3
4
5
6
7
let canary = {
  name: "Mildred",
  color: "Yellow",
  numLegs: 2
};

canary instanceof Bird; // false

总结

构造函数可以传参,比字面量对象灵活