如何将JavaScript代码转为类式写法?我的尝试代码存在哪些问题?
函数式转类式JavaScript的问题解析
原函数式代码
function Foo(options) { this.index = options.index; this.name = options.name || 'foo'; var items = options.items; var self = this; function bar() { self.say(); } items.forEach(function () { self.say(); }); for (var i = 0; i < items.length; i++) { bar(); } } Foo.prototype.say = function () { console.log(arguments); };
你尝试的类式代码
class Foo { constructor(options) { this.index = options.index; this.name = options.name || 'foo'; this.items = options.items this.items.forEach(() => { this.say() }) for (var i = 0; i < items.length; i++) { this.bar(); } } bar() { this.say(); } } class say extends Foo { constructor() { console.log(arguments) } }
你的类式代码存在的问题
say方法的定义完全错误:原代码里say是Foo原型上的实例方法,但你把它写成了一个继承Foo的独立类,这完全偏离了原逻辑。正确的做法是在Foo类内部直接定义say方法,而不是新建类。for循环中未正确引用items:你在构造函数里已经把options.items赋值给了this.items,但for循环里用了items.length,这里的items没有定义,会抛出ReferenceError,应该改成this.items.length。bar方法的定位偏差:原代码里bar是构造函数内部的私有函数(只能在构造内调用),而你把它放到了Foo的原型方法里,变成了公开的实例方法。如果想保持私有性,ES6类可以用私有方法语法(#bar()),或者如果不需要严格私有,当前写法虽然能运行,但和原逻辑的封装性有差异。say方法的实现不符合原逻辑:原say方法会打印调用时传入的所有参数,而你写的say类的构造函数里console.log(arguments)完全不对,应该在Foo类里定义say方法,比如say(...args) { console.log(args); }(用剩余参数比arguments更符合ES6风格)。
修正后的类式代码参考
class Foo { constructor(options) { this.index = options.index; this.name = options.name || 'foo'; this.items = options.items; // 原逻辑中的私有bar函数,用局部函数实现(保持私有性) const bar = () => { this.say(); }; this.items.forEach(() => { this.say(); }); for (let i = 0; i < this.items.length; i++) { bar(); } } // 定义实例方法say say(...args) { console.log(args); } // 如果需要把bar设为公开方法,也可以这样写(但原逻辑是私有) // bar() { // this.say(); // } }
是否值得切换到类式写法?
这个问题取决于你的场景和编程风格:
- 值得切换的场景:
- 你的项目是面向对象风格,需要创建多个具有相同属性和方法的实例;
- 需要使用继承、静态方法等面向对象特性,类式写法的
extends、static语法比手动操作原型链简洁直观得多; - 团队协作时,类式写法的结构更清晰,更容易被有其他面向对象语言经验的开发者理解。
- 可以保留函数式的场景:
- 只是简单的工具函数、纯函数,不需要实例化;
- 偏向函数式编程风格,更依赖闭包、函数组合等特性,函数式写法更灵活。
总的来说,类式写法是ES6标准化的面向对象语法糖,它没有改变JavaScript原型继承的本质,但让代码更易读易维护。作为现代JavaScript开发者,掌握类式写法是很有必要的,能帮你更好地理解JS的面向对象机制,也能适配更多现代项目的代码风格。
内容的提问来源于stack exchange,提问作者codebarz
相关产品推荐
相关产品推荐

