JavaScript中"抽象"函数的最佳实践?

Dan*_*don 19 javascript abstract-class functional-programming

我刚写了一些JavaScript代码,后面跟着我认为是创建带闭包和一些函数的对象的好习惯:

var myStuff = (function() {
 var number = 0;
 var fn = {};
 fn.increment = function() { number++; };
 fn.decrement = function() { number--; };
 fn.getNumber = function() { return number; };
 return fn;
})();

myStuff.increment();
myStuff.increment();
alert(myStuff.getNumber()); // alerts '2'
Run Code Online (Sandbox Code Playgroud)

编写像上一个代码片段一样的代码没有问题.我想编写一些功能类似于OOP"抽象"类的代码.这是我努力的结果:

var myStuff = (function () {
var number = 0;
var fn = {};
fn.increment = function () { number++; };
fn.decrement = function () { number--; };
fn.doSomethingCrazy = function () { throw new Error('not implemented'); }; // I want to specify later what this does.
fn.doSomethingCrazyTwice = function () { fn.doSomethingCrazy(); fn.doSomethingCrazy(); };
fn.getNumber = function () { return number; };
return fn;
})();

myStuff.doSomethingCrazy = function () { this.increment(); this.increment(); };
myStuff.doSomethingCrazyTwice();
alert(myStuff.getNumber()); // alerts '4'
Run Code Online (Sandbox Code Playgroud)

上面的代码片段有效,但看起来并不优雅.也许我正在尝试强制JavaScript(一种函数式语言)来做一些它不打算做的事情(对象继承)

在JavaScript中定义对象的好方法是什么,以便稍后可以定义该对象的功能?

SLa*_*aks 21

只是不要定义功能.

Javascript是一种鸭式语言.如果它看起来像一只鸭子,它像鸭子一样嘎嘎叫,它就是一只鸭子.
你不需要做任何特殊的事情来完成这项工作; 只要在调用它时函数存在,它就可以正常工作.

如果在没有该功能的实例上调用它,则会在调用点上收到错误.

  • @Rice:这没有什么区别; 这就是鸭子的意思. (3认同)

Jua*_*des 9

我同意SLaks,没有必要定义函数,但无论如何我倾向于.那是因为对我而言,重要的部分是在文档中.当有人读我的课时,我希望它清楚你必须实现这些方法,将传递什么参数以及应该返回什么.

这是来自工作中的文件.有一个具有基类的功能的多个实现,每隔一段时间执行一次数据加载.

/**
 * Called when data is received and should update the data buffer
 * for each of the charts 
 * 
 * @abstract
 * @param {cci.ads.Wave[]} waves
 * @void
 */
updateChartsData: function(waves){
    throw "Abstract method updateChartsData not implemented";
},
Run Code Online (Sandbox Code Playgroud)

2019年更新

如果可以在TypeScript中声明抽象方法,请使用TypeScript

  • @Raynos:仅仅因为一种语言没有这个概念,并不意味着它没有用。拥有一个基本的空函数可能是不可取的,因为它。然而,我认为不可接受的是没有在抽象类中记录方法将如何被调用,这就是我不喜欢“只是不定义函数”的地方。如果您选择使所有“抽象”方法不带下划线,那很好,我们的约定是使用下划线,因为这些方法不应该从类外部调用,只要保持一致即可。 (2认同)

Oli*_*ins 7

随着我们的团队不断发展,我们的javascript项目变得越来越复杂,我们也必须开始实现OO功能.

在我们的javascript"抽象"方法中,我们只是抛出一个错误,或者弹出警报.这是一个来自Page对象的示例:

Page.initialLoad = function() { //abstract
    alert('Page.initialLoad not implemented');
};
Run Code Online (Sandbox Code Playgroud)

在java世界中它与以下类似:

public void abstract initialLoad();
Run Code Online (Sandbox Code Playgroud)

Java代码给出了编译时错误,但是在Javascript中我们会遇到运行时错误.(一个脏错误对话框,说明实现对象尚未实现该方法).

我们有许多使用Page对象的不同团队; "鸭子打字"的理念绝对不会让我们失望.如果没有这些伪"抽象"方法,我们普遍缺乏API通信,有时我们会破坏超级对象(即,因为用户不知道他们应该实现该方法).

我厌倦了这种'鸭子打字'的理念.我不确定支持者是否曾经参与过10个开发人员的复杂Javascript项目.