论坛首页 综合技术论坛

无类语言的OOP(JavaScript描述)

浏览 27997 次
该帖已经被评为良好帖
作者 正文
   发表时间:2007-06-13  
dogstar 写道
well done,继续写一些好文章。

charon 写道
貌似很多开源包和很多人都实现了自己的extends/mixins或者类似的方法.有些在里面还干了一些非常magic的事情。

这个,大概是用基于prototype的语言来实现这些东西的困惑巴。因为没有在语言级别提供直接的支持,于是大家都百花齐放,或者说的难听一点就是各奔东西了。直接的结果是某些开源包互相之间有冲突,不能拿来一齐使用(我有近半年没用过javascript了,或者现状已经改变了?社区有了大一统的做法?)

另外,这里还差一个多态的实现,虽然简单,但称不上优雅。也一齐补全了吧


javascript应该算是小巧灵性。这些灵活就注定了他不太容易大规模工业生产。比如java。
为什么非要写的那么复杂呢?我在写javascript的时候,顶多就用到一些对象之类的,什么继承之类的考虑都不考虑。写java不也是一个接口,一个实现。连继承都很少有。(不要告诉我,我写的应用太小,哈哈)。所以,语言本身探讨可以,但不要过多吹毛求疵了。


或许OO程序中继承、多态所占的相关代码并不是很多,但往往是整个系统最闪光的部分

譬如DP整本书在教你少用继承,但如果没有继承和多态,那所有的DP就化为乌有了



0 请登录后投票
   发表时间:2007-06-14  
再提个问题
LZ这个逃逸变量法实现私有权限的方式,是内在不一致的。或者说实现的并不是真正的私有变量.
就LZ对Python提的8个问题,其中有三个是:
引用

...
Python 的类能在声明完成之后不声明额外名字给类添加方法吗?
Python 的对象能在声明完成之后不声明额外名字给自己添加方法吗?
....
Python 的类能真正支持私有属性吗?

姑且认为LZ是确认Javascript能够实现这些特性的。
但是,LZ的私有变量的实现,直接与前两个问题冲突。而且即便是声明额外的名字,也不能解决这个冲突。
在体外声明的方法,根本无法直接访问体内定义的私有变量。
因此这个逃逸法定义的实际上并不是私有变量。或者说是以牺牲内在一致性为代价的私有变量。

顺便说一下,如果这么做也算是私有变量的话,python照样也可以实现,只要把class定义在一个非全局环境中即可。
0 请登录后投票
   发表时间:2007-06-14  
好好好,不跟你们争关于多态的东西了,行不?
JavaScript 中的实例属性 __proto__ 指向其构造函数的 prototype,constructor 指向构造函数,不要自己写多态方法调用方法,要用哪个直接指定就可以了;如果一定要写,用类似文中 Mixin 用的技术外部调用多态方法也是可以的。

引用
而且,就继承而言,javascript中的分类也是五花八门,也许拿到一个js库,第一个任务就是理解它的继承模型http://ajaxpatterns.org/Javascript_Inheritance

你发的那个网址所说的我只了解一部分,仔细看了一下。
我所说的令人讨厌的是 Direct Inheritance,因为它只是在一味地模仿 Java,而且模仿地还不像,对于我这样成天用 this 在执行上下文中跳来跳去的用户还有严重的 Bug;它要求你必须中规中矩,改变代码风格。
其它方法中 Bound Inheritance 是个 Direct 的保守版本,不过我也不能接受。
剩下来的几种方式不知道你仔细阅读了代码没有,本质是一样的,基本上可以做到不影响代码风格(因为最终效果都是一样的,估计你也看出来了,我可以选择使用,想不用时也不会出问题);Reference Inheritance 其实只是把普通的 prototype 继承消息封装了起来,可扩展性受限制,不知是出于何种想法。

那当然是私有变量,而且还保证了不知道细节的外部定义函数再绑定也是白搭。真是比 private 还 private。
deak.getAgain = function () {
    return height
}
js> deak.getAgain()
js: ReferenceError line 2:height is not defined


