函数
什么是函数
JavaScript的编程离不开函数,因为其中很多功能都来自于函数,通过函数我们可以实现丰富多样的功能,这也极大的提高了我们的开发效率。
定义和使用函数
通常可以function关键字+函数名来定义一个函数,使用时在函数名后面加一对括号即可
// 定义一个函数
function sum(){
return 123
}
// 调用函数
sum()
向函数传递参数
我们定义了函数在调用的时候,在函数名后面的括号内传入参数即可,而在函数名后面的括号内接收传递的参数即可。函数的参数分为形参和实参,形参是指定义函数时使用的参数,实参是指在调用函数时所传递的参数。函数的参数可以传递1个或多个,多个参数直接用逗号分隔,有效的参数将取决于实参的个数,多余的形参将自动被忽略掉。
arguments
arguments是函数内置的一个变量,它主要返回的是函数接收的所有参数
function fun(){
return anguments
}
// [1,2,3,4]
fun(1,2,3,4)
内置函数
在JavaScript引擎中有一些内置的函数可以供我们随时调用,这就是内置函数。
parseInt() 将传入的任意参数转为整数,如果转换失败就返回NaN
parseFloat() 与parseInt的功能基本相同,只不过它可以保留小数
isNaN() 判断传入的参数是否“非数值”或者说不是数值
eval() 可以将字符串当做JavaScript代码来执行
alert()函数
alert()函数就是显示一个对话框,alert会阻塞当前的浏览器线程,在弹框关闭之前所有的代码都会停止执行。
变量的作用域
在函数内部声明的变量叫做局部变量,只有在函数内部才可以访问,在其外部是访问不到的;在函数外部声明的变量叫做全局变量。另外需要注意一点,在函数内部声明的变量,在调用函数之前是不存在的,并且在函数执行完这个变量就会立即被销毁
function sum(){
var a = 123;
console.log(a) // 123
}
sum()
a // undefined
变量提升
变量提升指的是在函数内部声明的变量,会被提升到函数的最顶部或者说是函数最开始的地方,只提升变量的声明而对于变量的赋值还会留在原来的位置上,这就是变量提升
function sum(){
var a; // 相当于变量的声明被提升到了这里
a // 此时访问变量a 返回的是 undefined
a = 123; // 其实变量的赋值还留在原地
a // 123
}
函数也是数据
也就是说可以将一个函数赋值给一个变量。
var sum = function(a, b){
return a + b
}
sum(1, 2) // 3
回调函数
回调函数:将函数a传递给函数b,并且由b执行了a,那么a就是b的回调。以上就是回调函数的简单概念。
// 有一个函数addnum,对传入的参数加10再返回
var addnum = function(a){
return a + 10
}
// 还有一个函数,对传入的三个参数分别乘以2再返回
var twoFunction(a,b,c){
var i,arr = []
for(i=0; i<3; i++){
arr[i] = arguments[i] * 2
}
return arr
}
// 现在有一个需求:给twoFunction函数传入的参数乘以2再加上10,那么我们就可以使用回调函数来改造一下
var twoFunction(a, b, c, callback){
var i,arr = []
for(i=0; i<3; i++){
arr[i] = callback(arguments[i] * 2)
}
return arr
}
var myarr = twoFunction(10, 20, 30, addnum);
myarr() // 30, 50, 70
这就是回调函数的用法,可以将一个函数传递给另一个函数。这样做的好处是节省了变量名的使用;将一个函数的调用委托给另一个函数,可以节省代码编写工作。
立即执行函数
立即执行函数指的是当执行到立即执行函数的时候,这个函数就会立即调用。通常在函数后加一对括号之后这个函数就是立即执行函数了。相当于立即调用这个函数。
var a = (
function(){
alert('a')
}())
// 第二种写法
(function(){
alert('aaa')
})()
// 第三种写法
var a = function(){
alert(123)
}()
立即执行函数通常用来执行一次性任务
内部私有函数
函数内部嵌套了另一个函数就是内部私有函数,内部私有函数只在嵌套函数内部有效,其外部访问不到
function a(params){
function inner(val){
return val * 10
}
return 'this res is ' + inner(params)
}
a(10) // 10
inner(10) // inner is not defined
返回函数的函数
函数都是有返回值的,也可以将一个函数作为返回值进行返回。
var a = function(){
alert('a')
return functon(){
alert('b')
}
}
var res = a() // a
res() // b
能重写的函数
一个函数可以返回另一个函数,因此我们可以用新的函数来覆盖旧的函数。
function a(){
alert('a')
a = function(){
alert('b')
}
}
闭包
闭包的概念:一个函数能够访问其作用域外部的变量,这就是闭包。当内部函数FN2访问外部函数FN1中变量的时候,FN1的变量并没有销毁而是还存在于内存中,这样的作用是延长了变量的生命周期。
function FN1(){
var a = '111';
function FN2(){
alert(a)
}
}
a // undefined
// 以上,这样就形成了一个闭包
// 迭代器
function setup(x){
var i = 0;
return function(){
return x[i++]
}
}
var next = setup(['a','b','c'])
console.log(next()) // a
console.log(next()) // b
console.log(next()) // c
// getter与setter
var getVal, setVal;
(function(){
var secret = 0;
getVal = function(){
return secret
}
setVal = function(val){
if(typeof val === 'number'){
secret = val
}
}
})()
console.log(getVal())
setVal(123)
console.log(getVal())
其实每一个函数都是一个闭包,因为每一个函数至少都有访问全局作用域的权限