重拾JavaScript(二)-函数

基本语法

JavaScript函数是指一个特定代码块,可能包含多条语句,可以通过名字来供其它语句调用以执行函数包含的代码语句。

比如我们有一个特定的功能需要三条语句实现:

1
2
3
statement1;
statement2;
statement3;

但是每次想实现这个功能的时候就需要写这三句话,很麻烦,我们可以把这三条语句打包为一个函数

1
2
3
4
5
function doSomething(){
statement1;
statement2;
statement3;
}

这样每次想实现功能的时候我们就调用一下函数就可以了,调用函数通过函数名称()的形式调用

1
doSomething();

例如:

1
2
3
4
function name(){
console.log("Tennant");
}
name();//Tennant

函数定义

函数声明(函数语句)

1
2
3
4
5
6
//使用function关键字可以声明一个函数
//printName() 即函数名称() ,可调用
function printName(){
console.log("Tennant");
}
printName();

函数表达式(function expression)

1
2
3
4
5
6
7
8
//通过var 进行一个声明变量,这里的  变量  等同于 函数表达式
var printName = function(){
console.log("Tennant")
};
printName()

//等同于
var printName = "Tennant"

当函数只使用一次时,通常使用IIFE (Immediately Invokable Function Expressions)

1
2
3
(function() {
statements
})();

Function构造函数

不推荐使用 Function 构造函数创建函数,因为它需要的函数体作为字符串可能会阻止一些JS引擎优化,也会引起其他问题。

1
new Function (arg1, arg2, ... argN, functionBody)

参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function printName(name){  //括号中的name为函数的参数
console.log(name)
}

printName("Tennant")

//等同于在函数设置变量
function printName(){ //括号为空括号
var name = arguments[0]
console.log(name);
}
printName("Tennant");

//假设没有传递参数
function printName(){ //括号为空括号
var name = arguments[0]
console.log(name);
}
printName();
//arguments[0] 为undefined,name=undefined ,那么结果为undefined


//函数在定义的时候可以写多个参数
function printPersonInfo(name, age, sex){
console.log(name)
console.log(age)
console.log(sex)
}

arguments

在函数体内可以通过arguments对象来访问参数数组,从而获取传递给函数的每一个参数。

1
2
3
4
5
6
function howManyArgs(){
alert(arguments.length);
}
howManyArgs("string", 45);//2
howManyArgs();//0
howManyArgs(12);//1
1
2
3
4
5
6
7
8
9
10
11
12
function Add(){
if(arguments.length == 1){
alert(arguments[0] + 10);
}else if(arguments.length == 2){
alert(arguments[0] + arguments[1]);
}
}

Add(10);//20
Add(30, 20);//50

函数Add()会在只有一个参数的情况下给该参数加上10;如果是两个参数,则将那个参数简单相加并返回结果。

注意:没有传递值的命名参数将自动被赋予undefined值,这就跟定义了变量但又没初始化一样。

1
2
3
4
5
6
7
8
9
function printPersonInfo(name, age, sex){
console.log(name)
console.log(age)
console.log(sex)
console.log(arguments)
console.log(arguments[0])
console.log(arguments.length)
console.log(arguments[1] === age)
}

重载

重载是很多面向对象语言实现多态的手段之一,在静态语言中确定一个函数的手段是靠方法签名——函数名+参数列表,也就是说相同名字的函数参数个数不同或者顺序不同都被认为是不同的函数,称为函数重载。

在JavaScript中没有函数重载的概念,函数通过名字确定唯一性,参数不同也被认为是相同的函数,后面的覆盖前面的。

1
2
3
4
5
6
7
function addNumber(num){
return num+100;
}
function addNumber(num){
return num+200;
}
var result = addNumber(100);//300

以下代码输出结果是? 为什么

1
2
3
4
5
6
7
8
9
10
11
12
13
var a = 1, b = 2, c = 3;
var val = typeof a + b || c >0
console.log(val)

var d = 5;
var data = d ==5 && console.log('bb')
console.log(data)

var data2 = d = 0 || console.log('haha')
console.log(data2)

var x = !!"Hello" + (!"world", !!"from here!!");
console.log(x)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1.
var a = 1, b = 2, c = 3;
var val = typeof a + b || c >0
console.log(val) //number2
按照优先级,首先是typeof a为number
number+b,b的值为2,故结果为字符串number2
c>0true,最后number2 || true为number2

2.
var d = 5;
var data = d ==5 && console.log('bb')
console.log(data)//bb
按照优先级,console.log('bb')为bb,d==5true
true&&bb为bb,赋值给data

3.
var data2 = d = 0 || console.log('haha')
console.log(data2)//haha
按照优先级,console.log('haha')为haha,把0赋值给d
false || haha为haha,赋值给data2

4.
var x = !!"Hello" + (!"world", !!"from here!!");
console.log(x)//2
两次逻辑非抵消,字符串空为false非空为truevar=true+(false+true),1+1=2

1
2
3
var a = 1;
var b = 3;
console.log( a+++b );
1
2
4
++的优先级高于+,故顺序为(a++)+b,a++为1,b为3,故结果为4