该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-06-13
dogstar 写道 well done,继续写一些好文章。
charon 写道 貌似很多开源包和很多人都实现了自己的extends/mixins或者类似的方法.有些在里面还干了一些非常magic的事情。
这个,大概是用基于prototype的语言来实现这些东西的困惑巴。因为没有在语言级别提供直接的支持,于是大家都百花齐放,或者说的难听一点就是各奔东西了。直接的结果是某些开源包互相之间有冲突,不能拿来一齐使用(我有近半年没用过javascript了,或者现状已经改变了?社区有了大一统的做法?) 另外,这里还差一个多态的实现,虽然简单,但称不上优雅。也一齐补全了吧 javascript应该算是小巧灵性。这些灵活就注定了他不太容易大规模工业生产。比如java。 为什么非要写的那么复杂呢?我在写javascript的时候,顶多就用到一些对象之类的,什么继承之类的考虑都不考虑。写java不也是一个接口,一个实现。连继承都很少有。(不要告诉我,我写的应用太小,哈哈)。所以,语言本身探讨可以,但不要过多吹毛求疵了。 ![]() 或许OO程序中继承、多态所占的相关代码并不是很多,但往往是整个系统最闪光的部分 譬如DP整本书在教你少用继承,但如果没有继承和多态,那所有的DP就化为乌有了 |
|
返回顶楼 | |
发表时间:2007-06-14
再提个问题
LZ这个逃逸变量法实现私有权限的方式,是内在不一致的。或者说实现的并不是真正的私有变量. 就LZ对Python提的8个问题,其中有三个是: 引用 ... Python 的类能在声明完成之后不声明额外名字给类添加方法吗? Python 的对象能在声明完成之后不声明额外名字给自己添加方法吗? .... Python 的类能真正支持私有属性吗? 姑且认为LZ是确认Javascript能够实现这些特性的。 但是,LZ的私有变量的实现,直接与前两个问题冲突。而且即便是声明额外的名字,也不能解决这个冲突。 在体外声明的方法,根本无法直接访问体内定义的私有变量。 因此这个逃逸法定义的实际上并不是私有变量。或者说是以牺牲内在一致性为代价的私有变量。 顺便说一下,如果这么做也算是私有变量的话,python照样也可以实现,只要把class定义在一个非全局环境中即可。 |
|
返回顶楼 | |
发表时间: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 我觉得我真的很有毅力…… |
|
返回顶楼 | |
发表时间:2007-06-14
表达式中不能出现本级空间中同名变量这个问题,官方的说法貌似是不能给中间作用域的变量直接赋值。或者说,所有赋值左端的自由变量都只能是最内层作用域的. python的作用域规则确实比较诡异,2.1之前还要差。
只有采用变通的办法, 搞个可读写的object。比如var=[x],则就可以在内层空间这么搞var[0] = var[0] + 10。 |
|
返回顶楼 | |
发表时间: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上去的方法就不允许访问源定义中的私有变量? 不过这么做确实是私有变量里面的私有变量。说白了就是揣个引用到处跑啊。 |
|
返回顶楼 | |
发表时间:2007-06-21
|
|
返回顶楼 | |
发表时间: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 } 来得直接,完全的无类。 |
|
返回顶楼 | |
发表时间: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的方式实现的是单继承。 |
|
返回顶楼 | |
发表时间: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}是每创建一个对象时为其创建独立的函数,还是所有该对象共享该函数呢??? |
|
返回顶楼 | |
发表时间:2007-08-18
每一次都会创建不同的函数对象,这是跑不了的了。但是所有这些函数对象是有共同点的,函数代码是一样的,仅仅是scope不一样,因此js引擎是可以做优化的。
所以上面的例子里,从节约内存的角度来说应该写成 Light.prototype.turnOn = function () {...} 但是,就算现在的写法,也不必过分紧张,因为函数执行代码还是一份。 |
|
返回顶楼 | |