函数就是将特定功能的代码封装起来,当需要实现特定功能时,直接调用函数实现即可。
function sum(a,b) {
return a + b;
}
let sum = function(a,b) {
return a + b;
};
按顺序传入参数
console.log(sum(1,3))
function sum(a,b) {
return a + b;
}
let sum2 = function(a,b) {
return a + b;
};
console.log(sum2(1,3))
函数声明提升:
语句式命名函数存在函数声明提升,函数表达式声明函数函数时,不可以把函数调用写在函数声明前面,因为变量赋值不存在提升。
let sum2 = function(a,b) {
console.log(arguments) //[1, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(arguments[2]) //4
return a + b;
};
sum2(1,3,4,5)
剩余参数,遵循传入顺序后的,所有参数。rest参数只能写在最后,前面用…标识
let sum = function(a,b,...rest) {
console.log(rest) //[4, 5]
return a + b;
};
sum2(1,3,4,5)
JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部
函数之外声明的变量,会成为全局变量,就具有全局作用域
函数中声明的变量,会成为函数的局部变量,在函数外部不能访问
当前作用域没有定义的变量,会顺着作用域向父作用域找,如果父级也没有找到,再一层一层向上寻找,直到找到全局作用域还是没找到,就宣布放弃。这种一层一层的关系,就是作用域链 。
用于解决相同的全局变量、相同名字的函数,造成命名冲突。
var NAME_SPACE = {}
NAME_SPACE.name = ''
NAME_SPACE.sum = function() {}
let、var声明的是变量,要声明一个常量,使用ES6的const声明,通常用全部大写的变量来表示“这是一个常量,不要修改它的值”,谷歌浏览器下,赋值会报错。
const PI = 3.14
PI = 3 // index.html:53 Uncaught TypeError: Assignment to constant variable.
console.log(PI)
可以同时对一组变量进行赋值
let arr = ['诸葛亮', ['刘备', '关羽'], '张飞'];
let [o, [p,q], r] = arr;
console.log(o,p,q,r) //诸葛亮 刘备 关羽 张飞
let obj = {
name: '张飞',
age: 37,
country: '蜀国'
}
let {name, age, country} = obj
console.log(name,age,country) //张飞 37 蜀国
嵌套的对象属性进行赋值:
address不是变量,而是为了让country、province、city获得嵌套的address对象的属性
let obj = {
name: '张飞',
age: 37,
address: {
country: '蜀国',
province: '四川',
city: '成都'
}
}
let {name, age, address:{country,province,city}} = obj
console.log(name,country,province,city) //张飞 蜀国 四川 成都
console.log(address) //Uncaught ReferenceError: address is not defined
当解构赋值,对应属性不存在时,会赋值undefined
let obj = {
key: '004',
name: '张飞',
age: 37,
address: {
country: '蜀国',
province: '四川',
city: '成都'
}
}
// key不是变量,而是为了让变量code获得key属性
let {name,id,key:code} = obj
console.log(name) //张飞
console.log(id) // undefined
console.log(code) // 004
解构赋值还可以使用默认值
let obj = {
key: '004',
name: '张飞',
age: 37,
address: {
country: '蜀国',
province: '四川',
city: '成都'
}
}
let {name,id='001'} = obj
console.log(name) //张飞
console.log(id) // 001
.
来获取和连续声明变量let {x,y,z} = {}
2、函数接收一个对象作为参数,可以直接用解构把对象属性赋值给变量
sum({x,y,z=0}){
return x+y+z
}
3、变量值替换,减少中间变量
let x=1, y=2;
[x,y] = [y,x]
console.log(x,y) //2 1
一个对象中绑定函数,这个函数称为这个对象的方法。
let obj = {
name: '张飞',
birth: 1993,
age: function() {
let y = new Date().getFullYear()
return y - this.birth
}
}
console.log(obj.age()) //30
this是执行环境上下文对象 ,它指向谁取决于它什么时候被调用、被谁调用。
let person = {
name: '张飞',
birth: 1993,
say: function() {
console.log(this)
console.log(this.name)
}
}
// person对象调用了方法,this指向person
person.say()
let person = {
name: '张飞',
birth: 1993,
say: function() {
console.log(this)
console.log(this.name)
}
}
// 全局对象调用say方法,因此this指向window
let say = person.say
say()
let personBase = {
name: '张飞',
birth: 1993,
say: function() {
console.log(this)
console.log(this.name)
}
}
let person = {
name: '刘备',
}
let say = personBase.say
say.call(person) //指向person
say.apply(personBase) //personBase
1.2 调用函数
扩展
声明函数的同时立即调用这个函数,立即执行函数是一个匿名函数
1、页面加载完成后只执行一次的设置函数。
2、将设置函数中的变量包裹在局部作用域中,不会泄露成全局变量
// a b 形参
(function(a,b){
//函数体内容
console.log(a,b)
}(1,2));//形参 立即执行函数结束要加分号
(function(a,b){
console.log(a,b)
})(3,4)
由于log调用前,循环执行结束,所以输出5
for(let i=0; i<6; i++) {
function log() {
console.log(i)
}
}
log() //5
使用立即执行函数
for(let i=0; i<6; i++) {
(function(j) {
console.log(i) //0,1,2,3,4,5
})(i)
}
闭包是指有权访问另一个函数中的变量
的函数
。(定义一个在函数内部的函数,内部函数可以访问外包函数的局部变量)
function fun () {
var x = 0, y = 1;
function sum() {
console.log(x + y)
return x + y
}
return sum
}
let f = fun()
f()
function fun () {
var n = 0;
function sum() {
n += 1
console.log(n)
}
return sum
}
var f = fun()
f() //1
f() //2
fun执行两次, n分别输出1 和 2,说明fun中的局部变量n一直存在内存中,没有在fun调用后,自动清除。
未清除的原因:sum函数是fun的子函数,fun执行后,把sum函数赋值给了全局变量f,全局变量f一直存在,所以sum函数一直存在,而sum又依赖于fun函数,所以fun一直存在内存中,未在调用结束后被垃圾回收机制回收。
箭头函数相当于匿名函数,简化了函数定义
// 省略简写方式
let fun1 = (x,y)=> x+y;
// 多条语句
let fun2 = (x,y)=> {
console.log(x)
return x+y
}
fun1(1,2)
fun2(2,3)
箭头函数内部的this是词法作用域,由上下文确定。
箭头函数的外层如果有普通函数,那么箭头函数的this就是这个外层的普通函数的this,箭头函数的外层如果没有普通函数,那么箭头函数的this就是全局变量。
let fun2 = (...args)=> {
console.log(args)
return args[0]+args[1]
}
fun2(2,3)