面向 Java 开发人员的 JavaScript【来源于网络】

当时和现在:为何 JavaScript 很重要

Netscape 于 1995 年引入了 JavaScript,它很快就流行起来了。最主要的原因是 Web 作为商业媒体平台的出现:使用 JavaScript,您(依然)可以通过编程来影响浏览器中 Web 页面的特性。那这是个很棒的工具!HTML 表单验证与受限图片欺骗(limited image trickery)是主题。

自那时起 JavaScript 就具有多个化身。Netscape 曾一度拥有一个产品,Netscape Application Server,它正是基于服务器端 JavaScript 来构建的 Web 应用程序。多年以后,由于 Ajax 和 Prototype、JQuery、和 Extjs 之类部件库的引入,重新引起了人们对 JavaScript 的兴趣。最近,服务器端 JavaScript 被用于 Node.js 当中,这是利用 Google's V8 JavaScript 引擎构建服务器端 Web 应用程序的基于事件的 I/O 框架。

Netscape 做了一件很有前瞻性的事,就是把 JavaScript 提交到 Ecma International 来进行标准化。这就是人们称 JavaScript 为 ECMAScript 的原因。更重要的是,这也是众多 Web 浏览器支持 ECMAScript 的原因。因此,Web 应用程序大都会采用 JavaScript,这一点没有改变过。目前还没有能与之相比的其他浏览器兼容脚本语言。

Node.js

Node.js(见 参考资料Resources)是服务器端、高并发、基于事件的框架。在处理大量有关并发编程的问题时,Node.js 程序比具有线程的程序效率更高。Node.js 相对比较新,围绕该技术的创新令人期待。了解 JavaScript 是使用 Node.js 相关工具的关键。

当前,尽管 JavaScript 的名声不好,它仍然是应用最广(最有用)的语言之一。如果您是位 Java 程序员(或者 Ruby、Python、或 PHP 程序员),那么您可能曾用过 JavaScript ,或者在不久的将来会使用 JavaScript。了解 JavaScript 的一些特性,有助于构建优秀的 Web 应用程序。此外,这有助于使用 Node.js,甚至还能增强您对 GWT 内部技术的了解。

在下一小节中,我将关注 JavaScript 语法的主要元素,重点介绍一些细节内容,这将有助于 Java 开发人员的提高。然而,我首先想打破一个关于 JavaScript 的神话:就是您需要一个 Web 页面来与其交互。

 

在 Chrome 中使用 JavaScript

在过去,JavaScript 需要浏览器,并间接地需要一个 Web 页面来执行。这对于一些开发人员来说是个麻烦,甚至是个障碍。幸运的是浏览器已经发展了;今天不论 Firefox 还是 Chrome 都提供了用于执行 JavaScript 的 IDE。

我喜欢 Chrome 漂亮的 JavaScript 控制台。就像 Ruby's IRB 或者 Python's shell,Chrome 提供不需要 Web 页面的用于浏览 JavaScript 的交互式环境。

CoffeeScript

如果您喜欢 JavaScript 的功能,但不喜欢它的语法,那么您可以尝试一下 CoffeeScript。CoffeeScript 是 “编译成 JavaScript 的小型语言” — 也就是说,CoffeeScript 通过简化 JavaScript 的一些语法,使 JavaScript 编程更加方便。CoffeeScript 更像 Ruby 或者 Python,但能提供 JavaScript 的效果。见 参考资料 中 CoffeeScript 的相关内容。

想要了解 Chrome's JavaScript 控制台,需要 下载用于您 OS 中的 Chrome。然后,打开一个新的空白标签(也就是说,不要指向 Web 页面)并选择 View > Developer > JavaScript Console。在 Chrome 窗口的底部,会弹出 JavaScript 开发人员控制台。可通过选择控制台左下角的 Undock 图标来使其成为独立对话框。然后可选择右上角的 Console 图标,来打开用于和 JavaScript 交互的空白窗口,如图 1 所示:


图 1. 在 Google Chrome 中与 JavaScript 交互

.
现在来看一些语法。


JavaScript 变量

JavaScript 是一个比较容易使用的语言,它能容忍很多编程错误,并仍然能在加载的 Web 页中执行。JavaScript 元素经常没有任何提示就失败了,这大部分都是好消息。如果 JavaScript 语言草率地禁止页面加载,那么早期的 Web 将是一片混乱。也就是说,当我们利用 JavaScript 来做我们喜欢做的事时(比如异步更新页面状态),草率使用 JavaScript 将付出代价。由于这个原因,Java 开发人员应该花时间真正了解 JavaScript 语法的特定方面。

JavaScript 变量的处理对理解来说很重要。例如,您想定义一个变量 foo,可以直接定义或者通过 var 声明,如清单 1 所示:


清单 1. 变量 foo

				
foo = 'foo'
var bar = 'bar'

清单 1 中的 foo 是 JavaScript 中的有效变量。但它缺少 var 声明,这是个全局变量。因此利用 var 定义的变量是有范围的(例如,在定义它的函数中)。

通常,全局变量比较麻烦。它们很容易造成变量使用的混乱,因为全局变量可在 JavaScript 应用程序中的任何地方进行访问和改变,这将导致潜在 bug。因此,当在 JavaScript 中编程时,不要忘了对变量应用 var


基元和对象

尽管 JavaScript 不够完善,但在类型方面十分简单。事实上,JavaScript 仅有 4 个基本类型,其中三个是基元。JavaScript 的基元类型是 NumberString、和 Boolean。您可通过 JavaScript typeof 运算符来在操作中查看这些类型。

我们来一起看一下该问题。在 Chrome's JavaScript 中,输入清单 2 中的内容:


清单 2. Activating types

				
var string = "test"
typeof string

可以看到控制台输出值 “string”。还要注意在 JavaScript 中分号是可选的。正如在流行的语言当中一样,string 通过引号来划定;因此,数字通过数字来划定。Booleans 通过值 true 或者 false 来划定,没有分号。


清单 3. JavaScript truth 与 numbers

				
var aNumber = 10
var anotherNumber = 0.99
var aBool = true
var notABoolean = "false"

您会注意到,JavaScript 不区分数字类型;数字就是数字,只不过具有不同格式。

JavaScript 还支持通用对象,它本身具有实例类型,比如 Array,如清单 4 所示:


清单 4. Array 的实例

				
> var myArray = ["Hello", 1, true]
> typeof myArray
"object"
> myArray instanceof Array
true

JavaScript 中的 Arrays 更像其他语言中的列表:可不必限制大小来进行创建,可以保存任何您输入的内容。比如在 Ruby 或者 Groovy 中,JavaScript Arrays 可通过文字语法来创建:[]。更重要的是,就像在其他支持列表的语言一样,希望在 JavaScript Arrays 支持方法(如清单 5 所示):


清单 5. Array 方法

				
> var myArray = ["Hello", 1, true]
> myArray[0]
"Hello"
> myArray.length
3
> myArray.pop()
true
> myArray
["Hello", 1]
> myArray.pop()
1
> myArray
["Hello"]
> myArray.push("pushed")
2
> myArray
["Hello", "pushed"]

可通过 Array 的位置来获取其值,从零开始。Arrays 支持pushpop 操作,其中 push 增加项目(在其最后一个位置)而 pop 移除项目(就像堆栈,从最后一个开始)。

Arrays 还支持迭代,如清单 6 所示:


清单 6. 通过 Array 迭代

				
> var myArray = [1,2]
> for(var i = 0; i < myArray.length; i++) { console.log(myArray[i]) }
1
2

类型强制

JavaScript 不仅是一个弱类型的语言 — 它比 Ruby 或者 Groovy 更弱 !JavaScript 可强制变量在代码的特定位置为任何类型。这符合 JavaScript 最初设想:Web 页面交互。JavaScript 不应草率地禁止用户读取在线文章!

类型强制不仅限于 JavaScript,但是 JavaScript 的特点是非常灵活。这是好事还是坏事,取决于您怎么看。JavaScript 的松散可能会隐藏缺陷,就像全局变量一样。

例如,先定义 Array 然后无意中尝试用于进行一些数字操作,甚至是一些 String 级联,如清单 7 所示:


清单 7. JavaScript 类型的灵活性

				
> var myArray = [1,2]
> console.log(2 * myArray)
> console.log("A" + myArray)

在本例中,第一个日志消息将会打印 NaN,而第二个将会打印 A1,2。在两个例子中,该代码能 “正常运行”,因为没有任何错误发生 — JavaScript 只是不停地运转。这是极端情况下的弱类型。Ruby 中同样的代码不会这样运行,如清单 8 所示:


清单 8. Ruby 不采用那种方式

				
> array = ["A", "B"]
> ans = 2 * array

清单 8 中的 Ruby 代码将会出错:

 

TypeError: Array
can't be coerced into Fixnum

如果尝试向 array 增加 "A",情况将是:

 

TypeError: can't convert
Array into String

如果在 Groovy 中尝试相同的操作,将会得到如下结果:

groovy.lang.MissingMethodException: No signature of method: 
java.lang.Integer.plus() is applicable for argument types: (java.util.ArrayList) values:
[[A, B]]

因此,您可以在操作中看到不同层面的弱类型。显而易见,如果有一个度量类型强弱的标准,JavaScript 将会是它们当中最弱的!


