论坛首页 Java企业应用论坛

Js和Groovy的语言层面上的比较,兼谈“Javaer眼中的Js”

浏览 4389 次
精华帖 (0) :: 良好帖 (4) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-12-18  

主要因为这位童鞋的帖子,http://www.iteye.com/topic/1118016

 

所以想写下个人对Java/Groovy和Js的一些语言层面的比较和理解,如果作为一个Javaer而对Js有偏见的,若是从事Web开发,不妨多多深入去了解下Js。

 

 

***** *****

本文以一个例子开头:

	createFn : function(tag){
		return (function(tagIn){
			return function(text, attr){
				var attrStr = '';
				if(attr){
					for(key in attr)
						attrStr += key + '="' + attr[key] + '" ';
				}
				return '<{0} {1}>{2}</{0}>'.format(tagIn, attrStr, text);
			}
		})(tag);
	}, 

这段代码是一个我常用的为了生成html dom的基础方法

后面可以这么定义:

var tdFn = createFn('td');

用来生成<td></td>之类——完全就是Javaer眼中的template的模式,貌似在Fn programming里有个专有名词:可里化。

 

这个例子很简单,有些Jser可能很熟悉JQuery式的实现$("td").attr({}).click(function(){}).append("");

这都没关系,我只是通过这个例子想表达,面对类似的问题,不同语言可能有不同的解决方法,一些Javaer不要总抱有“在Java中是这么写代码的”的思想去看其他的语言开发方式。

关于Js的入门和进阶学习个人推荐先看看“博客园李战的‘唔透Javascript'”和“Iteye上Js core系列”。

***** *****

 

***** *****

第二个话题就是语言层面的基础api对比——这一点估计Javaer会更满意点,毕竟Java sdk的基础api(基本类型和数据结构的处理和操作)已经很强大了,更不用说n多第三方的库,尤其是commons-lang/collection***。而Js呢,看下参考手册的size就能看出来,没多少,但是用过js的都会有感触——js太灵活了,尤其是其对象机制。

 

同样Js的开源库中也有类似Java的sdks,比如dojo/extjs,还有一些可能开发者用的不多的,如JsClass,Google Closure Tools——Javaer不要只以为Js更关注Html控件,漂亮的UI等,除了这些,基础api一样很丰富,原生态的Js足够灵活,通过设计和扩展,它可以变得很强大。

另外不得不说的是Js同时具备OO和Fn Programming的特点,闭包这点特性还是很有用途的。

***** *****

 

***** *****

然后再和题目挂钩,谈谈Groovy/Js的对比,就不拿Java来比较了——Groovy sdk的api比Java强大些。

关于类系统方面就不多说了,这方面坛子里写的文章很多

 

先说闭包

 

Groovy语言中的闭包以Closure类实现,编译一个Groovy文件,会发现中间出现的闭包都是**$Closure.class单独的类的,定义闭包也很简单

 

def closure1 = {param1, param2 ->

}

 

和Js定义函数一样

var fun1  = function(param1, param2){

};

 

调用时候Groovy为了方便,可以不用(),如Sql的用法db.eachRow({row ->

println row['name']

})

简写了

db.eachRow{row ->

println row['name']

}

所以Groovy语言里基础函数涉及到闭包的一般把闭包作为最后一个参数

这个和Js也一样

如:(JQuery)

$([1,2,3,4,5]).each(function(){

console.log(this);

});

其中对List(Array)的操作方法Js的一些库远远没有象Groovy一样考虑那么多:any/every/grep***,但这些方法在Js中都很容易实现:如JQuery

var llEven = $([1,2,3,4,5]).filter(function(i){

return i % 2 == 0;

}).get();

如果直接在prototype上实现也可以——至少不用Groovy要考虑下你要实现的方法是不是final的

 

再说正则

 

正则部分其实Java语言做得不好,不支持/^***/这样直接定义正则对象,Js好些,String可以直接match(//)

Groovy个人感觉有一点用着不方面就是//m or g之类的情况,多行或不区分大小写,Groovy里是这么定义的

/{?i}/标示的,不知道是不是为了不同而不同了。

 

PS,关于Groovy语言层面的推荐先看看这个blog,然后再看Groovy in action/Mining Groovy等书

http://blog.csdn.net/hivon/article/details/4256296

 

还有就是Groovy在switch语句上更延伸一步,switch的对象貌似什么类型都支持,可以case正则,List,Closure回调

要是Js,就不得不写成if了。。。

 

再说函数参数

 

Java/Groovy中有可以变参数,但都是同一类型,编译后也是数组形式实现的,Js较灵活,arguments是一个专门的对象,定义方法时候甚至不用显示写具体参数,可能是设计时候一个偏向灵活,一个偏向OO多态想法吧,我就碰到一个Php的DB操作的一个类库,其中公用了一些参数很多的方法,而方法实现中会有大量的if分支,如果在Java中设计,应该会对应很多独立的方法。

 

再说基本数据类型之间的转换

 

Js相关的null/undefine 1 == true 0 == false '0' == true之类的都不列举了

Java就相当死板,必须if(obj != null) ****

Groovy好点,和Js类似,也有===的运算符,和Js区别的是:

  1. 只有null,没有undefine***等复杂

  2. if([] && [:])是false的,Js里空对象和空数组是true

  3. typeof ****的结果

 

因为Js的对象永远是{},不管里面怎么定义,所以不会想Java一样会可以的去对应一个“Bean",如

class Person{

  def String name ***

}

在JavaBean方面,Groovy的基础类型和JavaBean的转换比较容易,一般as即可——在Groovy的程序里中,我个人是偏向基本数据结构而非Beans。(这方面http://blog.csdn.net/hivon/article/details/4256296里讲得较详细

 

  关于这方面还有很多细节的,尤其是Js的浏览器兼容性问题

 

其他的尤其是非Js涉及的功能,如socket/thread,如果拿来比较就太欺负Js了,关于node.js等服务端js的确了解太少,我个人的看法是,既然都是c的库,用python/ruby去调用应该比js更擅长。Web客户端就别折腾了,只愿各浏览器厂商多多标准化,别把js弄得太臃肿。

 

 

欢迎大家来讨论和拍砖

 

 

   发表时间:2011-12-21  
恩,挺好。
没有接触过groovy,但是想学习下Scale,楼主有木有好建议
0 请登录后投票
   发表时间:2011-12-21  
JS不错,但不看好groovy
0 请登录后投票
   发表时间:2011-12-21  
houfeng0923 写道
恩,挺好。
没有接触过groovy,但是想学习下Scale,楼主有木有好建议


Scala?很好很强大啊,我个人了解不多,当初并没有做详尽的比较,只是喜欢Groovy语法更简洁罢了,

基于Jvm的脚本语言总也逃不开Java jars生态圈,做研究还有点区别(Scala Actor**/Fn **),真正应用(如做web开发),只看IDE的支持情况和个人对语言熟悉程度了

我个人推荐Javaer学一门脚本语言——我是懒,所以学了最简单的Groovy,想必Scala更有挑战性些,有C开发经历的Ruby更合口味吧
0 请登录后投票
   发表时间:2011-12-21  
groovy 不错,熟悉python的我,用不惯java ,用groovy倒是兴头一下子上来了

不过感觉groovy推广上做的不好,不像nodejs社区那么火热,网站也只是host 在codehaus,不弄一个独立的,看起来很不专业
0 请登录后投票
   发表时间:2011-12-21  
groovy 不错,有空看看。
0 请登录后投票
   发表时间:2011-12-21  

groovy 好像没有把函数做为一等公民,闭包是闭包,函数是函数,函数不能传递当闭包用.


class TestClass{
    def test


    def hello(){
        if (test){
            test('hello')
        }
    }
}
def test2={
    println  it
}



test2('test')

def t=new TestClass(test:test2)

t.hello()

如果把test2闭包改为函数

def test2(foo){
    println foo
}
就无法运行

还是我不会用
0 请登录后投票
   发表时间:2011-12-21   最后修改:2011-12-21
jjx 写道

groovy 好像没有把函数做为一等公民,闭包是闭包,函数是函数,函数不能传递当闭包用.


class TestClass{
    def test


    def hello(){
        if (test){
            test('hello')
        }
    }
}
def test2={
    println  it
}



test2('test')

def t=new TestClass(test:test2)

t.hello()

如果把test2闭包改为函数

def test2(foo){
    println foo
}
就无法运行

还是我不会用


。。。。在java里(groovy最终也编译成java),函数从来没有独立存在过吧——你这段groovy代码最终运行的时候报错,也是Class *****(文件名),TestClass是作为内部类处理的

java局限Jvm底层,只不过优雅点解决函数传递罢了(以闭包对象的形式)
0 请登录后投票
   发表时间:2011-12-21  
楼主写的不错. 自己做项目就用Grails2.0+ExtJS4.x,爽歪歪
0 请登录后投票
   发表时间:2011-12-21  
如果按这个理论的话,把函数包装在一个类中,成为一个静态方法就可以传递了,但事实上还是不行

看提示应该是函数不算属性,而def test={}这样的形式是可以作为属性读取的缘故

比python还是差了一些
0 请登录后投票
论坛首页 Java企业应用版

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