JavaScript类不是“只是句法糖”

2021-04-17 08:36:04

阅读又一次博客帖子关于JS课程是“只是糖的原型继承”,我决定写这篇文章来帮助澄清,再一次,为什么这个陈述是误导;一个希望解释有什么区别的帖子以及理解它的原因。

使用"使用严格"在ES5中的指令将不会禁止禁止胁迫函数,而无需新关键字。

// ES5功能测试(){"使用严格&#34 ;; test.call({}); //它' s OK // ES6 +类测试{} test.call({}); //它抛出

原因是现代类有一个新的概念否则无法在ES5中复制,而不使用模拟此类行为的转发器。 Transpiler也必须使用instanceof检查,导致较慢,膨胀,代码。

自2004年以来,我的个人尝试到子类阵列和其他人,它并不是真的可以在ES5中以有用或有意义的方式扩展内置。

// eS5 epic失败函数列表(){"使用strict&#34 ;; list.prototype = Object.Create(array.Prototype); var列表=新列表; list.push(1,2,3); json.stringify(列表); // {" 0":1," 1":2," 2":3,"长度":3} list.slice (0)instanceof列表; // 错误的

让我们忽略我甚至不使用Array.apply(这,参数),因为它也将失败期望,无论您如何看待它,AS5阵列延伸都是笨拙的,也是其他所有内置的字符串或其他人。

// ES5 EPIC失败V2函数文本(价值){"使用严格&#34 ;; string.call(此值);新文本("这项工作吗?"); // nope,它并不......无能为力。

好的,我听到你的声音,“谁会需要延长字符串伙伴?”,你是对的:你可能不需要这样做,但这就是用ES5或更好地做到这一点,或者更好地是不可能的:原型是不可能的继承不能这样做,JS类可以。

如果您想知道“如何list.slice(0)不是列表的实例?”,答案是符号。

// es6 +类列表扩展array {}(新列表).slice(0)instanceof列表; // true [] .slice.call(new list)instanceof列表; // 真的

因此,除非您保护每种方法来返回初始类型的方法,否则将期望通过所有阵列方法,但这里的ES5只是痛苦,不可靠,脆弱,而不是使用物种配合使用。

如果您想知道“如何传达array.apply(这,参数)在构造函数中无法在ES5工作?”答案是:

数组内置创建一个新数组,它根本不关心上下文,也没有其他内产

JS课程推广/升级实例,在没有转介机的情况下,在ES5中是不可能做的,即使与Transpiler一样,它在内置延伸时是一团糟

是的,正确的答案是后者,所以除非我们编写所有子类别:

函数mysubclass(){var self = class.apply(这,参数)||这; //用自我回归自我做任何事情; }

如果超级级是一个内置的,我们可能会在一个原始的自我时代

函数mysubclass(){var self = class.apply(这,参数);如果(self == null)self = the;否则if(!(selficationof mysubclass)){object.setprototypeof(self,mysubclass.prototype); //做自我回报的事情; }

// es6 +类按钮{constructor(){return document.createelement('按钮'); Class MyButton扩展了按钮{构造函数(值){super(); this.textContent = Value; Document.Body.AppendChild(新MyButton("你好"));

这不是严格的一些JS类功能,但这是许多不知道的东西:方法不构成,与速记文字方法相同。

在ES5中,所有功能都可以用作构造函数,除非每次检查上下文品牌,否则都无法避免这种情况。

// ES5函数test(){} test.prototype.method = function(){if(!(这个实例测试))抛出新的typeerror("不是构造函数"); };

你看到自己写作这样的代码是因为宣言课程只是糖吗?

在JS类中,静态和非静态方法都不是令人令人登应的。是的,我们也可以用ES5做到这一点,但是Boilerplate巨大,慢,尴尬。

在JS类中,我们可以在类定义中指定箭头。我们可以在ES5构造函数中做同样的事情,但我们再次需要大量的样板来模拟相同的样板:

// es5函数witharrows(){object.defineproperties(这,{method1:{可配置:true,写:true,value:()=>"箭头1"}); } // es6 +类与arrows {method1 =()=> "箭头1&#34 ;; } //(新的witharrows).method1();

// es6 +类inprivates {#value; #method(价值){这个。#value = value;构造函数(值){此。#方法(值); }}

我们可以在ES5中模拟私人吗?不是真的,除非我们使用Transpiler和Dealmap来捕获每个实例,特定私有私有遗漏,不应该在那里泄漏,如果发生这种泄漏的情况下没有警卫。

是的,可以通过ES5和旧原型继承来模拟许多事情,但这些都不是出来的,并且与类的适当语法一样快,或者是安全的,并且在那里原型遗产不可能的事情。

因此,让我们停止说,JS类只是糖,因为除非我们决定不想使用可以在JS中制作OOP的现代类功能,否则不能被忽视或忽略这些陈述中缺少的细节数量比最后20个,原型,年好。

在这种情况下,正确的陈述更像:“我不喜欢JS课程,因此我认为我们的原型继承了”。

现在这是一个更诚实的,纠正,声明......说课程是“只是糖”是一个非常糟糕的现代JS及其特征。