概要
new运算符的作用是创建一个对象实例。这个对象可以是用户自定义的,也可以是带构造函数的一些系统自带的对象。
语法
new constructor[([arguments])]
参数
构造函数(constructor)- 一个指明了对象类型的函数。
传参(arguments)- 一个用来被构造函数调用的参数列表。
描述
创建一个用户自定义的对象需要两步:
- 定义构造函数。
- 通过new来创建对象实例。
创建一个对象类型需要创建一个指定了名称和属性的函数;其中这些属性可以指向它本身,也可以指向其他对象,看下面的例子:
当代码 new foo(...) 执行时:
- 一个新对象被创建。它继承自
foo.prototype. - 构造函数
foo被执行。执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新实例。new foo等同于new foo(), 只能用在不传递任何参数的情况。 - 如果构造函数返回了一个“对象”,那么这个对象会取代整个
new出来的结果。如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象,ps:一般情况下构造函数不返回任何值,不过用户如果想覆盖这个返回值,可以自己选择返回一个普通对象来覆盖。当然,返回数组也会覆盖,因为数组也是对象。
任何情况下都可以对任意一个对象添加新的属性,比如 car1.color = "black" 这句代码给car1添加了一个新的属性color , 然后给这个属性赋值 "black"。然而,这个操作不会影响任何其他对象。如果想给所有同样类型的对象添加属性,你需要给Car这个对象类型来添加属性。
你可以通过给 Function.prototype 添加属性的方式来给所有先前定义的实例来添加属性。这种定义属性的方式会影响到所有通过new构造函数创建的对象,因为它们共享了这个对象类型。下面的代码给实例car的对象类型添加了一个color属性null,然后又给实例car1覆盖了color属性'black',详见 prototype.
function Car() {}
car1 = new Car()
alert(car1.color) // undefined
Car.prototype.color = null
alert(car1.color) // null
car1.color = "black"
alert(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);
上面的代码没有传字符串或数字过去,而是传了一个对象 rand 和 ken ,这个时候可以这样来获取car2的拥有者的名称:
car2.owner.name
详解new function(){}和function(){}()
情景一:
var yx01 = new function() {return "圆心"};
alert(yx01);
我们运行情景一代码,将返回显示“[object object] ”,此时该代码等价于:
function 匿名类(){
return "圆心";
}
var yx01 = new 匿名类();
alert(yx01);
我们对情景一的代码进行下面改造:
var yx01 = new function() {return new String("圆心")};
alert(yx01);
我们运行,将会发现返回的是“圆心”,这是为什么呢?
只要 new 表达式之后的 constructor 返回(return)一个引用对象(数组,对象,函数等),都将覆盖new创建的匿名对象,如果返回(return)一个原始类型(无 return 时其实为 return 原始类型 undefined),那么就返回 new 创建的匿名对象。(谢谢 Lunatic_Sun ,描述更精准点)
由于 new String 会构造一个对象,而不是一个 string 直接量,且new String(x) 如果带参数,那么alert它的时候就会返回 x。所以 yx01 将返回 new String(“圆心”) 这个对象,而 alert yx01 则显示 “圆心”。
情景二:
var yx02 = function() {return "圆心"}();
alert(yx02);
我们运行情景二代码,将返回显示“圆心”,此时该代码等价于:
var 匿名函数 = function() {return "圆心"};
yx02 = 匿名函数();
alert(yx02);
很明显,yx02 返回的是匿名函数的执行结果值,即 yx02 为:“圆心”。
当然匿名函数的执行结果也可以为一个匿名对象。具体常见应用可以看《Javascript的一种模块模式》
浙公网安备 33010602011771号