能否不使用new运算符实例化ES6类?
ES6类能否实现无new实例化?
在普通JavaScript构造函数中,我们可以借助new.target实现不用new运算符也能实例化对象,示例代码如下:
function Person(name) { if (!new.target) { return new Person(name); } this.name = name; } let p1 = new Person("John"); let p2 = Person("Jack");
不管加不加new,都能正常创建Person实例。
但换成ES6类后,直接写类似逻辑会抛出TypeError: Class constructor Person cannot be invoked without 'new'错误,比如这段代码:
class Person { constructor(name) { if (!new.target) { return new Person(name); } this.name = name; } } let p2 = Person("Jack"); // 执行报错
这是因为ES6类的构造函数被设计为必须通过new调用——在进入构造函数代码执行前,JS引擎就会先检查调用方式,不符合要求就直接抛出错误,所以构造函数里的new.target判断根本没机会执行。
要实现ES6类的无new实例化,可以用以下两种简单方案:
方案一:添加静态创建方法
给类定义一个静态方法,专门用来处理无new的实例创建:
class Person { constructor(name) { this.name = name; } // 静态方法用于创建实例 static create(name) { return new Person(name); } } // 通过静态方法创建实例 let p2 = Person.create("Jack"); console.log(p2 instanceof Person); // 输出 true
方案二:用普通函数包裹类
写一个普通函数作为外层接口,拦截调用并自动用new创建类实例:
// 外层普通函数,处理无new调用 function Person(name) { return new _Person(name); } // 实际的ES6类 class _Person { constructor(name) { this.name = name; } } // 两种调用方式都生效 let p1 = new Person("John"); let p2 = Person("Jack"); console.log(p1 instanceof _Person); // 输出 true console.log(p2 instanceof _Person); // 输出 true
这两种方案都能实现类似普通构造函数的无new实例化效果,根据实际场景选择即可。
内容的提问来源于stack exchange,提问作者roman465
相关产品推荐
相关产品推荐

