js 写自定义类,怎么可以使用 new Customer.Create(),这种方式创建类?

js 写自定义类,怎么可以使用 new Customer.Create(),这种方式创建类?

现在的方式是:
custom.js

export class Stage {
  constructor(name) {
        this.name = name
  }
  Create(){
    console.log(this.name)
  }
}

text.vue

import { Stage } from '@/untils/custom.js'

const stage = new Stage("stageName")

假如:想改上面的代码为下面这样调用,怎么写?

const stage = new Stage.Create({
  id: "stageName",
  ...
})
阅读 1.8k
3 个回答

不要乱用,已经有 Stage.create 就不需要 new 了。

简单来说可以这样:

custom.js

class Stage {

}
export default {
  create(params) {
    return new Stage(params);
  }
}

然后使用的地方:

import StageManager from './stage';

const myStage = StageManager.create({ ... });

并不清楚你的想要 new Stage.Create() 的目的是什么,但是很明显你的 Stage.Cretae 并不是一个 构造函数 或者 ,所以并不能这样用。

我个人理解是你想要使用 Object.create() 来创建一个实例,但是又想用 new 操作符。但 new 操作符 和 Object.create() 其实就是都是为了创建一个对象实例,并不能混用,实际使用中要么使用 new 要么使用 Object.create()
所以既然是想要使用 Class 的写法了,其实可以好好阅读一下阮一峰老师的ES6入门教程。

也有可能是你想实现 嵌套类/内部类,但其实嵌套类也并不能直接 new ClassA.ClassAB 的形式来创建。

相关阅读

new 运算符 - JavaScript | MDN
Object.create() - JavaScript | MDN
Class 的基本语法 - ECMAScript 6入门

不能对静态方法使用 new 运算符,会报 xxx is not a constructor 错误。我没找到对这个语法的明确说明,但试验如此。

从写法来看,应该是想写一个 create,通常这是工厂方法模式。一般情况下 create 的实际是直接调用,返回对象,代替使用 new 构造对象

export class Stage {
    constructor(name) {
        this.name = name;
    }

    static create(...args) {
        return new Stage(...args);
    }
}

const stage1 = Stage.create("stage one");

在 C#、Java 等语言中有内部类的概念,但是 JS 没有。不过 JS 的普通 function 是可以作为类使用的。

function Create(...args) {
    return new Stage(...args);
}

// 两种方式调用都可以
console.log(new Create("stage 2"));
console.log(Create("stage 3"));

接下来是奇迹发生的时刻

Stage.Create = Create;

console.log(new Stage.Create("stage 4"));
console.log(Stage.Create("stage 5"));

实验到此,但是不建议这么用。既然 JS 还不提供内部类的语法,这种用法也就是把 Stage 当作一个命名空间来用,Create 和 Stage 并没有多少联系。

建议:

一个类如果有一个 create 或者 createXxxx 方法,通常是作为工厂方法,用来构造其对象或者子类对象,就是作为方法来使用,而不是作为类来使用,使用的时候不用 new 运算符。

一个类如果有一些相关类需要挂在上面(内部类),通常这个类是外面这个类的子类或者密切相关的一些类。最好直接按 ES6 的语法挂 class Xxxx 而不是 function Xxxx


补充一点。没考虑到题主有可能是想基于对象属性来创建新对象。这样的话,定义 create 是对的,只是调用方法不对。不应该 new Stage.create(),而应该 new Stage("a name").create()。也就是先创建一个对象,再调用这个对象的 create 实例方法,根据对象本身的属性值创建新对象。

比较典型的应用是 clone(),比如

export class Stage {
    constructor(name) {
        this.name = name;
    }

    clone() {
        return new Stage(this.name);
    }
}

const s1 = new Stage("s1");
const s2 = s1.clone();

console.log(s1, s2);
// Stage { name: 's1' } Stage { name: 's1' }

s2.name = "s2";

console.log(s1, s2);
// Stage { name: 's1' } Stage { name: 's2' }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