new操作符里面到底发生了什么?

    function Person1(name) {
        this.name = name;
    }
    function Person2(name) {
        this.name = name;
        return this.name;
    }
    function Person3(name) {
        this.name = name;
        return new Array();
    }
    function Person4(name) {
        this.name = name;
        return new String(name);
    }
    function Person5(name) {
        this.name = name;
        return function() {};
    }
    
    
    var person1 = new Person1('xl');  // {name: 'xl'}
    var person2 = new Person2('xl');  // {name: 'xl'}
    var person3 = new Person3('xl');  // []
    var person4 = new Person4('xl');  // 'xl'
    var person5 = new Person5('xl');  // function() {}

请问new操作符里面到底发生了什么?特别是第2个例子

阅读 7.5k
4 个回答

new 的过程实际上分三步。
1,创建一个以这个函数为原型的空对象.
2,将函数的 prototype 赋值给对象的 __proto__ 属性
3,将对象作为函数的 this 传进去。如果有 return 出来东西是对象的话就直接返回 return 的内容,没有的话就返回创建的这个对象

写成代码就是如下:

function NewFunc(func){
    var ret = {};
    if (func.prototype !== null) {
        ret.__proto__ = func.prototype;
    }
    var ret1 = func.apply(ret, Array.prototype.slice.call(arguments, 1));
    if ((typeof ret1 === "object" || typeof ret1 === "function") && ret1 !== null)               
    {
        return ret1;
    }
    return ret;
}
function Person1(name) {
    this.name = name;
    //默认return this
}
function Person2(name) {
    this.name = name;
    return this.name;
    //此构造函数得看name基本类型还是引用类型!基本类型->return this、引用类型->return this.name
    //楼主传入的name是字符串'x1',return this.name,这里this.name也是字符串,所以会忽略掉这个return并返回this引用的对象,由于你this.name = name这里给该对象添加了name属性,最终返回{name: 'x1'}
}
function Person3(name) {
    this.name = name;
    return new Array();
    //new Array()是引用类型,因此直接返回新创建的数组
}
function Person4(name) {
    this.name = name;
    return new String(name);
    //new String(),这里用了String包装函数,也会返回引用类型,因此返回new String(name)的结果
    //楼主的代码我复制测试了一遍,会返回String{xxx:xxx……}的,是否有看错呢
}
function Person5(name) {
    this.name = name;
    return function() {};
    //function(){}也是引用类型,你懂的……
}

new Fun()会进行几个步骤:
1、创建一个空对象,并且 this 引用该对象,同时还继承了该函数的原型。
2、this.name 这种属性和方法被加入到 this 引用的对象中。
3、该函数有return,如果有,但是返回值是基本类型(Number,String,Boolean,undefined,null)时,会忽略掉此return并返回this(this引用的对象),如果返回值是引用类型(对象),则返回该对象,this会被忽略
4、该函数没有return,则默认返回this引用的对象

//new操作符下, 如果构造函数返回一个基本类型的话( 如string), 那么则返回构造函数生成的对象。
function Person2(name) {
    this.name = name;
    //console.log(typeof this.name) 返回string
    return this.name;
    //返回基本类型 则返回构造函数生成的对象
}
//等价于
function Person2(name) {
    this.name = name;
    return 'string';
}
var person2 = new Person2('xl'); // {name: 'xl'}
//new操作符下, 如果构造函数返回一个对象的话( 如数组, 函数), 那么则返回对象。
function Person3(name) {
    this.name = name;
    return new Array();
}

function Person4(name) {
    this.name = name;
    return new String(name);
}

function Person5(name) {
    this.name = name;
    return function() {};
}
//均返回对象。
function Person6(name) {
    this.name = name;
    return [];
}
var person6 = new Person6('xl'); // []

不同语言不同,大部分都是分配新的符号空间信息。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