JS构造函数加new与不加new的区别?

前端面试的时候经常会被问到一个问题: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

猜你喜欢

转载自blog.csdn.net/a1059526327/article/details/110802553