new运算符

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象类型之一。

语法

new constructor[([arguments])]

参数

构造函数(constructor)
一个指定对象实例的类型的函数。
传参(arguments)
一个用来被构造函数调用的参数列表。

描述

创建一个用户自定义的对象需要两步:

  1. 定义构造函数。
  2. 通过new来创建对象实例。

创建一个对象类型需要创建一个指定了名称和属性的函数;其中这些属性可以指向它本身,也可以指向其他对象,看下面的例子:

当代码 new foo(...) 执行时:

  1. 一个新对象被创建。它继承自foo.prototype.
  2. 构造函数 foo 被执行。执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新实例。new foo 等同于 new foo(), 只能用在不传递任何参数的情况。
  3. 如果构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象。(一般情况下构造函数不返回任何值,不过用户如果想覆盖这个返回值,可以自己选择返回一个普通对象来覆盖。当然,返回数组也会覆盖,因为数组也是对象。)

任何情况下都可以对任意一个对象添加新的属性,比如 car1.color = "black" 这句代码给car1添加了一个新的属性color , 然后给这个属性赋值 "black"。然而,这个操作不会影响任何其他对象。如果想给所有同样类型的对象添加属性,你需要给Car这个对象类型来添加属性。

你可以通过给 Function.prototype 添加属性的方式来给所有先前定义的实例来添加属性。这种定义属性的方式会影响到所有通过new构造函数创建的对象,因为它们共享了这个对象类型。下面的代码给实例car的对象类型添加了一个color属性null,然后又给实例car1覆盖了color属性'black',详见 prototype.

function Car() {}
car1 = new Car()
console.log(car1.color)           // undefined
Car.prototype.color = null
console.log(car1.color)           // null
car1.color = "black"
console.log(car1.color)           // black

例子

例1:对象类型和对象实例

假设你要创建一个汽车的对象类型。你希望这个类型叫做car,这个类型具备make, model, year等属性,要做到这些,你需要这样来写个构造函数:

function car(make, model, year) {
   this.make = make;
   this.model = model;
   this.year = year;
}

现在,你可以创建一个实例:

var mycar = new car("Eagle", "Talon TSi", 1993);

这段代码创建一个mycar这个对象实例,还给它赋予3个属性,现在mycar.make等于"Eagle", mycar.year 等于1993,以此类推。

你已经可以通过new来创建任意个汽车对象实例:

var kenscar = new car("Nissan", "300ZX", 1992);

例2: 对象属性为自身或其他对象

假设你定义了一个对象叫做person

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

然后定义了两个实例:

var rand = new Person("Rand McNally", 33, "M");
var ken = new Person("Ken Jones", 39, "M");

然后你重写了car的定义,添加了一个owner属性来指向一个person对象实例:

function Car(make, model, year, owner) {
   this.make = make;
   this.model = model;
   this.year = year;
   this.owner = owner;
}

创建实例变成了这样:

var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
var car2 = new Car("Nissan", "300ZX", 1992, ken);

上面的代码没有传字符串或数字过去,而是传了一个对象 randken ,这个时候可以这样来获取car2的拥有者的名称:

car2.owner.name

规范

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The new Operator
Standard  
ECMAScript 5.1 (ECMA-262)
The new Operator
Standard  
ECMAScript 3rd Edition (ECMA-262)
The new Operator
Standard  
ECMAScript 1st Edition (ECMA-262)
The new Operator
Standard Initial definition. Implemented in JavaScript 1.0.

浏览器兼容性

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Yes) (Yes) (Yes) (Yes) (Yes)
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support (Yes) (Yes) (Yes) (Yes) (Yes) (Yes)

相关链接

文档标签和贡献者