JavaScript 函数

JavaScript 函数,类似于 Java 方法,是用于定义和封装可重用行为的结构。JavaScript 中的函数看上去很像 Groovy 的闭包。在 JavaScript 中的函数是对象。事实上,他们是第一类对象,不像 Java 代码中的方法。因为 JavaScript 函数是对象,所以它可传递给其他函数,并可被调用。

利用 function 关键字来定义函数。就像 Java 语言中的方法声明一样,可以指定参数,还可从 JavaScript 函数返回一些内容。与动态语言不同,比如 Groovy 或者 Ruby,其中返回调用是可选的(这样任何方法的最后一行将返回),如果想要得到返回值,JavaScript 的函数中必须使用 return 语句;否则,将不会返回值。

可以像在 Groovy 中调用闭包一样来在 JavaScript 中调用函数。在清单 9 中,定义了一个没有参数的简单函数。其目的是在 Chrome 的 JavaScript 控制台中打印 “blah”。


清单 9. 在 JavaScript 中定义并调用函数

				
> function blah() { console.log("blah"); }
> blah() //prints blah
> blah.call() //prints blah
> blah.apply() //prints blah

可通过方法 call 或者方法 apply 直接调用有括号(也就是 ())的函数。在这里展示了首个无类函数对象。清单 10 展示了在函数 blah 中调用 garbage 方法时的情形:


清单 10. JavaScript 中函数作为对象

				
> blah.foo()

在本例中,错误消息说明 foo 不是一个定义的方法,像这样:

 

TypeError: Object function blah() { console.log("blah"); } has no method 'foo'

现在再次读取错误消息。看到 foo 不是 已定义的,这意味着如果它 定义,一切就会正常。


JavaScript 中的类

JavaScript 支持原语,我们曾讨论过。它也支持对象,比如 Array。JavaScript 不支持类 — 至少在经典 Java 语言中不支持。因为 JavaScript 是基于原型的语言,您不能定义类:相反,通过克隆 现有对象来重用行为。因此,在 JavaScript 中,不定义类对象,而在函数中进行定义,然后利用嵌套函数来定义行为 — 有些已在运行中见过。

想要模拟一个类,您必须定义一个函数。可以给其一个名称(也就是一个类名),指定参数(和在构造函数中一样),甚至可以使用关键字 .this,这意味着在函数范围内引用变量。更何况,内部函数可以具有别名,看上去像方法调用一样。

为了进行说明,在清单 11 中,我将创建一个 Message 原型(也称为一个类),这非常简单。我将提供一些参数(消息从何处来,发给谁,以及消息本身),而且该类将会以 JSON 格式呈现该消息。


清单 11. JavaScript 中函数作为类

				
function Message(to, from, msg){
 this.to = to;
 this.from = from;
 this.msg = msg;

 this.asJSON = function(){
  return "{'to':'" + this.to + "', 'from':'" + this.from + "', 'message':'" +
    this.msg + "'}";
 }
}

清单 11 中,我定义了一个 Message 函数 — 带有一个名字和几个属性的对象;即,tofrom、和 msg。然后我定义了一个属性(asJSON)指向内部函数,其任务是将 JSON 消息用字符串表示。

注意,还可在 Web 页面中定义该 “类”,利用 Chrome 来进行加载,打开 JavaScript 控制台,并交互式地进行使用。这就是清单 12 所述的:


清单 12. 在 JavaScript 中使用类

				
> var message = new Message('Andy', 'Joe', 'Party tonight!');
> message.asJSON();
"{'to':'Andy', 'from':'Joe', 'message':'Party tonight!'}"

此代码很像 Groovy 代码,甚至像 Java 代码(如果不考虑 var),不是吗?实际上,完全可以利用 OOP 技术来构建 JavaScript 应用程序(也就是,程序包含带有数据和相互交互方法的对象)。


结束语

我希望这篇文章能够推翻早已过时的 JavaScript 语言无用论。事实上,它的功能十分强大,而且具有很多语法糖,可以像 Groovy 和 Ruby 之类新的语言一样方便。在 90 年代使得 JavaScript 流行的一些特性,在今天也是可取的。

鉴于 Web 对越来越多的 Java 应用程序开发的重要性,以及 JavaScript 作为浏览器兼容语言的独特地位,每个 Java 程序员都应当熟悉 JavaScript。 浏览器(不论是在计算机中,或者在移动设备、电话、或者平板电脑中)是越来越多用户与应用程序交互的方法。JavaScript 是所有服务器端语言中最常见的媒介。此外,对 JavaScript 有一定理解,将会使您成为任何语言领域(包括您最熟悉的语言)的一名优秀的程序员。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值