我刚刚编写了一些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'
编写像上一个代码片段一样的代码没有问题。我想编写一些功能类似于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'
上面的代码片段有效,但看起来并不优雅。也许我正在尝试强制JavaScript(一种函数式语言)来做一些它不打算做的事情(对象继承)
在JavaScript中定义对象的好方法是什么,以便稍后可以定义该对象的功能?
答案 0 :(得分:20)
只是不要定义功能。
Javascript是一种 duck-typed 语言。如果它看起来像一只鸭子,它像鸭子一样嘎嘎叫,它就是一只鸭子 你不需要做任何特别的事情来完成这项工作;只要在调用它时该函数存在,它就可以正常工作。
如果您在没有该功能的实例上调用它,您将在呼叫站点收到错误。
答案 1 :(得分: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";
},
2019年更新
,请使用TypeScript答案 2 :(得分:7)
随着我们的团队不断发展,我们的javascript项目变得越来越复杂,我们也必须开始实现OO功能。
在我们的javascript'摘要'方法我们只是抛出错误,或弹出警报。这是一个来自Page对象的例子:
Page.initialLoad = function() { //abstract
alert('Page.initialLoad not implemented');
};
在java世界中它与以下类似:
public void abstract initialLoad();
Java代码提供了编译时错误,但是在Javascript中我们会得到运行时错误。 (一个脏的错误对话框,说明实现对象还没有实现该方法)。
我们有许多使用Page对象的不同团队;鸭子打字的哲学'绝对不会与我们一起切割它。没有这些伪抽象的'方法我们普遍缺乏API通信,有时我们会破坏超级对象(即因为用户不知道他们应该实现该方法)。
我已经厌倦了这种“打字”的问题。哲学。我不确定支持者是否曾经参与过10多个开发人员的复杂Javascript项目。
答案 3 :(得分:3)
如果你没有找到优雅的方式,可能有一种方法可以创建一些函数来使流程变得更好。但回到主题......
是的,Javascript具有内置委托,即继承,通过原型。
给出一个原型对象:
var proto = {
f: function(){ console.log(this.x); }
}
我们可以创建一个从中继承的新对象:
var obj = Object.create(proto);
obj.x = 42;
obj.f(); //should work!
for(var i in obj) console.log(i);
//should print x, f and some other stuff perhaps
请注意,并不总是支持通过Object.create直接执行操作(旧浏览器等)。旧的(有些人可能会说,正常)方式做的事情是通过时髦的新运算符(不要过多地考虑名称 - 它的目的是混淆分散Java人的注意力)
function Constructor(arg){
this.x = arg;
}
Constructor.prototype = {
f: function(){ ... }
};
var obj = new Constructor(17);
obj.f();
原型继承需要考虑的一个重要区别是缺少私有变量。 只能继承公共变量!因此,常见的约定是使用下划线作为私有变量和受保护变量的前缀。
答案 4 :(得分:0)
您可能需要查看以前的帖子How do I create an abstract base class in JavaScript?
在OOP和JavaScript上为您提供一些轻松阅读的几个网站,我假设您的新手是基于您所说的评论的OOP语言
http://mckoss.com/jscript/object.htm