1. arguments
An array-like object corresponding to the arguments passed to a function.
arguments.callee
Reference to the currently executing function.
arguments.caller --- arguments.callee.caller
(Obsolete)
Reference to the function that invoked the currently executing function.
arguments.length
Reference to the number of arguments passed to the function.
function myConcat(separator) { var result = ""; // iterate through non-separator arguments for (var i = 1; i < arguments.length; i++) { result += arguments[i] + separator; } return result; } document.write(myConcat('-', "red", "green", "blue"));
递归
var foo = function bar() { // statements go here};
在函数体内,以下是等价的
- bar()
- arguments.callee()
- foo()
function loop(x) { if (x >= 10) // "x >= 10" is the exit condition (equivalent to "!(x < 10)") return; // do stuff loop(x + 1); // the recursive call}loop(0);
嵌套函数和闭包 (nested function and clousurs)
嵌套函数对外部函数是私有的。也可以形成闭包。
内部函数可以用外部函数的输入参数和变量,但外部函数不能用内部函数的变量和传入参数
function outside(x) { function inside(y) { return x + y; } return inside;}fn_inside = outside(3); result = fn_inside(5); // returns 8result1 = outside(3)(5); // returns 8
多层嵌套函数
function A(x) { function B(y) { function C(z) { alert(x + y + z); } C(3); } B(2);}A(1); // alerts 6 (1 + 2 + 3)
1. B 形成一个包含A的闭包。 B可以访问A的arguments and variables
2. C形成A的闭包
3. 因为b的闭包包含A, C的闭包包含A, C可以同时访问B和C的输入参量和变量。
当变量冲突的时候,遵从chain的访问规则
Function
Every function in JavaScript is actually a Function
object.
属性 和 方法
属性:
An array corresponding to the arguments passed to a function
function test(a) { // do something }
Apply :
Calls a function with a given this
value and arguments
provided as an array.
解析过程
1. 执行顺序
编译型语言,编译步骤分为:词法分析、语法分析、语义检查、代码优化和字节生成。
解释型语言,通过词法分析和语法分析得到语法分析树后,就可以开始解释执行了。这里是一个简单原始的关于解析过程的原理,仅作为参考,详细的解析过程(各种JS引擎还有不同)还需要更深一步的研究
JavaScript执行过程,如果一个文档流中包含多个script代码段(用script标签分隔的js代码或引入的js文件),它们的运行顺序是:
- 步骤1. 读入第一个代码段(js执行引擎并非一行一行地执行程序,而是一段一段地分析执行的)
- 步骤2. 做词法分析和语法分析,有错则报语法错误(比如括号不匹配等),并跳转到步骤5
- 步骤3. 对【var】变量和【function】定义做“预解析“(永远不会报错的,因为只解析正确的声明)
- 步骤4. 执行代码段,有错则报错(比如变量未定义)
- 步骤5. 如果还有下一个代码段,则读入下一个代码段,重复步骤2
- 步骤6. 结束
2、特殊说明
全局域(window)域下所有JS代码可以被看成是一个“匿名方法“,它会被自动执行,而此“匿名方法“内的其它方法则是在被显示调用的时候才被执行
3、关键步骤
上面的过程,我们主要是分成两个阶段
- 解析:就是通过语法分析和预解析构造合法的语法分析树。
- 执行:执行具体的某个function,JS引擎在执行每个函数实例时,都会创建一个执行环境(ExecutionContext)和活动对象(activeObject)(它们属于宿主对象,与函数实例的生命周期保持一致)
3、关键概念
到这里,我们再更强调以下一些概念,这些概念都会在下面用一个一个的实体来表示,便于大家理解
- 语法分析树(SyntaxTree)可以直观地表示出这段代码的相关信息,具体的实现就是JS引擎创建了一些表,用来记录每个方法内的变量集(variables),方法集(functions)和作用域(scope)等
- 执行环境(ExecutionContext)可理解为一个记录当前执行的方法【外部描述信息】的对象,记录所执行方法的类型,名称,参数和活动对象(activeObject)
- 活动对象(activeObject)可理解为一个记录当前执行的方法【内部执行信息】的对象,记录内部变量集(variables)、内嵌函数集(functions)、实参(arguments)、作用域链(scopeChain)等执行所需信息,其中内部变量集(variables)、内嵌函数集(functions)是直接从第一步建立的语法分析树复制过来的
- 词法作用域:变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,通过静态分析就能确定,因此词法作用域也叫做静态作用域。 with和eval除外,所以只能说JS的作用域机制非常接近词法作用域(Lexical scope)
- 作用域链:词法作用域的实现机制就是作用域链(scopeChain)。作用域链是一套按名称查找(Name Lookup)的机制,首先在当前执行环境的 ActiveObject 中寻找,没找到,则顺着作用域链到父 ActiveObject 中寻找,一直找到全局调用对象(Global Object)
来源:https://www.cnblogs.com/jackyweb/archive/2012/01/30/2332353.html