如何自己实现JavaScript中new.target的功能

如何自己实现JavaScript中new.target的功能

我现在还记得Douglas CrockfordJavaScript语言精粹提到过的:构造器函数,按照约定,它们保存在以大写格式命名的变量里。如果调用构造器函数时没有在前面加上new,可能会发生很糟糕的事情,既没有编译时警告,也没有运行时警告,所以大写约定非常重要。
我以前也在JavaScript——深入了解this中记录过在构造器调用时省略new关键字还可能会污染全局作用域

function Person(){
    
    
	this.personName = 'person';
}
let person = Person();
console.log('person.personName : '+person.personName);//Cannot read property 'personName' of undefined
console.log('window.personName : '+window.personName);//window.personName : person

还提出过蠢办法解决调用构造函数不用new关键字的:

function Person(){
    
    
	if(this === window){
    
    
        throw Error('You must use the new keyword.');
    }
	this.personName = 'person';
}
let person = Person();//You must use the new keyword.

改进版:

function Person(){
    
    
	let context;
    (function(){
    
    
        context = this;
    }())
    if(this === context){
    
    
        throw Error('You must use the new keyword.');
    }
	this.personName = 'person';
}
let person = Person();//You must use the new keyword.

改动一下倒是和今天的new.target有些相似:

function newTarget(){
    
    
    let context;
    (function(){
    
    
        context = this;
    }())
    return context === this ? undefined : this.constructor;
}

function Person(){
    
    
    console.log('newTarget : ' + newTarget.call(this));//newTarget : undefined
    console.log('new.target : ' + new.target);//new.target : undefined
}
Person();
//
function newTarget(){
    
    
    let context;
    (function(){
    
    
        context = this;
    }())
    return context === this ? undefined : this.constructor;
}

function Person(){
    
    
    console.log('newTarget : ' + newTarget.call(this));//newTarget : function Person(){xxx} 指向此函数的引用
    console.log('new.target : ' + new.target);//new.target : function Person(){xxx} 指向此函数的引用
}
new Person();

首先贴个图,浏览器支持情况:
来自MDN
在这里插入图片描述
首先,new.target关键字必须使用在function中,如果这个function是作为构造器函数调用,new.target指向这个构造器函数;如果这个function是个普通函数,new.target的值为undefined;箭头函数是没有new.target,但是它可以使用最近的外部函数的new.target。

new.target可以很好的解决掉调用构造器函数时没有在前面加上new的问题,但是每个构造器函数中都要加上判断,显然没有class用起来方便,并且这种new+构造器函数的组合也不推荐使用,所以我个人认为new.target很鸡肋(只是我个人目前的看法,如果以后发现其用处,再更新)

猜你喜欢

转载自blog.csdn.net/qq_35508835/article/details/108180209
今日推荐