Javascript学习笔记三 之 函数

  Javascript相对于很多纯粹的面向对象和面向过程的语言有很大的区别,具备灵活性,这里我们先抛开它面向对象的特征讨论。

 

  对于大多数面向过程式的语言而言,函数就是一个有名称的代码段,方便重用。 

  例如,当我们需要大量数字求和的运算,如果在代码中大量使用加号运算符会浪费很多代码,

  于是我们可以将他们封装到一个函数体内,以后我们可以直接调用就可以使用了

    
    
function sum(a,b){
return a + b;
}
var n = sum( 1 , 2 );

 

1.函数基本概念

  (1)函数参数(arguments)——灵活的参数

  
  
function sum(){
var res= 0;
for(i=0;i<arguments.length;i++){
res
+=arguments[i];
}
return res;
}
sum(
1,2,3,4);

    在Javascript的函数中有个名为arguments的类似数组的对象。而它实际上并不是个数组,使用typeof arguments语句尝试会返回"Object"对象,所以它不能像Array一样使用push和pop等方法。即便如此,仍然可以使用下标以及长度(length)获取它的值。

代码
   
   
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< html >
< head >
< script language ="JavaScript" >
<!--
/* *
* arguments不是数组(Array类)
*/
Array.prototype.selfvalue
= 1 ;
function testAguments(){
alert(
" arguments.selfvalue= " + arguments.selfvalue);
}

alert(
" Array.sefvalue= " + new Array().selfvalue); // 打印 "Array.sefvalue=1"

testAguments();
// 打印 "arguments.selfvalue=undefined"
//
-->
</ script >
</ head >
< body >
</ body >
</ html >

 

   转化为实际的数组

  
  
var args = Array.prototype.slice.call(arguments);

  另外由于参数数不定,那么如何判断函数实际传入的参数和定义的参数

 

代码
   
   
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< html >
< head >
< script language ="JavaScript" >
<!--
/* *
* 演示arguments的用法,如何获取实参数和形数数
*/
function argTest(a,b,c,d){
var numargs = arguments.length;
// 获取被传递参数的数值。
var expargs = argTest.length;
// 获取期望参数的数值。
alert( " 实参数目为: " + numargs);
alert(
" 形数数目为: " + expargs);
alert(arguments[
0 ]);
alert(argTest[
0 ]); // undefined 没有这种用法
}
/* *
* 下面调用分别打印:
* "实参数目为:2"
* "形数数目为:4"
* "1"
* "undefined"
*/
argTest(
1 , 2 );

/* *
* 下面调用分别打印:
* "实参数目为:5"
* "形数数目为:4"
* "1"
* "undefined"
*/
argTest(
1 , 2 , 3 , 4 , 5 )
// -->
</ script >
</ head >
< body ></ body >
</ html >

  函数还有2个属性,一个是caller,一个是callee,分别获得该函数的引用,和形参数;

代码
   
   
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< html >
< head >
< script language ="JavaScript" >
<!--
/* *
* 演示函数的caller属性.
* 说明:(当前函数).caller:返回一个对函数的引用,该函数调用了当前函数
*/
function callerDemo() {
if (callerDemo.caller) {
var a = callerDemo.caller.arguments[ 0 ];
alert(a);
}
else {
alert(
" this is a top function " );
}
}

function handleCaller() {
callerDemo();
}

callerDemo();
// 打印 "this is a top function"

handleCaller(
" 参数1 " , " 参数2 " ); // 打印 "参数1"
//
-->
</ script >
</ head >
< body >
</ body >
</ html >

 

代码
   
   
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< html >
< head >
< script language ="JavaScript" >
<!--
/* *
* 演示函数的callee属性.
* 说明:arguments.callee:初始值就是正被执行的 Function 对象,用于匿名函数
*/
function calleeDemo() {
alert(arguments.callee);
}

calleeDemo();
// 打印 calleeDemo 整个函数体
( function (arg0,arg1){alert( " 形数数目为: " + arguments.callee.length)})(); // 打印 "形数数目为:2"
//
-->
</ script >
</ head >
< body >
</ body >
</ html >

 

 (2)作用域

    一个函数的执行,实际上是在当前作用域下,新建了一个子作用域.(注意下面的var的使用)  

  
  
function f1(){
var v1 = 1 ;
}
f1();
alert(v1);
// 报错

 由下可见,在函数体子作用域内不使用var,则定义的全局变量

  
  
function f2(){   
v1
= 1 ;
}
f2();
alert(v1);
// 1

  接下来一个例子我证明该全局变量的范围。

  
  
function f3(){

function f4(){   
v1
= 1 ;
alert(
" 现在在f4中v1等于 " + v1);
}
f4();
alert(
" 现在在f3中v1等于 " + v1);
}
f3();
alert(
" 现在在window中v1等于 " + v1);

 结果全部弹出,由此证明不使用var的全局变量是window的变量 

 

2.匿名函数

参考《javascript精粹》译者秦歌博客:http://dancewithnet.com/2008/05/07/javascript-anonymous-function/

 在Javascript定义一个函数一般有如下三种方式:

 

 函数关键字(function)语句:

  
  
function fnMethodName(x){

  alert(x);

}


函数字面量(Function Literals):

  
  
var fnMethodName = function (x){

  alert(x);

};

 

Function()构造函数: 

  
  
var fnMethodName = new Function( ' x ' , ' alert(x); ' );

上面三种方法定义了同一个方法函数fnMethodName,第1种就是最常用的方法,后两种都是把一个函数复制给变量fnMethodName,而这个函数是没有名字的,即匿名函数。

 

 匿名函数的代码模式

  错误模式:其无法工作,浏览器会报语法错。

function(){  alert(1);}();

  1. 函数字面量:首先声明一个函数对象,然后执行它。

  
  
( function (){alert( 1 );})();

  2.优先表达式:由于Javascript执行表达式是从圆括号里面到外面,所以可以用圆括号强制执行声明的函数。  

  
  
( function (){alert( 2 );}());

 3.Void操作符:用void操作符去执行一个没有用圆括号包围的一个单独操作数 

  
  
void function (){alert( 3 );}()

 

3.内部函数(Inner Function)

 

  把函数作为一个值来思考一下,既然一个值可以定义在函数中,把函数做为数据放在函数中也未尝不可。如下:


  
  
function outer(param){
function inner(theinput){
return theinput * 2 ;
}
return ' The result is ' + inner(param);
}

也可以写成:

  
  
var outer = function (param){
var inner = function (theinput){
return theinput * 2 ;
};
return ' The result is ' + inner(param);
};

 

inner函数在outer函数之中的 ,也就是意味着,在outer函数的外部是无法访问inner函数的。所以也称之为私有函数(private function);

如果要让外部能够访问内部,则需要使用闭包。

 

 内部函数的是使用还是有很多好处的。

1.可以有更少的全局变量。过多的使用全局变量就有可能由于命名冲突而产生过多的bugs

2.私有性,可以设计更好的接口函数供外部访问

你可能感兴趣的:(JavaScript)