定义函数
函数声明
一个函数定义(也称函数声明,或函数语句)由一系列的function关键字组成,依次为:
- 函数的名称
- 函数参数列表,包围在括号中并由逗号分隔
- 定义函数的JavaScript语句,用大括号{}括起来
function 函数名(参数列表){
函数体;
return 返回值;
}
function add(x,y){
return x+y;
}
函数表达式
函数也可以由函数表达式创建,这样的函数是匿名的,函数的名字可以省略,如果这个函数名不省略,也只能用在此函数内部.
// 匿名函数
const add = function(x,y){
return x+y;
}
const sub = function fn(x,y){
return x-y
}
// console.log(fn(2,3)) // fn只能用在函数内部
//有名字的函数表达式
const sum = function _sum(n){
if (n===1) return n;
return n + _sum(--n) //_sum只能内部使用
}
console.log(sum(4))
函数、匿名函数、函数表达式的差异
函数和匿名函数,本质上都是一样的,都是函数对象,只不过函数有自己的标识符–函数名,匿名函数需要借助其他的标识符而已.
区别在于,函数会声明提升,函数表达式不会.
console.log(add(4,5))
const add = function(x,y){ //声明提升
return x+y;
}
console.log(sub(4,5)) //sub 未定义
const sub = function fn(x,y){
return x-y
}
高阶函数
函数作为参数或返回一个函数
const counter = function (){
let c = 0;
return function(){
return ++c;
};
};
const c = counter()
console.log(c())
console.log(c())
console.log(c())
箭头函数
箭头函数表达式(也称胖箭头函数)相比函数表达式具有较短的语法并以词法的方式绑定this.箭头函数总是匿名的
const map = function(arr,fn){
let newarr = []
for (let i in arr){
newarr[i] = fn(arr[i])
}
return newarr
}
console.log(map([1,2,3,4], function(x) {return x+=1}))
console.log(map([1,2,3,4], (x) => {return x+=1})) //箭头函数
console.log(map([1,2,3,4], x => {return x+=1}))
console.log(map([1,2,3,4], x => x+=1))
箭头函数参数
- 如果一个函数没有参数,使用()
- 如果只有一个参数,参数列表可以省略小括号()
- 多个参数不能省略小括号,且使用逗号间隔
箭头函数返回值
如果函数体部分有多行,就需要使用{},如果有返回值使用return.
如果只有一行语句,可以同时省略大括号和return.
只要有return语句,就不能省略大括号.console.log(map([1,2,3,4], x => {return x+=1}))有return必须有大括号
如果只有一个非return语句,加上大括号,函数就成了无返回值了.例如 console.log(map([1,2,3,4], x => {x*2})); 加上了大括号,它不等价于 x =>{return x*2} 。因此,记住 x => x*2 这种正确的形式就行了。
函数参数
默认参数
在JavaScript中,函数参数的默认值是undefined.然而,在某些情况下设置不同的默认值是有用的.
普通参数:一个参数占一个位置
function add(x,y=6){
return x+y
}
console.log(add(1,2))
console.log(add(x=1,y=2))
console.log(add(a=1,b=2))
Js中没有Python中的关键字传参
Js只是做参数位置的对应
Js并不限制默认参数的位置
建议默认参数(缺省参数)写到后面
可变参数 (rest parameters剩余参数)
JS使用…表示可变参数(Python用*收集多个参数)
const map = function(...args){
let result = 0
for (let i in args){
result += args[i]
}
return result
}
console.log(map(...[1,2,4]))
arguments对象
函数的所有函数会保存在一个arguments的键值对对象中
(function(p1,...args){
console.log(p1)
console.log(args)
console.log(arguments)
})(1,2,3,4)
ES6之前,arguments是唯一可变参数的实现。
ES6开始,不推荐,建议使用可变参数。为了兼容而保留。
((p1,...args) =>{
console.log(p1)
console.log(args)
console.log(arguments) //不是传入的值
})(...[1,2,3,4]) //参数结构
函数返回值
python 中可以使用 return 1,2 返回多值,本质上也是一个值,就是一个元组。
const add = function (x,y){
return x,y;
}
console.log(add(4,5)) // 5
表达式的值
类C的语言中,都有一个概念–表达式的值
赋值表达式的值:等号右边的值.
逗号表达式的值:类C语言,都支持逗号表达式,逗号表达式的值,就是最后一个表达式的值。
a = (x = 5, y = 6, true);
console.log(a);
b = (123, true, z = 'test')
console.log(b)
function c() {
return x = 5, y = 6, true, 'ok';
}
console.log(c());
作用域
function是函数的定义,是一个独立的作用域,其中定义的变量在函数外不可见
var a=100 可以提升声明,也可以突破非函数的块作用域.
a=100 隐式声明不能提升声明,在"严格模式"下会出错,但是可以把变量隐式声明为全局变量.
let a=100 不能提升声明,而且不能突破任何的块作用域.推荐使用
// 函数中变量的作用域
function test(){
a = 100;
var b = 100;
let c = 300;
}
test()
console.log(a)
console.log(b) //
console.log(c) //
if(2){
a = 100;
var b = 100;
let c = 300;
}
console.log(a)
console.log(b)
console.log(c) //
严格模式:使用"use strict",这条语句放到函数的首行,或者js脚本首行
异常
抛出异常
Js的异常语法和JAVA相同,使用throw关键字抛出
使用throw关键字可以抛出任意对象的异常
throw new Error('new error');
throw new ReferenceError('Ref Error');
throw 1;
throw 'not ok';
throw [1,2,3]; throw {'a':1};
throw () => {}; // 函数
捕获异常
try…catch语句捕获异常
try…catch…finally语句捕获异常,finally保证最终一定执行
注意这里的catch不支持类型,也就是说至多一个catch语句。可以在catch的语句块内,自行处理异常。
try{
//throw new Error('new error');
//throw new ReferenceError('Ref Error');
//throw 1;
//throw new Number(100);
// throw 'not ok';
// throw [1,2,3];
// throw {'a':1};
throw () => {}; // 函数
}catch(error){
console.log(error);
console.log(typeof(error));
console.log(error.constructor.name);
}finally{
console.log('===end===')
}