是否有任何“和谐”方式从ES6类实例获取类名?以外
someClassInstance.constructor.name
目前,我指望Traceur的实现。而且,Babel似乎具有Function.name
Tracefill没有的polyfill。
综上所述:ES6 / ES2015 / Harmony中没有其他方法,并且ES中没有ATM的预期。
它可以为未缩小的服务器端应用程序提供有用的模式,但是在旨在用于浏览器/桌面/移动设备的应用程序中是不需要的。
巴别用途core-js
来填充工具Function.name
,应当手动Traceur和打字稿应用适当装载。
someClassInstance.constructor.name
正是这样做的正确方法。编译器可能不支持此功能,但这是规范中的标准方法。(name
通过ClassDeclaration产生式声明的函数的属性在14.5.15的步骤6中设置。)
如@Domenic所说,使用someClassInstance.constructor.name
。@Esteban在评论中提到
someClassInstance.constructor
是一个功能。所有函数都有一个name
属性...
因此,要静态访问类名,请执行以下操作(这适用于我的Babel版本BTW。根据@Domenic上的注释,您的行驶里程可能会有所不同)。
class SomeClass {
constructor() {}
}
var someClassInstance = new SomeClass();
someClassInstance.constructor.name; // === 'SomeClass'
SomeClass.name // === 'SomeClass'
更新资料
Babel很好,但丑化/缩小确实导致了我麻烦。我正在做一个游戏,并且正在创建一个池中Sprite资源的哈希(其中键是函数名)。缩小后,每个函数/类都被命名为t
。这杀死了哈希。我正在Gulp
这个项目中使用,在阅读了gulp-uglify文档后,我发现有一个参数可以防止这种局部变量/函数名称的修改发生。所以,在我的gulpfile中,我改变了
.pipe($.uglify())
至 .pipe($.uglify({ mangle: false }))
这里需要权衡性能与可读性。不修改名称将导致(略微)较大的构建文件(更多的网络资源),并可能导致代码执行速度变慢(需要引用-可能是BS)。另一方面,如果保持不变,则必须getClassName
在每个ES6类上手动定义-在静态和实例级别。不用了,谢谢!
更新资料
在评论中进行讨论之后,似乎避开.name
约定以支持定义这些功能是一个很好的范例。它只需要几行代码,就可以完全缩小代码的通用性(如果在库中使用)。因此,我想我改变主意了,将getClassName
在课堂上进行手动定义。谢谢@estus!。无论如何,与直接变量访问相比,getter / setter通常是一个好主意,尤其是在基于客户端的应用程序中。
class SomeClass {
constructor() {}
static getClassName(){ return 'SomeClass'; }
getClassName(){ return SomeClass.getClassName(); }
}
var someClassInstance = new SomeClass();
someClassInstance.constructor.getClassName(); // === 'SomeClass' (static fn)
someClassInstance.getClassName(); // === 'SomeClass' (instance fn)
SomeClass.getClassName() // === 'SomeClass' (static fn)
Getting class name directly from class
先前的答案解释说这someClassInstance.constructor.name
很好用,但是如果您需要以编程方式将类名转换为字符串,并且不想为此创建实例,请记住:
typeof YourClass === "function"
而且,由于每个函数都有一个name
属性,因此使用类名获取字符串的另一种不错的方法是:
YourClass.name
接下来的例子很好地说明了为什么这样做很有用。
加载网页组件
正如MDN文档所教导的,这是您加载Web组件的方式:
customElements.define("your-component", YourComponent);
从那里YourComponent
延伸的班级在哪里HTMLElement
?由于在组件标签本身之后命名组件的类是一种好习惯,因此最好编写一个辅助函数,所有组件都可以使用该函数来注册自己。所以这是该函数:
function registerComponent(componentClass) {
const componentName = upperCamelCaseToSnakeCase(componentClass.name);
customElements.define(componentName, componentClass);
}
因此,您需要做的就是:
registerComponent(YourComponent);
很好,因为它比自己编写component标签要容易出错。总结一下,这是upperCamelCaseToSnakeCase()
函数:
// converts `YourString` into `your-string`
function upperCamelCaseToSnakeCase(value) {
return value
// first char to lower case
.replace(/^([A-Z])/, $1 => $1.toLowerCase())
// following upper chars get preceded with a dash
.replace(/([A-Z])/g, $1 => "-" + $1.toLowerCase());
}
进行通天译本(缩小前)
如果您将Babel与结合使用@babel/preset-env
,则可以保留类定义,而无需将它们转换为函数(这会删除constructor
属性)
您可以在此配置中删除与此配置之间的旧浏览器兼容性babel.config / babelrc
:
{
"presets": [
["@babel/preset-env", {"targets": {"browsers": ["> 2%"]}}]
]
}
有关更多信息
targets
:https : //babeljs.io/docs/en/babel-preset-env#targets
为了缩小通天粉(在移植后)
看来目前没有简单的解决方案...我们需要研究如何处理排除问题。
文章标签:ecmascript-6 , javascript , traceur
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!