再读斋

JavaScript⑤函数

初识函数

ECMAScript中的函数使用 function 关键字来声明,后跟一组参数以及函数体。

1
2
3
4
5
6
7
8
9
10
11
12
// 基本的语法
function functionName(argument1,argument2){
/*一堆的代码*/
}
//下面是函数的一个实例,
function diff(a,b){
console.log(a-b);
}
diff(10,5);//输出5
diff(20,2);//输出18

函数还有一个属性,就是可以return;ECMAScript中函数在定义的时候,不要求函数是否返回一个值,但是每个函数都有return的权利;任何函数在任何时候都可以通过return语句返回的值来实现把值返回给外部变量。

1
2
3
4
5
function diff(a,b){
return a-b;
}
var diffNumber=diff(10,5);
console.log(diffNumber);

函数的返回值只能通过return来返回,除了return以外,没有任何声明可以表示返回值,无论return在哪里,只要有执行了return同一条的代码后,函数立即停止,并且立即退出,因此位于return语句之后的人和代码都永远不会执行;

return语句可以不带任何返回值,这种情况下,函数返回值是undefined;这种写法,一般用在需要提前停止函数又不需要返回值的情况下。

函数的定义

  • function语句的定义方法
  • 函数直接量的定义方法
  • 构造函数的定义方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//function语句的定义方法
function test1(arg1,arg2){
console.log("function语句的定义方法:",arg1+arg2);
return;
}
//函数直接量的定义方法
var test2 = function(arg1,arg2){
console.log("函数直接量的定义方法:",arg1+arg2);
return;
}
//构造函数的定义方法
var test3 = new Function("arg1","arg2","console.log('构造函数的定义方法:',arg1+arg2)");

函数的重载

ECMAScript 函数不能实现重载,ECMAScript 没有函数签名,因为其参数是由包含0 或者多个值的数组来表示的。如果在 ECMAScript 中定义了两个名字相同的参数,则该名字只属于后定义的函数。

1
2
3
4
5
6
7
8
9
10
11
function add(num) {
return num + 100;
}
function add(num) {
return num + 200;
}
var ret = add(100);
console.log(ret);
//300

函数的调用

直接调用:函数名(实参列表)

1
2
3
4
5
6
7
function test1(arg1,arg2){
console.log("function语句的定义方法:",arg1+arg2);
return;
}
//直接调用
test1(1,2);//function语句的定义方法: 3

在链接中调用

1
2
3
4
5
6
7
8
9
<body>
<button type="button" name="button" onclick="test1(9,9)">click me</button>
<script>
function test1(arg1,arg2){
console.log("function语句的定义方法:",arg1+arg2);
return;
}
</script>
</body>

在事件中调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<body>
<button type="button" name="button" id="btn1">click me</button>
<script>
var oBtn1=document.getElementById("btn1");
oBtn1.onclick=function(){
test1(2,2)
};
function test1(arg1,arg2){
console.log("function语句的定义方法:",arg1+arg2);
return;
}
</script>
</body>

递归调用

在函数内部调用函数自身

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<button type="button" name="button" id="btn1">click me</button>
<script>
var oBtn1=document.getElementById("btn1");
oBtn1.onclick=function(){
test1(10,1);
};
function test1(arg1,arg2){
console.log("最开始的调用方法",arg1+arg2);
arg1--;
if(arg1>0){
test1(arg1,arg2)
}
return;
}
</script>

arguments对象

功能

存放实参的参数列表

1
2
3
4
5
6
test1(1,2);//[1,2]
test1(1,2,3,4,5);//[1, 2, 3, 4, 5]
function test1(){
console.log(arguments);
}
//{ '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }

argutments 在普通模式里,可以在函数内部修改函数的值;在严格模式下,函数内部不能修改argument的值,即使修改了,操作也是无效的;其次重写arguments值会导致语法错误,代码不执行;

特性

仅能在函数体内使用

1
2
3
4
5
test1(1,2);//[1,2]
function test1(){
console.log(arguments);
}
console.log(arguments);//arguments is not defined

函数声明时自动初始化

属性

length:获取函数实参的长度

1
2
3
4
test1(1,2,3,4,5);// 输出5
function test1(){
console.log(arguments.length);
}

this关键字的指向

  • this:指向当前操作对象;
  • callee:指向正在执行函数的指针;

函数表达式

匿名函数

创建一个函数并把它赋值给变量,这种情况下创建的函数叫做匿名函数

1
2
3
4
5
6
7
var sayHi;
sayHi = function (num) {
console.log("sayHi " + num);
}
sayHi(1);
//sayHi 1
1
2
3
4
5
6
7
8
//创建一个匿名函数并立即执行
var ret = (function (x,y) {
return x * y;
})(3,8);
console.log(ret);
//24

函数闭包

闭包是指有权访问另一个 函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function lazy_sum(arr) {
var sum = function () {
return arr.reduce(function (x,y) {
return x * y;
});
}
return sum;
}
var f = lazy_sum([1,2,3,4,5]); //返回的是求和函数
console.log(f()); //调用函数f计算求和

借助闭包,可以封装一个私有变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//闭包实现计数器
function create_counter(initial) {
var x = initial || 0;
return {
inc: function () {
x += 1;
return x;
}
}
}
var counter1 = create_counter();
console.log(counter1.inc()); //1
console.log(counter1.inc()); //2
console.log(counter1.inc()); //3
var counter2 = create_counter(10);
console.log(counter2.inc()); //11
console.log(counter2.inc()); //12
console.log(counter2.inc()); //13

闭包还可以把多参数的函数变成单参数的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
function make_pow(n) {
return function (x) {
return Math.pow(n,x);
}
}
//创建两个新函数
var pow1 = make_pow(2);
var pow2 = make_pow(3);
console.log(pow1(2)); // 4
console.log(pow2(2)); // 8

箭头函数

ES6标准新增了一种新的函数:Arrow Function(箭头函数)。

1
x => x * x

上面的箭头函数相当于

1
2
3
function (x) {
return x * x;
}

使用

1
2
3
'use strict';
var fn = x => x * x;
console.log("箭头函数 "+ fn(3));

高阶函数

JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。一个最简单的高阶函数:

1
2
3
4
function addHigh(x, y, f) {
return f(x) + f(y);
}
console.log(addHigh(-4,-5,Math.abs)); //9
刘涤生 wechat