`

JAVASCRIPT基础学习篇(9)--ECMAScript Basic5(EcmaScript Function)

阅读更多

第五章 方法


1、The basic syntax is:


function functionName(arg0, arg1,...,argN) {
statements
}

如果方法有返回值,不需要声明返回的类型就象JAVA的VOID一样如:

function sum(iNum1, iNum2) {
return iNum1 + iNum2;
}

The value of the sum function is returned and assigned to a variable like this:
var iResult = sum(1,1);
alert(iResult); //outputs “2”

Another important concept is that, just as in Java, the function stops executing code after a return statement is executed.(return后面的语句将不再执行)

If a function doesn’t return a value, it can use the return operator without any parameters to exit a function at any time. Example:
function sayHi(sMessage) {
if (sMessage == “bye”){
return;
}
alert(sMessage);
}
In this code, the alert will never be displayed if the message is equal to the string “bye”.

When a function doesn’t explicitly return a value or uses the return statement without a value, the function actually returns undefined as its value.

当方法没有明确声明返回某个确定的值而使用了return;实际上方法返回的值为undefined

2、No overloading(js方法没有重载)

You can define two functions with the same name in the same scope without an error; however, the last function becomes the one that is used.

在JS中你可以定义任何多个同名的方法,但是真正起作用的是最后一个定义的方法,也就是说后面的方法相当于重写了前面的方法,前面的方面就不起作用了。

测试例子如下:

<script language="JavaScript">
<!--

function testArgu(arg1){
alert('arg1')
}

function testArgu(arg1,arg2){
alert('arg2')
}
function testArgu(arg1,arg2,arg3){
alert('arg3')
}

testArgu(23);
testArgu(23,23);
testArgu(23,23,23,23);
//-->
</script>

以上定义三个同名的方法,但参数个数不同,你会发现测试结果输出全是arg3.

你会发现testArgu(23,23,23,23);有四个参数,按理说没有方法与之匹配,但它确实输出了arg3,这正说明了JS中方法不能重载。调换三个方法的顺序你会发现谁最后定义,那么该方法将会被调用。其它的当作不存在。那么为什么传进去四个参数却可调用小于四个参数的方法呢?

The arguments object

function sayhi(){
if(arguments[0]=="good"){
alert('sfsf')
}
}
sayhi("good")

arguments对象通过index遍历传入的参数,0第一个参数,1第二个。。。。

可通过arguments对象的length属性检测传入的参数数目

上面提到:为什么传进去四个参数却可调用小于四个参数的方法呢?

解释:ECMAScript functions don’t validate the number of arguments passed against the number of arguments defined by the function; any developer-defined function accepts any number of arguments (up to 255, according to Netscape’s documentation) without causing an error. Any missing arguments are passed in as undefined; any excess arguments are ignored.

JS不会验证传入参数的个数是否与方法定义的参数个数是否相等。也就是说我可以传入至多255个参数到方法中,那怕该方法没有定义所谓的形参。

当然,既然可以通过arguments.length判断传入参数的数目,那么可通过这一属性来模拟出JAVA中的方法重载特性如:

function doAdd() {
if(arguments.length == 1) {
alert(arguments[0] + 10);
} else if (arguments.length == 2) {
alert(arguments[0] + arguments[1]);
}
}
doAdd(10); //outputs “20”
doAdd(30, 20); //outputs “50”

3、The Function class(方法类)

创建一个方法(函数)可以使用:

function functionName(arg0, arg1,...,argN) {
statements
}

你会发现这里使用的是function,注意首字母是小写的,JS中大小写是敏感的。那么通过Function类怎么来创建函数呢?

var function_name = new Function(argument1, argument2,..,argumentN, function_body);

这里要注意的是new Function后面的格式,所有参数必需都为字符串格式,最后为函数体部分

看下面的方法:

function doAdd(iNum) {
alert(iNum + 100);
}
function doAdd(iNum) {
alert(iNum + 10);
}
doAdd(10); //outputs “20”

上面解释过这里定义的方法,后面的方法重写了前面的方法那么将上面的方法換成另一种形式,也就是采用类定义的形式如下:

var doAdd = new Function("iNum","alert(iNum+100)");
var doAdd = new Function("iNum","alert(iNum+10)");
doAdd(10)

看看是不是很容易理解为什么方法名相同的时候最的是后一个方法了。。

不过这里看清楚了,方法名doAdd实际上是一个指向Function对象的引用。所以可以这样:

var doAdd = new Function("iNum","alert(iNum+100)");
var doAdd = new Function("iNum","alert(iNum+10)");
doAdd(10) //outputs “20”
var doAddagain = doAdd;
doAddagain(30) //outputs “40”

既然方法名是一个引用变量,那么就可以完全作为变量来使用,可以将这个变量作为另一个方法的参数。

var doAdd = new Function("iNum","alert(iNum+100)");
function callFun(fnFun,arg){
fnFun(arg)
}
callFun(doAdd,23) //outputs 123

同样可以使用length属性和toString方法

function doAdd(iNum){
alert(iNum + 100);
}
alert(doAdd.length) //outputs 1 代表参数个数
alert(doAdd.toString()) //方法体内容

alert(doAdd.valueOf()) //方法体内容

4.Closures方法的闭合区域(闭包)

我们知道JAVA等语言是以(if,while,for)等块作为变量范围控制的,在块以肉定义的变量在块以外是不能使用的。在块以块定义的变量是全局变量。那么在JS中是以方法来划分变量作用域范围的,也就是说在本方法以内定义的变量是局部变量,在方法以外定义的变量是全局变量,那么当一个方法调用另一个方法的时候,在被调用方法里就可以直接使用外层方法的变量了,而不用象java里面一样,如果被调用方法要使用外层方法的变量必须将其作为参数传入。

var tempVal = 34;
function alertNum()
{
alert(tempVal)
tempVal = 12;

}
tempVal = 23;
alertNum();
alert(tempVal)

//outputs 23

//outputs 12

JS中方法中可以访问外面环境的变量并改变它,它能侦测变量的变化并把调用前变量的最终值传入方法。

var tempVal = 34;
function alertNum()
{
var tempVal =66
alert(tempVal)
tempVal = 12;
alert(tempVal)

}
tempVal = 23;
alertNum();
alert(tempVal)

//outputs 66

//outputs 12

//outputs 23

这个例子中,首先定义了全局变值为34,再更改为23,而调用方法alerNum(),方法内部自己又定义了一个同名的变量,但是由于方法划分作用域,所以方法内部定义的变量为局部变量,下面将该局部变量改为12,最后调用结束,输出66,12而在方法外面为全局变量范围,所以输出23.

var tempVal = 34;
function alertNum()
{
tempVal =66
alert(tempVal)
tempVal = 12;
alert(tempVal)

}
tempVal = 23;
alertNum();
alert(tempVal)

//outputs 66

//outputs 12

//outputs 12

输出结果与上例不同,两例子的区别是在方法中变量tempVal的定义中使用了var和不使用var,我们知道JS中如果不使用var定义变量,那么会作为全局变量,也就是说这里其实跟下面是一样的效果:

var tempVal = 34;
function alertNum()
{
//tempVal =66
alert(tempVal)
tempVal = 12;
alert(tempVal)

}
tempVal = 23;
var tempVal =66; //重新定义了一个变量,也就是前面的tempVal已经不起作用。
alertNum();
alert(tempVal)

所以我们在方法里面声明变量的时候一定要注意细节。。。

再看下面例子,在方法中调用另一方法时发生的:

var tempVal = 34;
function alertNum(tempNum)
{
var tempNum2 = 23;
function doAdd(){
return tempNum + tempNum2;
}
return doAdd();
}

var result = alertNum(tempVal);
alert(result);

//outputs 57

结果表明,doAdd方法中使用了外围方法alertNum中的变量,在JS中这是一种特性,但在JAVA中是不行的。

对于浏览器来说,全局变量其实是window对象的一个属性:如下

var tempVal = 34;

alert(window.tempVal == 34)

//outputs true

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics