1

new命令

new作用

作用是执行构造函数,返回实例对象
function F() {
    this.name = "object"
}
var obj = new F();

上面例子是自定义一个构造函数,其最大的特点就是首字母大写,用new执行构造函数;
其中this,在new的执行下,代表了实例化后的对象,这个obj也就有name属性
注意点:如果不用new执行构造函数,那么this指向的是全局window

function F() {
    this.name = "object"
}
var obj = F();
console.log(obj);     //undefined
console.log(name);    //object

有两种方式可以避免:

  • 内部定义严格模式,当this为undefined时,添加属性会报错
function F() {
    this.name = "object"
}
F();
//TypeError: Cannot set property 'name' of undefined
  • 加个判断机制
function F() {
    if(!(this instanceof F)){
        return new F();
    }
    this.name = "object"
}
F();
  • 用new.target来判断,在没有用new执行时new.target返回undefined,new执行下返回构造函数自身
function F() {
    if(!new.target){
        return new F();
    }
    this.name = "object"
}
F();

简单来说:不加new执行,this就是window;加了new执行,那么this = Object.create(F.prototype),构建一个空对象,继承下F的原型

  • 当构造函数内部有return时,需要分情况执行
  • return的内容不是对象,则忽视,返回的时this对象

    function F() {
        this.name = "object"
        reutrn 123;
    }
    var obj = F();   //{name : "object"}
  • return的内容是对象时,则返回return的对象,(null除外)

    function F() {
        this.name = "object"
        reutrn {a : 123};
    }
    var obj = F();   //{a : 123}

new的原理

前提是使用了new来执行构造函数
  • 创建一个空对象,作为对象实例来返回
  • 将空对象的原型链指向构造函数的prototype
  • 将空对象赋值给构造函数内部的this,(this = Object.create(F.prototype))
  • 执行构造函数内部代码,若return没有返回新对象(null除外),则返回this对象

利用上述原理我们可以简单模拟一个new的函数

        function _new(constructor, params) {
            //将arguments对象转为数组
            var args = [].slice.call(arguments);
            //1.取出参数中的构造函数,2.过滤args,剩下对构造函数有用的实参
            var constructor = args.shift();
            //构建空对象,并继承构造函数的原型
            var context = Object.create(constructor.prototype);
            //1.借用构造函数,将context空对象赋给this,2.并args实参与构造函数参数一一对应对其赋值,3.形成完整的this对象
            var result = constructor.apply(context, args);
            //这个是处理return返回对象时的情况
            return (typeof result === "object" && result != null) ? result : context;
        }
        function P(n) {
            var a = 1;
            this.b = n;
            //return null;
        }
        var p = _new(P,123);
        console.log(p);

Infinity
293 声望9 粉丝

学前端中,只想激情优雅的写代码