JavaScript是一种动态解释型语言,这使得它和传统的编译型语言有着一些区别。这些区别引发出某些独特的概念和使用方法,简单举例说明。


在我的理解里,这些特点分别有:解释执行、弱类型、面向过程与面向对象相结合、相关性
一、
解释执行导致一个在编写代码时需要留意的方面——执行结果和语句的顺序有很大相关性:
比如:
1.script语句写在了某些html元素之前,而试图去操作这些元素,那么是不能成功的;


2.声明写在使用之后是不行的,而在编译型语言里编译时的语序影响通常不大,因为还没到执行时刻
比如在java中,这样是可以的:
private String test(){
return this.name;
}
private String name;


Script中这样是不行的:


(function test(){
alert(name);
})();
name="aaa";


3.在函数里定义一个全局变量,那么在这个函数没有执行之前,引用这个变量是不能成功的(尽管函数语句在变量引用之前)
function f1(){
test = 10;
}
f1(); //函数必须先执行过,下面的引用才能成功
alert(test);


二、弱类型
虽然也定义了Undefined、Null、Boolean、Number、String、Object六种数据类型,但属于弱类型语言,对于变量的使用和类型转换并不严格,所以经常有一些看似奇怪的语法。比如:
var num=5;
num="hello";
alert(num);


对函数调用时,参数类型和个数也没有要求:
function add(a,b){
return a+b;
}
alert(add(1,"2","hi",false)); //也没有问题


三、面向过程与面向对象相结合
可以象面向过程语言那样定义和调用函数,如:
function add(a,b){
return a+b;
}
add(1,2);
这是面向过程语言的特征。
同时函数可以作为一个对象/变量,如:
var add=function(a,b){
return a+b;
}
add(1,2);


常规语言里,对象意味着属性与方法的集合。属性与方法是有区别的。属性是数据,方法是动作(当然属性值可以是别的对象)。那么既然JavaScript函数可以成为对象,自然也可以作为属性值。所以实际上在JavaScript里,属性和方法是没区别的。于是统称为名称:属性,这样类似key-value的样式。


除了属性值可以采用函数,函数的参数、返回值也可以是函数。这种把函数作为参数或返回值带来一个比较纠结的问题————如果用变量把作为返回值的函数保存起来,那么这个函数随时执行应该没问题吧。问题是这个函数作为那个函数的返回值,它可能引用了那个函数里的某些东西。随时调用这个函数也就意味着包裹着它的那个外层函数也必须时时被保存,不能被释放。那这就是闭包了。有点绕嘴,看个例子:
function fout(){
var n=123;
return function fin(){
alert(n); //123
}
}
var f=fout();
f();


//尽管fout已经执行完成,但返回值被f保存起来,于是fout也不能被释放,里面的所有内容包括局部变量n也一直不能被释放,因为随时可能被f用到


闭包是其他语言里不具备的,就是因为JavaScript这种“函数是对象,对象是函数”绕出来的。


此处还可参考:《JavaScript作用域、上下文环境、函数对象的定义与调用、匿名函数的定义与调用、闭包》


四、
此外由于各个浏览器的实现细节有所差别,所以JavaScript在不同的浏览器中执行结果会有差异,这也是需要在使用中注意的。


比如:
function(event){
event.target.style.color="";
}
这是一个常见的事件处理函数,在firefox里必须要加上event参数,而在ie和chrome里则可以省略
再比如:
switch (event.type){
case "click":
errorMethod();
alert("click button");
break;
case "mouver":
event.target.style.backgroundColor="green";
break;
}
当其中一个case出现错误调用,firefox会认为整个事件处理函数都是错误的,拒绝执行。而在ie中则仅仅是错误的case不能执行,正确的case依旧会执行。


简单总结一下学习过程中遇到的思考点和迷惑点,总之JavaScript还是满有趣和强大的。