一、定义
new运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例
function Car(color) {
this.color = color
}
Car.prototype.start = function() {
console.log(this.color + "car start");
}
var car = new Car("black")
console.log(car.color);//black 访问构造函数中的属性
car.start();//blackcar start 访问原型中的属性
以上代码可以看出new创建的实例有以下两个特性:
1、访问到构造函数里的属性
2、访问到原型链中的属性
二、注意点
ES6新增Symbol类型,不可以使用new Symbol(),因为symbol是基本的数据类型,每个从Symbol()返回的symbol值都是唯一的
Number("123"); // 123
String(123); // "123"
Boolean(123); // true
Symbol(123); // Symbol(123)
new Number("123"); // Number {123}
new String(123); // String {"123"}
new Boolean(true); // Boolean {true}
new Symbol(123); // Symbol is not a constructor
三、模拟实现
(1)new操作符会进行如下操作
a、创建一个空的简单的JavaScript对象
b、为步骤a新创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象
c、将步骤a新创建的对象作为this的上下文
d、如果该函数没有返回对象,则返回this
(2)以new Foo()执行时为例子,再次分析
a、一个继承自Foo.prototype的新对象被创建
b、使用指定的参数调用构造函数Foo,并将this绑定到新创建的对象上。new Foo等同于 new Foo(),也就是没有指定参数列表,Foo不带任何参数调用的情况
c、由构造函数返回的对象就是 new 表达式的结果。如果构造函数没有显式的返回一个对象,则使用步骤1创建的对象
(3)版本one
new 是关键词,不可以直接覆盖。这里使用create来模拟实现new的效果
new 返回一个新对象,通过obj.__proto__
= Con.prototype继承构造函数的原型,同时通过Con.apply(obj,arguments)调用构造函数实现继承,获取构造函数上的属性
function create() {
//创建一个新对象
var obj = new Object()
//获得构造函数,arguments中去除一个参数
let Con = [].shift.call(arguments)
//链接到原型,obj可以访问到构造函数原型中的属性
obj.__proto__ = Con.prototype
//绑定this实现继承,obj可以访问到构造函数中的属性
Con.apply(obj,arguments); //把Con的this用obj来代替
//返回对象
return obj
}
function Car(color) {
this.color = color
}
Car.prototype.start = function() {
console.log(this.color + "car start");
}
var car = create(Car,"black")
car.color
car.start()//blackcar start
(4)版本two
解决上述构造函数返回值的问题
构造函数的返回值有如下三种情况:
a、返回一个对象
b、没有return,即返回undefuned
c、返回undefined以外的基本类型
a、返回一个对象: 实例中的car只能访问到返回对象中的属性
function Car(color,name) {
this.color = color
return {
name : name
}
}
var car = new Car("black","BNM")
console.log(car.color);//undefined
console.log(car.name);//BNM
b、没有return,即返回undefined: 实例中的car只能访问到构造函数中的属性,与情况a刚好相反
function Car(color,name) {
this.color = color
}
var car = new Car("black","BMN")
console.log(car.color);//black
console.log(car.name);//undefined
c、返回undefined以为的基本类型: 实例car中只能访问到构造函数中的属性,和情况a刚好相反,结果相当于没有返回值
function Car(color,name) {
this.color = color
return 1
}
var car = new Car("black","BMN")
console.log(car.color);//black
console.log(car.name);//undefined
结合以上,我们第二版需要判断返回值是不是一个对象,如果是对象返回这个对象,不然返回新创建的obj对象
function create() {
//创建一个空的对象
var obj = new Object()
//将构造函数返回出来,并将新对象的__proto__链到构造函数的原型对象上
var Con = [].shift.call(arguments)
obj.__proto__ = Con.prototype
//绑定this实现继承,obj可以访问到构造函数中的属性
var ret = Con.apply(obj,arguments)
//优先返回构造函数返回的对象
return ret instanceof Object ? ret : obj
}