为了备战学校的卓越杯,整理了一下JavaScript的一些知识点。
JavaScript提供两种相等操作符。
(1)相等(==)和不相等(!=)
相等和不相等操作符工作时是先转换再比较。进行比较时,如果参数的类型不相同,这两个操作符会先对操作数进行强制转型,然后再比较它们的相等性。
转换类型时,相等和不相等操作符遵循以下准则:
1. false转换为0,true转换为1;
2. 字符串和数值比较,把字符串转为数值;
3. 对象和非对象比较,调用对象的valueOf()方法,再用得到的基本类型进行比较;
4. null和undefined相等;
5. 对于NaN,只要出现NaN的相等操作都返回false,不相等返回true;
6. 如果两个操作数都是对象,则比较是不是同一个对象。
(2)全等(===)和不全等(!==)
全等和不全等操作符工作时是仅比较而不转换。除了不强制转型外,全等和不全等操作符与相等和不相等操作符一样。
E.g:
“5” = = 5 true NaN = = NaN false
“5” = = = 5 false false = = null false
0 = = null false null = = = undefined false
在Web浏览器中,JavaScript的全局执行环境是window对象(大家都这么认为)。 当代码在一个环境中执行的时候,会创建变量对象的一个作用域链。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。
JavaScript的作用域和C、C++、Java等语言不完全相同。
对于函数来说,JavaScript和前几种语言一样,一个函数内部(局部环境)的变量不会能被外部(可能是包含它的函数的局部环境或者全局环境)访问到。
与C、C++、Java等语言不同的是,JavaScript没有块级作用域。
举个例子下面这段代码在C、C++、Java等语言中会报错,但是在JavaScript中能够成功执行。
if(true)
{
var ex=1; //声明变量
}
alert(ex); //执行成功,ex=1
同样,for循环中的i也会在for循环结束后仍然存在。
JavaScript声明变量可以通过关键字var或者直接声明变量。
比如:
var ex=1;
x=2;
但是,这两种方法声明是不一样的。不同点在于变量的作用域。通过var声明的变量会被自动添加到最近的环境中。如果初始化变量的时候没有使用var声明,该变量自动被添加到全局环境中。
变量声明了之后,在某个环境中想要访问某变量时,JavaScript会搜索该变量名。搜索的过程从作用域链的前端开始,即由“内”往“外”找,从局部环境逐级向上一直搜索到全局环境。一旦找到了就停止。请仔细分析下面的几个例子。
//example1
function test()
{
show=0;//声明变量show,因为没有var,该变量属于全局环境
}
test();
alert(show); //成功执行 弹出窗口显示 0
//example2
function test()
{
var show=0; //使用var声明变量,该变量会自动杯添加到最接近的环境中,
//也就是函数test的局部环境
}
test();
alert(show); //执行失败
//example3
var show=1
function test()
{
var show=0; //使用var声明变量,该变量会自动杯添加到最接近的环境中
alert(show);
}
test(); // 结果是0
alert(show); // 结果是1
//example4
var show=1
function test()
{
alert(show); // 结果是1
show=0; //使用var声明变量,该变量会自动杯添加到最接近的环境中
alert(show); // 结果是0
}
test(); // 结果是0
alert(show); // 结果是0
//example5
var show=1
function test()
{
alert(show); // 结果是undefined,因为全局变量在test()函数中已经被覆盖了
var show=0;//声明变量show,因为没有var,该变量属于全局环境
alert(show); // 结果是0
}
test();
alert(show);
JavaScript定义函数的方式有三种,分别是:
(1)定义命名函数。
语法格式如下:
function functionName (parameter_list)
{
statements
}
函数无须声明是否有返回值。
(2)定义匿名函数。
函数实际上是一个Function类的对象,所以可以将其赋值 给一个变量名,通过该变量名调用函数。格式如下:
var f = function (parameter_list)
{
statements
};
经过这样声明后,就可以通过调用f来调用该函数了。不要忘了最后的分号,因为是一个声明嘛,总要分号结束的。
(3)使用Function类声明匿名函数
格式如下:
var f = new Function (parameter_list)
{
statements
};
这种方式不推荐使用。
What’s more,定义匿名函数和定义命名函还是有区别的。看这个例子:
test();//成功执行
tr(); //执行失败
function test()
{
var show=3;//声明变量show,因为没有var,该变量属于全局环境
alert(show);
}
var tr=function()
{
tryNum=31;//声明变量show,因为没有var,该变量属于全局环境
alert(tryNum);
};
在这个例子中,test()函数能够执行成功,而tr()函数却失败了,为什么呢?事实上,在代码开始执行之前,解析器会通过一个名为函数声明提升的过程,读取并将函数声明添加到执行环境中。tr()函数处于一个初始化语句中,而不是函数声明。这一个细微的不同有时也需要引起大家的注意。
JavaScript的函数实际上也是对象。每个函数都是Function类型的实例,具有属性和方法。我们可以把函数名想象成指针,所以JavaScript没有函数重载的概念,假如声明了重名的函数,结果会是后面的函数覆盖了前面的函数。
JavaScript中所有函数的参数都是按值传递的。
函数的名字仅仅是一个包含指针的变量。同一个函数可以在不同的环境中执行,在不同的环境下,this所指的值也不同。JavaScript中的this引用的是函数据以执行的环境对象。this可以理解为,谁调用了这个函数this就指向谁。比如正常情况下调用函数test(),这时test()的this指向了window对象。再比如person.smile()中,this指向了person这个对象。
setTimeout("function",time) ; setInterval("function",time);
setInterval为自动重复,setTimeout只在指定时间后执行一次,不会重复。
在JavaScript中,每个函数都包含两个非继承而来的方法:apply()和call()。这两个方法的用途是在特定的作用域中调用函数,实际上等于设置函数体内的this对象的值。
apply()方法接受两个参数:一个是在其中运行函数的作用域,另一个是参数数组。例如:func.apply(this,arguments)。
call()方法和apply()方法的作用相同,区别在于接受参数的方式不同。对于call()方法而言,第一个参数和apply()方法一样都是this,后面的参数则需要一个个列举出来。什么时候用call()什么时候用apply(),取决与怎么传递参数方便而已。
caller是函数对象的一个属性,这个属性中保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,它的值是null。
在函数对象中,有两个特殊的对象:arguments和this。callee就是arguments的一个属性,这个属性是一个指针,指向拥有这个arguments对象的函数。callee的一个用途是用于递算法中替代要重复用到的函数名,使得函数的执行和函数名松绑。因为函数名可以理解为一个变量,所以一个函数可以复制给另一个变量,然后用新的名字去运行。例如,var newFac = fac; 这里fac是一个函数名,经过这条语句后调用newFac也可以执行这个函数,但如果这个函数是递归函数,里面就必须用arguments.callee,否则会运行失败。
如有不正确的地方,恳请评论或留言指出,不胜感激。
参考书籍:JavaScript高级程序设计(第3版)、疯狂HTML5/CSS3/JavaScript讲义