【发布时间】:2015-02-07 03:29:18
【问题描述】:
前段时间,我想从其他几个语言中多年的 oop 编码中理解 js oop。我发现它非常混乱。几个月后,阅读了一本 JS 书和许多文章和 SO 问题,我在一个具体示例中总结了所有内容,该示例说明了主要的 oop 概念正确工作。这里是:
function Operators() {
//mandatory
var self = this
//private
var IPT_X = '#x'
var IPT_Y = '#y'
//public
this.x = 0
this.y = 0
this.showOperators = function() {
//use of a private property (IPT_X) and a public property (this.x)
$(IPT_X).val(this.x)
$(IPT_Y).val(this.y)
}
this.clean = function() {
this.x = 0
this.y = 0
// call to a local public method
this.showOperators()
}
this.updateOperators = function(_x, _y) {
// use of a public property when call from
// derived class method is necessary
self.x = _x
self.y = _y
}
}
function Randomizer() {
// mandatory for derived classes
Operators.call(this)
// mandatory for overloaded methods with call to the inherited method
var parentUpdateOperators = this.updateOperators
var self = this
// private
function getRandomNumber() {
return Math.round(Math.random() * 1000)
}
// public
this.updateOperators = function(_x, _y) {
// call to inherited method of superior class
parentUpdateOperators(_x, _y)
// call to method of superior class
self.showOperators()
}
this.populateRandomNumbers = function() {
// call to public local method (this.updateOperators())
// and to a local private method (getRandomNumber())
this.updateOperators(getRandomNumber(), getRandomNumber())
}
// init
this.populateRandomNumbers()
}
// Mandatory for derived classes. Allows access to superior classes with
// more than 2 levels of inheritance ("grandfather" classes)
Randomizer.prototype = Object.create(Operators.prototype)
function Operations() {
Randomizer.call(this)
var self = this
//private
var IPT_RES = '#res'
var BTN_SUM = '#sum'
var BTN_SUBTRACT = '#subt'
var BTN_MULTIPLY = '#mult'
var BTN_DIVISION = '#div'
var BTN_CLEAN = '#clean'
var BTN_RAND = '#rand'
function calcSum() {
return self.x + self.y
}
function calcSubtraction() {
return self.x - self.y
}
function calcMultiplication() {
return self.x * self.y
}
function calcDivision() {
return self.x / self.y
}
function showRes(val) {
$(IPT_RES).val(val)
}
//public
this.sum = function() {
// call to 2 local private methods
showRes(calcSum())
}
this.subtract = function() {
showRes(calcSubtraction())
}
this.multiply = function() {
showRes(calcMultiplication())
}
this.division = function() {
showRes(calcDivision())
}
// init
$(BTN_SUM).on('click', function() { self.sum() })
$(BTN_SUBTRACT).on('click', function() { self.subtract() })
$(BTN_MULTIPLY).on('click', function() { self.multiply() })
$(BTN_DIVISION).on('click', function() { self.division() })
$(BTN_CLEAN).on('click', function() { self.clean() })
$(BTN_RAND).on('click', function() { self.populateRandomNumbers() })
}
Operations.prototype = Object.create(Randomizer.prototype)
var obj = new Operations()
这是使其工作所需的 HTML:
X: <input id='x'>
<br>
Y: <input id='y'>
<br>
Res: <input id='res'>
<br>
<input id='sum' type='button' value='+'>
<input id='subt' type='button' value='-'>
<input id='mult' type='button' value='*'>
<input id='div' type='button' value='/'>
<input id='clean' type='button' value='C'>
<input id='rand' type='button' value='Rand'>
这是一个 JSFiddle,我的示例运行良好:
http://jsfiddle.net/vqqrf2cb/24/
然后我开始在日常工作中使用这种格式,一切都很好。但现在,在成功使用这种格式几个月后,我继续阅读这个主题,发现很多人使用不同的格式。所以我正在尝试将上面的代码调整为使用对象的其他可能格式。我认识的有:
格式一:
var something = (function() {
//private
foo = 111
bar = 222
function baz() {
//whatever
}
return {
// public
x : 333,
y : 444,
z : function() {
// whatever
}
}
})()
格式2:
var something = (function() {
var obj {
foo : 111,
bar : 222,
function baz() {
//whatever
},
}
return obj
})()
格式 3:
var something = {
foo : 111,
bar : 222,
baz : function() {
//whatever
}
}
格式 4:
// define the Person Class
function Person() {}
Person.prototype.walk = function(){
alert ('I am walking!');
};
Person.prototype.sayHello = function(){
alert ('hello');
};
// define the Student class
function Student() {
// Call the parent constructor
Person.call(this);
}
// inherit Person
Student.prototype = new Person();
// correct the constructor pointer because it points to Person
Student.prototype.constructor = Student;
// replace the sayHello method
Student.prototype.sayHello = function(){
alert('hi, I am a student');
}
// add sayGoodBye method
Student.prototype.sayGoodBye = function(){
alert('goodBye');
}
以及所有这些格式的许多小变体。我什至倾向于认为在 JS 中进行 OOP 的方式趋于无穷。 :D 无论如何,我想尝试一些方法来找到在日常工作中我觉得更好的方法。但是我无法将我的代码转换为任何其他格式以使所有 oop 工作。 'all oop' 我的意思是封装(私有和公共方法和变量)、继承、通过高级类调用重载以及最后的类初始化(如构造函数或其他东西)。
我的问题是:有人可以将我的工作代码翻译成其他一些 js 对象格式吗?我对转换为格式 1 和格式 3 特别感兴趣。也欢迎列表中未包含的其他格式。一个限制:我不想使用 mixins。我想使用原型进行继承。
我还阅读了有关模块化模式的信息。这个例子用起来会怎么样?
也欢迎对我的示例进行更正/评论。
编辑:
在@Robert 和@NoBugs 的答案和cmets 之后,我使用Module Pattern 做了一个替代示例:
【问题讨论】:
-
您展示的不同示例本质上不提供相同的功能。
-
还有其他提供吗?
标签: javascript oop prototype