确实,把 class 定义在局部空间中可以达到类似的效果,只不过,Python 在理解局部变量的时候,重绑定上级空间中的变量时,表达式中不能出现本级空间中同名变量——看到这个是不是很晕?而且,你打算用什么把 class 从函数空间中返回出来?难道说:
def MyClass ():
    private_val = 12
    class _noname_:
        def get_val (self):
            return private_val
    # 很有意思,可以考虑做一成个“私有类容器”//smile
    return _noname_
>>> obj = MyClass()()
>>> obj.get_val()
12

我觉得我真的很有毅力……
0 请登录后投票
   发表时间:2007-06-14  
表达式中不能出现本级空间中同名变量这个问题,官方的说法貌似是不能给中间作用域的变量直接赋值。或者说,所有赋值左端的自由变量都只能是最内层作用域的. python的作用域规则确实比较诡异,2.1之前还要差。
只有采用变通的办法, 搞个可读写的object。比如var=[x],则就可以在内层空间这么搞var[0] = var[0] + 10。
0 请登录后投票
   发表时间:2007-06-15  
Lich_Ray 写道

那当然是私有变量,而且还保证了不知道细节的外部定义函数再绑定也是白搭。真是比 private 还 private。
deak.getAgain = function () {
    return height
}
js> deak.getAgain()
js: ReferenceError line 2:height is not defined





faint.兄弟在开玩笑吧。
这个不仅仅是外部函数,内部函数也不行啊。除非这个内部函数是定义在那个逃逸变量的作用域范围内。
用现在时髦的说法,俺们都流行open class了,难道这些open上去的方法就不允许访问源定义中的私有变量?
不过这么做确实是私有变量里面的私有变量。说白了就是揣个引用到处跑啊。
0 请登录后投票
   发表时间:2007-06-21  
相关文章:
http://www.iteye.com/topic/85966
关于JavaScript的 貌似类(pseudo-classes)----不吐不快
0 请登录后投票
   发表时间:2007-07-01  
引用
# //把那些垃圾的库抛在脑后,让它们见识见识什么叫优雅。 
# Object.prototype.extend = function (aClass) { 
#     this.prototype = new aClass 
# } 
# PhilipLight.extend(Light) //No problem


不如
Object.prototype.extend = function (object) { 
    this.prototype = object
}
来得直接,完全的无类。
0 请登录后投票
   发表时间:2007-07-18  
nihongye 写道
引用
# //把那些垃圾的库抛在脑后,让它们见识见识什么叫优雅。 
# Object.prototype.extend = function (aClass) { 
#     this.prototype = new aClass 
# } 
# PhilipLight.extend(Light) //No problem


不如
Object.prototype.extend = function (object) { 
    this.prototype = object
}
来得直接,完全的无类。



很多书上说用一个父类的实例去替换子类的prototype。另外,只用prototype chain的方式实现的是单继承。
0 请登录后投票
   发表时间:2007-08-18  
Lich_Ray 写道

建立类。只需声明一个函数作为类的构造函数即可。
function Light (light) {
	//填充对象属性
	this.light = light ? light : 0
	this.state = false
	
	//对象方法。
	//放心,JavaScript 没傻到给每个对象都真去分配一个函数的地步
	this.turnOn = function () {
		this.state = true
	}
}




我之前看过一些相关资料,说
this.trunOn=function(){
     this.state=true;     
}

每次创建一个Light时,会重复生成函数,为每个Light对象都创建建立的函数.所以这样会比较浪费内存!!
一直在我人印象都是这样,刚刚看了本文后,有一点动摇,究竟是会为this.state=function(){this.state=true}是每创建一个对象时为其创建独立的函数,还是所有该对象共享该函数呢???
0 请登录后投票
   发表时间:2007-08-18  
每一次都会创建不同的函数对象,这是跑不了的了。但是所有这些函数对象是有共同点的,函数代码是一样的,仅仅是scope不一样,因此js引擎是可以做优化的。

所以上面的例子里,从节约内存的角度来说应该写成
Light.prototype.turnOn = function () {...}

但是,就算现在的写法,也不必过分紧张,因为函数执行代码还是一份。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics