1: 变量定义和函数定义是在整个脚本执行之前完成的,而变量赋值是在执行阶段完成的。
变量定义的作用仅仅是给所声明的变量指明它的作用域,变量定义并不给变量初始值,任何没有定义的而直接使用的变量,或者定义但没有赋值的变量,他们的值都是 undefined。
函数定义除了声明函数所在的作用域外,同时还定义函数体结构。这个过程是递归的,也就是说,对函数体的定义包括了对函数体内的变量定义和函数定义。
例:
alert(a); //方法体
alert(c); //undefined
var a = "a";
function a() {}
function b() {}
var b = "b";
var c = "c";
var c = function() {}
alert(a); //a
alert(b); //b
alert(c); //方法体
猜猜这个程序执行的结果是什么?然后执行一下看看是不是跟你想的一样,如果跟你想的一样的话,那说明你已经理解上面所说的了。
这段程序的结果很有意思,虽然第一个 alert(a) 在最前面,但是你会发现它输出的值竟然是 function a() {},这说明,函数定义确实在整个程序执行之前就已经完成了。
再来看 b,函数 b 定义在变量 b 之前,但是第一个 alert(b) 输出的仍然是 function b() {},这说明,变量定义确实不对变量做什么,仅仅是声明它的作用域而已,它不会覆盖函数定义。
最后看 c,第一个 alert(c) 输出的是 undefined,这说明 var c = function() {} 不是对函数 c 定义,仅仅是定义一个变量 c 和一个匿名函数。
再来看第二个 alert(a),你会发现输出的竟然是 a,这说明赋值语句确实是在执行过程中完成的,因此,它覆盖了函数 a 的定义。
第二个 alert(b) 当然也一样,输出的是 b,这说明不管赋值语句写在函数定义之前还是函数定义之后,对一个跟函数同名的变量赋值总会覆盖函数定义。
第二个 alert(c) 输出的是 function() {},这说明,赋值语句是顺序执行的,后面的赋值覆盖了前面的赋值,不管赋的值是函数还是其它对象。
理解了上面所说的内容,我想你应该知道什么时候该用 function x(..) {…},什么时候该用 var x = function (…) {…} 了吧?
最后还要提醒一点,eval 中的如果出现变量定义和函数定义,则它们是在执行阶段完成的。所以,不到万不得已,不要用 eval!另外,即使要用 eval,也不要在里面用局部变量和局部方法!
2:javascript的构造函数
例: function classA()
{
//类成员函数不能直接调用,必须将其赋给一个this变量
function fnA()
{
alert("this is fnA");
}
this.A=fnA;
{
alert(11);
}
}
var test=new classA(); //此时打印出11
test.A(); //打印this is fnA; 这样就实现了成员函数的调用
3:
this 和执行上下文
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
<script type="text/javascript">
var x = "I'm a global variable!";
function method() {
alert(x);
alert(1);
alert(this.x);
}
function class1() {
// private field
var x = "I'm a private variable!";
// private method
function method1() {
alert(x);
alert(2);
alert(this.x);
}
var method2 = method;
// public field
this.x = "I'm a object variable!";
// public method
this.method1 = function() {
alert(x);
alert(3);
alert(this.x);
}
this.method2 = method;
// 构造函数
{
this.method1(); // I'm a private variable! 确定作用域在class1内部
// 3
// I'm a object variable!
this.method2(); // I'm a global variable! 确定作用域在class1内部
// 1
// I'm a object variable!
method1(); // I'm a private variable! 未确定作用域则为顶级作用域
//2
// I'm a global variable!
method2(); // I'm a global variable! 未确定作用域则为顶级作用域
//1
// I'm a global variable!
method1.call(this); // I'm a private variable! call改变执行上下文
//2
// I'm a object variable!
method2.call(this); // I'm a global variable! call改变执行上下文
//1
// I'm a object variable!
}
}
</script>
</head>
<body>
<script type="text/javascript">
var o = new class1();
alert("----------------分割条------------------")
method(); // I'm a global variable!
//1
// I'm a global variable!
o.method1(); // I'm a private variable!
//3
// I'm a object variable!
o.method2(); // I'm a global variable!
//1
// I'm a object variable!
</script>
</body>
</html>