第7章 函数表达式
- 匿名函数的name属性是空字符串;
- 闭包是函数:闭包是有权访问另一个函数作用域中变量的函数;(P181 副作用,解释了点击li弹出循环最后值的原因)
- 当某个函数第一次被调用时,会创建一个执行环境及相应作用域链,并把作用域链赋值给一个特殊内部属性[[scope]],使用this、arguments和命名参数来初始化函数的活动对象;
- 无论什么时候在函数中访问一个变量时,就会从作用域链中搜索具有相应名字的变量。一般来讲,当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局作用域(全局执行环境的变量对象);
- 闭包不然:在函数内部定义的函数,会将外部函数的活动对象,添加到自己的作用域链中;
- 闭包的副作用:闭包只能取得外部函数中任何变量的最后一个值;
function createFunctions() {var result = new Array()for(var i = 0;i < 10; i++){return[i] = function() {return i}}return result
}
// 每个函数的作用域链中都保存着createFunctions()函数的活动对象,它们引用同一个变量i
- 创建一个匿名函数,强制让闭包的行为符合预期:
function createFunctions() {var result = new Array()for(var i = 0;i < 10; i++){return[i] = function(num) {return function() {return num}}(i)}return result
}
//没有直接将闭包赋值给数组;
//定义了一个匿名函数,并将立即执行该函数的结果赋值给数组;
//匿名函数有参数num,也是最终函数要返回的值;
//在调用每个匿名函数时,传入变量i,函数参数是按值传递的,会将变量i的当前值传给num
//匿名函数的内部,又创建并返回了一个访问num的闭包
- 匿名函数的执行环境具有全局性,其this对象通常指向window:
var name = "The Window"
var obj = {name: "My Obj",getNameFunc: function(){return function(){return this.name}}
}
obj.getNameFunc()() // The Window
- JavaScript不会告诉你是否多次声明了同一个变量,遇到这种情况,它会对后续的声明视而不见;
- 用匿名函数来模仿块级作用域:
(function(){// 这里是块级作用域
})()
错误写法:
function(){// 这里是块级作用域
}()
错误: 函数声明后面不能跟圆括号
第8章 BOM
- window对象
- location对象
- navigator对象
- screen对象
- history对象
- 尝试访问未声明的变量会抛出错误,但是通过查询window对象,可以知道某个可能未声明的变量是否存在:
var b = a //报错,这里a未定义
var c = window.a // c的值是undefined
第9章 客户端检测
- 能力检测:
1) 先检测达成目的的最常用的特性(避免测试多个条件)
2) 必须测试实际要用到的特性
第10~12章 DOM
- NodeList是有生命、呼吸的对象,而不是在我们第一次访问它们的某个瞬间拍摄下来的一张快照;
- 如果列表中只有一个节点,那么该节点的nextSibling和previousSibling都为null;
- ownerDocument是所有节点都有的属性,指向整个文档的文档节点;
第13章 事件
- 建议使用事件冒泡;
- 事件处理程序中的代码在执行时,有权访问全局作用域中的任何代码;
- 在HTML中指定事件处理程序的缺点:
1)存在时差问题:用户可能在页面刚显示按钮时,就点击,如果点击事件是在按钮下方、页面的最底部定义的,就会引发错误,可以封装在try-catch块中;
2)事件处理程序的作用域链在不同浏览器中可能会有不同效果;
3)HTML和JavaScript紧密耦合; - 事件对象:
1) DOM中:event对象作为参数;
2) IE中:event对象作为window对象的属性