前端面试的时候经常会被问到一个问题:new的过程中,发生了什么?
先来看js红宝书(js高级程序设计第三版)给出的答案:
1.创建一个空对象
2.将这个空对象的原型,指向构造函数的prototype属性,构造函数中的this指向这个空对象
3.开始执行内部的代码。
4.如果该函数没有返回对象,则返回this
很多人只是把它背下来,并没有真正的理解,不信的话看一下这个面试题:
填写"TO DO"处的内容让下面代码支持 a.name = "name1"; b.name = "name2"
;
function Obj(name){
// TO DO
}
obj. /* TO DO */ = "name2";
var a = Obj("name1");
var b = new Obj;
看到这个很多人一下就懵了,其实这个题目的本质也是对new本质的理解。
我们看一下有new和没有的new以及分别有无return的区别:
//没有new 没有return
function Obj1(name){
this.name = name;
}
var a = Obj1("name1");
console.log(a); // undefined "没有new 没有return"
//没有new 有return基本数据类型
function Obj2(name){
this.name = name;
return '123'
}
var b = Obj2("name2");
console.log(b); // 123
//没有new 有return复杂数据类型
function Obj3(name){
this.name = name;
return {a:1}
}
var c = Obj3("name3");
console.log(c); //{a: 1}
//有new 没有return
function Obj4(name){
this.name = name;
}
var d = new Obj4("name3");
console.log(d); //Obj4 {name: "name4"}
//有new 有return基本数据类型
function Obj5(name){
this.name = name;
return '123'
}
var e = new Obj5("name5");
console.log(e); //Obj5 {name: "name5"}
//有new 有return复杂数据类型
function Obj6(name){
this.name = name;
return {a:1}
}
var f = new Obj6("name6");
console.log(f); //{a: 1}
小结:
1. 没有new的构造函数就是一个普通函数,this指向的window,返回值就是构造函数的返回结果。并且不管return的是基本数据类型还是引用类型,都会原样返回。
2. 有new的构造函数,默认返回this,而this指向实例化的对象。并且如果return的是基本数据类型,那么忽视掉该return值,如果返回的是一个引用类型,那么返回该引用类型。
现在我们来看一下文章开头抛出问题的参考答案:
function obj(name){
if(this == window){
return {'name':name}
}
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj;
console.log(a.name) //name1
console.log(b.name) //name2