本文总结 JavaScript 开发中的常见基础问题,涵盖变量与方法的严格大小写敏感规则、字符串单双引号的使用规范及 XHTML 兼容性、括号作为分隔符与表达式的双重语义、函数调用与引用的区别、JS 不支持重载的特性,以及通过具体代码示例深入解析作用域与闭包机制,帮助开发者避免常见陷阱。
JavaScript 基础语法规范
在 JavaScript 中,所有的标识符(包括方法和变量名)均严格区分大小写。
在 JavaScript 中,单引号和双引号在创建字符串时功能相同,没有本质区别。然而,作为一种通用编码规范,多数开发者倾向于使用单引号。需要注意的是,XHTML 规范要求所有属性值必须使用双引号包裹。因此,在 JavaScript 代码中使用单引号,而在 XHTML 标记中使用双引号,可以使混合代码的结构更加清晰且易于维护。
单引号字符串内部可以包含双引号,同理,双引号字符串内部也可以包含单引号。
关于括号的使用。
需要明确的是,JavaScript 中的括号具有两种不同的语义:既可作为分隔符,也可作为表达式的一部分。
a、作为分隔符:这是大家非常熟悉的用法,例如在数学运算中 (1+3)*3 等于 12。
b、作为表达式:例如 (function(){})(); 这种写法中,function 之前的一对括号起到分隔符的作用,而随后的括号则表示立即执行该函数。
关于函数调用与引用的区别。
由于括号代表函数的执行,因此:
var foo=example(); 这行代码表示 foo 接收的是函数的返回值。
var foo1=example; 这行代码表示将函数本身的引用赋值给变量 foo1,而非执行结果。
关于函数重载。
JavaScript 原生不支持函数重载,因此这里提到的“重载”实际上更接近于函数替换的行为。
JavaScript 不区分调用时传递的参数个数,即无论传递多少个参数,都执行同一个函数定义。
作用域与闭包机制解析
关于作用域与闭包。
作用域是指对某一属性或方法具有访问权限的代码空间。例如:
代码如下:
function myFunction(){
var temp="abc";
} 上述代码中的 temp 变量在函数外部无法被访问。
闭包是与作用域紧密相关的概念,它指的是内部函数即便在外部函数执行完成并终止后,仍然可以访问其外部函数的属性。
下面我们就作用域和闭包来举个例子:
我们建立如下 html 页面:
代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">}
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
<script language="javascript" type="text/javascript">
function init(){
for(var i=1;i<=3;i++){
author=document.getElementById("author"+i);
author.onclick=function(){
alert("author"+i);
}
}
}
window.onload=init;
</script>
</head>
<body>
<a id="author1" href="#">abc</a><br />
<a id="author2" href="#">abc</a><br />
<a id="author3" href="#">abc</a><br />
</body>
</html> 运行结果:
pic
可以看到,这并不是我们想要的。
进行修改后,关键代码如下:
代码如下:
<script language="javascript" type="text/javascript">
function init(){
for(var i=1;i<=3;i++){
author=document.getElementById("author"+i);
registerListener(author,i);
}
}
function registerListener(author,i){
author.onclick=function(){
alert("author"+i);
}
}
window.onload=init;
</script> 这样,我们就得到了我们想要的结果。
这是因为 init 每次调用都产生 function 的一个实例,每个实例里都维护了一个新的 i
而对于匿名函数的上一级已经有这个 i,而且已经和 init 里的 i 不一样了。