读《javascript权威指南> 》第五版 第八章 函数

来源:互联网 发布:软件编程成果展板 编辑:程序博客网 时间:2024/06/04 18:57

1. 函数的定义与调用

1、当一个函数在一个对象上被调用时,它的调用所在对象就会成为函数的一个参数来传递
2、函数的return语句:
1. 有return语句,并带表达式,会终止函数的运行,并返回表达式的值
2. 有return语句,没有带表过式,会终止函数的运行,并返回undefined
3. 没有return语句,没有带表过式,自动执行到最后一条语句,并返回undefined
3、函数的参数,js不会检测函数的参数类型、参数个数,如果比原型更多则自动忽略,更少则会以undefined补上

2.嵌套的函数

1、使用function语句定义的被嵌套函数有可能只在它所嵌入的函数的最顶层定义,不会被嵌入到语句块中
2、函数直接量,

 var function(x){ return x*x}  function face(x){if (x<=1) return  1;else return x*fact(x-1)}  var tensquerd =( function(x){return  x*x;})(10)


3、函数命名,现在美元符号和下划线是除了字母和数字以外,可以用于js的合法标识符。

4、可变长度的参数列表,Arguments对象:
1). arguments 是一个类似数组对象
2). arguments 使我们可以定义一个任意长度的函数。
3).arguments 是一个普通的JS标识符,而不是一个保留字。如果函数有一个参数或者局部变量使用了这个名字,它就会隐藏对Argument对象的引用。
4)、属性callee 引用正在执行的函数 如:

function(x){    if(x<=1) return 1;    else return x*arguments.callee(x-1);}

3. 作为数据的函数

1、

function square(x){return x*x;}var a=square;c=a(10);//c contains the number 100a[0]=function(x){return x*x;}function add(a,b){return a+b;}function subtract(a,b){return a-b;}function multiply(a,b){return a*b;}function divide(a,b){return a/b;}function operate(operator,operand1,operand2){    return operator(operand1,operand2);}

4. 函数属性

1、length:形参的个数
如:arguments.callee.length;
2、定义自己的属性

uniqueInteger.counter=0;function uniqueInteger(){    return uniqueInteger.counter++;}


3、apply()和call() o.call(o,1,2) o.apply(o,[1,2])

5. 函数作用域和闭包

准备知识:
即作用域控制着变量与函数的可见性和生命周期
1. 全局作用域(Global Scope)
(1)最外层函数和在最外层函数外面定义的变量拥有全局作用域
(2)所有末定义直接赋值的变量自动声明为拥有全局作用域
(3)所有window对象的属性拥有全局作用域
2. 局部作用域
局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部 
3. 作用域链(Scope Chain)
函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。
这里写图片描述
4. 运行期上下文(execution context)”
执行此函数时会创建一个称为“运行期上下文(execution context)”的内部对象,运行期上下文定义了函数执行时的环境。每个运行期上下文都有自己的作用域链,用于标识符解析,当运行期上下文被创建时,而它的作用域链初始化为当前运行函数的[[Scope]]所包含的对象。
这些值按照它们出现在函数中的顺序被复制到运行期上下文的作用域链中。它们共同组成了一个新的对象,叫“活动对象(activation object)”,该对象包含了函数的所有局部变量、命名参数、参数集合以及this,然后此对象会被推入作用域链的前端,当运行期上下文被销毁,活动对象也随之销毁。新的作用域链如下图所示
这里写图片描述
准备知识结束。

1、词法作用域:在定义它们的作用域里运行,而不是在执行它们的作用域中运行。注,尽管当一个函数定义了的时候,作用域链就固定了,但作用域链中定义的属性还没有固定。

2、调用对象:activation object (call object ){arguments:Arguments对象,参数,局部变量} 意味着它会隐藏了作用域链更上层的同名的属性。

3、作为名字空间的调用对象:定义一个只是创建调用对象的函数,这个调用对象充当一个临时的名字空间,在这个名字空间中定义变量和创建属性,不会破坏全局的名字空间。代码如下:
第一种,

function init(){    //code goes here    //any variables declared become properties of the call object instead of cluttering up the global namespace.}init();

第二种,第一种给全局域加了一个init属性,第二种更省

function(){     //code goes herre      //any variables declared become properties of the call object instead of cluttering up the global namespace. })();


4、作为闭包的嵌入函数
例子1:

uniqueID=(function(){// The call object of this function holds our                        //value     var i=0;       //this is the private persistent value     //the outer function returns a nested function that has access     //to the persistent value;It is this nested function we are //storing in the variable uniqueID above     return function(){return i++;}//return and increment})();//Invoke the outer function after  defining it.

6. Function构造函数

1、Function()构造函数允许js 动态地创建并且运行时编译。

2、Function()构造函数解析函数体,且每次被调用都创建一个新的函数对象。

3、它所创建的函数并不使用词法作用域,相反,它总是当作顶层的函数一样来编译。

0 0