一 参考文献
《JavaScript忍者秘籍》
二 函数特征总结
1. 函数是【第一型对象(first-class object)】:可以像这门语言的其它对象一样使用
函数可以共处,可以将其视为其它任意类型的JavaScript对象;
普通的JavaScript数据类型,函数可以被任意变量进行引用,
或者声明成对象字面量,甚至可将其作为函数参数进行传递。
①可以通过【字面量】[创建]
②可以[赋值]给【变量】、【数组】或【其他对象的属性】
③可以作为一个独立实体的【参数】[传递]给函数(见样例1)。
④可以作为【函数的返回值】进行[返回]
⑤可以拥有[动态创建并赋值]的【属性】
⑥可以在【任何地方】[创建]函数(即 只要能使用本门语言表达式的地方,就能创建函数,包括:匿名函数、即时函数等)
2. 浏览器的事件轮询
①事件相互穿插发生。
浏览器事件[页面加载完成、页面卸载]、
网络事件、
用户事件[鼠标点击、移动、按键]、
计时器事件
②浏览器的事件轮询是【单线程】的。
③每个事件都在自己的生命周期中进行处理,所有其他事件必须等到这个事件处理结束后才能继续处理。

3. 回调概念
定义:
①当我们定义一个(回调)函数稍后执行,无论何时定义、或者何处执行(在浏览器执行海曙其他地方执行)
②定义一个函数,以便其他一些代码在适当的时机再回头调用它(>回调函数)。
③可以将函数作为参数,传递给另一个函数,并在随后对该函数进行调用。
样例1
function useless(callback){ return callback(); } var text = 'Johnny'; console.log(useless(function(){ return text; }) == text);//true
样例2

var count = 1; var MAX_COUNT = 2; function A(messageA,fn1,arg1){ console.log("A:",messageA); C("A call C"); fn1(arg1); setTimeout(B("A call B once again after 1000ms"), 1000);//A再次回调B,二者形成了双向沟(调)通(用) } function B(messageB,fn2){ //启动入口:B(" startup from B"); console.log("B:",messageB); if(count < MAX_COUNT){ count++; A("B call A",function(msg){ console.log(msg); },"B call A's others arg/function"); } } function C(messageC,fn3){ console.log("C:",messageC); B("C call B"); }
test/output:
B("Startup from B"); B: Startup from B A: B call A C: A call C B: C call B B call A's others arg/function B: A call B once again after 1000ms
4.函数声明
格式:function [名称可选]([arg1,arg2,...,argN]) { ... }
[]表示:可选,非必须
5.作用域和函数
意义:当我们声明一个函数时,不仅要关注该函数可用的作用域,还要关注该函数自身所创建的作用域,以及函数内部的声明是如何影响这些作用域的。
特征:
1.在JavaScript中,作用域是由function进行声明的,而不是代码块【()、{}等】。
比如:if(...) { } //并不能像其他语言一样形成作用域
2.变量声明的作用域开始于:声明的地方;结束于所在函数的结尾,与代码嵌套无关。
3.机制提升:命令函数的作用域是指声明该函数的整个函数范围,与代码嵌套无关。
4.对于作用域声明,全局上下文就像一个包含页面所有代码的超大型函数。
function outer(){ assert(typeof outer == 'function',"1 outer() is in scope"); //true assert(typeof inner == 'function',"2 inner() is in scope"); //true assert(typeof a == 'number',"3 a is in scope"); assert(typeof b == 'number',"4 b is in scope"); assert(typeof c == 'number',"5 c is in scope"); var a = 1; function inner(){ assert(typeof inner == 'function',"6 inner() is in scope"); //true assert(typeof a == 'number',"7 a is in scope"); //true assert(typeof b == 'number',"8 b is in scope"); //true assert(typeof c == 'number',"9 c is in scope"); //true } var b = 2; if(a == 1){ assert(typeof a == 'number',"10 a is in scope"); //true assert(typeof b == 'number',"11 b is in scope"); //true assert(typeof c == 'number',"12 c is in scope"); var c= 3; } assert(typeof a == 'number',"13 a is in scope"); //true assert(typeof b == 'number',"14 b is in scope"); //true assert(typeof c == 'number',"15 c is in scope"); //true inner(); } outer(); assert(typeof outer == 'function',"16 outer() is in scope"); //true assert(typeof inner == 'function',"17 inner() is in scope"); assert(typeof a == 'number',"18 a is in scope"); assert(typeof b == 'number',"19 b is in scope"); assert(typeof c == 'number',"20 c is in scope");
output:
1 outer() is in scope 2 inner() is in scope 3 a is in scope 4 b is in scope 5 c is in scope 10 a is in scope 11 b is in scope 12 c is in scope 13 a is in scope 14 b is in scope 15 c is in scope 6 inner() is in scope 7 a is in scope 8 b is in scope 9 c is in scope 16 outer() is in scope 17 inner() is in scope 18 a is in scope 19 b is in scope 20 c is in scope
s