【发布时间】:2016-09-02 16:45:43
【问题描述】:
在 ES5 中我们都可以这样做:
myClass.prototype.myMethod = (function () {return function() {}})();
我能用 ES6 类文字做同样的把戏吗?
【问题讨论】:
-
请用类文字举例说明您所指的内容。
在 ES5 中我们都可以这样做:
myClass.prototype.myMethod = (function () {return function() {}})();
我能用 ES6 类文字做同样的把戏吗?
【问题讨论】:
不,至少现在还没有。 ES6 类只支持声明方法,因此任何不是直接方法的东西(包括间接评估为方法的东西,例如 IIFE)仍然必须使用原型声明。
然而,ES6 类的工作方式与 ES5 构造函数的工作方式相同,只是语法更简洁,所以你仍然可以这样做:
class MyClass {
constructor() {
/* initialize */
}
regularMethod() {
/* some stuff */
}
}
MyClass.prototype.myMethod = (function() { return function() })()
相当于这个:
function MyClass() {
/* initialize */
}
MyClass.prototype.regularMethod = function() {
/* some stuff */
}
MyClass.prototype.myMethod = (function() { return function() })()
【讨论】:
this?
2019 年更新
是的,你可以做到。
您只需要像“函数表达式”一样创建 IIFE(将其分配给变量)
class MyClass {
IIFE = (() => {
let textArrayCreatedJustOnce = ['text A', 'text B', 'text C'];
console.log('Only called in object creation');
return () => {
console.log(textArrayCreatedJustOnce[1]);
}
})()
}
let myClassInstance = new MyClass(); //log: 'Only called in object creation'
myClassInstance.IIFE(); //log: 'text B'
myClassInstance.IIFE(); //log: 'text B'
myClassInstance.IIFE(); //log: 'text B'
【讨论】:
this,但可以。这不是太高科技。这些分配是在构造函数中完成的,不要害怕。就好像你写了constructor() {this.IIFE = ...} 见developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。
可以创建一个装饰器:
function iife(target, key, { value: fn, configurable, enumerable }) {
return {
configurable,
enumerable,
value: fn(),
};
}
并像这样使用它:
class MyClass {
@iife
methodName() {
/* some stuff */
return function() {
/* real method content */
}
}
}
如果我需要一些繁重的临时变量,例如我不想为每个方法调用创建的向量矩阵,我会使用它。
【讨论】:
@juanma-menendez 的 2019 年回答很有趣,尽管给我留下了一些疑问和未回答的问题。
第一个问题是它使用了箭头函数。箭头函数处理调用上下文的方式与普通函数表达式不同。此外,它们不支持递归(据我所知)。
第二个问题是它从不尝试this 关键字。
在这个句法糖浆中调用上下文是什么有点不清楚。
经过一些不成功的尝试,我在 Google Chrome 中成功进行了以下设置。此示例演示了可以从返回的方法访问私有属性和对象属性,并且它适用于多个实例:
class C {
constructor(attr) {
this.attr = attr;
}
IIFE = function() {
const privateArray = ["A", "B", "C"];
console.log("Created private array during object creation.");
return function() {
console.log("privateArray[1] = %s", privateArray[1]);
console.log("this.attr = ", this.attr);
}//.bind(this);
}.call(this);
}
var obj1 = new C("asdf");
console.log(obj1.IIFE());
console.log(obj1.IIFE());
var obj2 = new C("ghjk");
console.log(obj2.IIFE());
输出(未定义为返回值):
Created private array during object creation.
privateArray[1] = B
this.attr = asdf
undefined
privateArray[1] = B
this.attr = asdf
undefined
Created private array during object creation.
privateArray[1] = B
this.attr = ghjk
undefined
我必须承认我不明白为什么.bind(this) 是错误的。我也有点困惑,私有数组是为每个实例创建的,并且不仅仅存在于原型中。我不是 100% 确定这是否等同于使用 IIFE 制作的原型方法。
无论如何,这对于部署来说可能有点太高科技了,因为许多最终用户将使用 2019 年之前的浏览器。另外,我还没有测试过性能。使用风险自负! :-)
【讨论】:
不,类文字不能包含 IIFE,它们需要由方法声明组成。
在使用 class 关键字声明 myClass 之后,您可以在 ES6 中使用相同的赋值。然而,在 ES6 中使用 IIFE 并没有什么好的理由,因为它们通常可以被块作用域或模块替换。
【讨论】: