javascript概念
作用域: js没有块作用域,只有函数作用域
作用域链: 按序检索对象列表
自执行函数:拥有私有作用域
匿名函数:this -> window
初始化: 全局对象, 执行环境栈, 全局执行环境
类数组(伪数组): 可像数组索引,有length属性,但是没有数组的方法,其实是个对象
例: arguments是一个object对象
Array.prototype.slice.call(arguments, 0)是用来将arguments变量转换为真正的数组.
Arguments的属性callee都会指向当前的被调函数.(可用于递归匿名函数)
[1] callee与caller
caller返回一个函数的引用,这个函数调用了当前的函数;
使用这个属性要注意:
1. 这个属性只有当函数在执行时才有用
2. 如果在javascript程序中,函数是由顶层调用的,则返回null
var a = function() {
alert(a.caller);
}
var b = function() {
a();
}
b(); // var b = function() { a(); }
预编译: 声明提前(hoisting)
1)函数声明会置顶
2)变量声明也会置顶
3)函数声明 > 变量声明
4)变量和赋值语句一起书写,在js引擎解析时,会将其拆成声明和赋值2部分,声明置顶,赋值保留在原来位置
5)声明过的变量不会重复声明
同一个标识符的情况下,变量声明与函数声明都会提升;函数声明会覆盖变量声明,但不会覆盖变量赋值,即:如果声明变量的同时初始化或赋值,
那么变量优先级高于函数。
*多次声明变量,只取最后值
函数表达式
(1) 要清楚两者的区别:
(function {// code})是表达式, function {// code}是函数声明.
(2) js"预编译"的特点:
js在"预编译"阶段, 会解释函数声明, 但却会忽略表式.
(3) 当js执行到function() {//code}();时, 由于function() {//code}在"预编译"阶段已经被解释过,
js会跳过function(){//code}, 试图去执行(), 故会报错;
当js执行到(function {// code})();时, 由于(function {// code})是表达式, js会去对它求解得到返回值,
由于返回值是一 个函数, 故而遇到();时, 便会被执行.
(4) 函数转换为表达式的方法并不一定要靠分组操作符(),我们还可以用void操作符,~操作符,!操作符……
如:!function(){ alert("另类的匿名函数自执行"); }();