注意: console.log()永远返回undefined,它打印出来的值和返回的值没有关系。
函数的5种声明方式
- 具名函数
function f(input1, input2) {
return undefined
}
console.log(f) //没有问题,可以在函数外部访问f
- 匿名函数
var f
f = function (input1, input2) {
return undefined
}
//匿名函数必须赋值给一个变量
- 具名函数赋值给变量
var x
x = function f(input1, input2) {
return undefined
}
console.log(f) //会报错显示f: undefined
//它只能在function f(input1, input2){只能在这里访问f}大括号内部访问到f
- window.Function
var f
f = new Function('x', 'y', 'return x + y')
f(1, 2)
//output:
3
- 箭头函数
sum = (x, y) => {return x + y}//箭头函数没有名字,只能把它赋值给一个变量,相当于匿名函数的简化
sum(1,2)
//output:
3
sum = (x, y) =>{
var n = x * 2;
var m = y * 3;
return n + m
}
sum(1,2)
//output:
8
//如果只有一个返回值,可以把{}和return一起去掉
sum = (x, y) => x + y
sum(1,2)
//output:
3
//如果参数只有一个,则()可以去掉
sq = n => n * n
sq(2)
//output:
4
函数的name属性
一个垃圾属性
函数的本质
函数的本质就是可执行代码的对象
// 函数调用的两种方法
f(x1, x2) //小白方法
f.call(undefined, x1, x2) //尽量用这种
this和arguments
f.call(undefined, x1, x2)
1. call的第一个参数可以用this得到
2. call的后面的参数可以用arguments得到
1. this
在普通模式下,如果this是undefined,浏览器会把this变成window(小写)
在严格模式下,如果this是什么就是什么。
所以this就是call的第一个参数。
2. arguments
arguments是call后面的参数组成的伪数组(proto不是Array.prototype,或者它的原型链中没有Array.prototype)
函数作用域
- 第一题
var a = 1
function f1(){
f2.call()
console.log(a)
var a = 2 //新手永远不记得变量提升
function f2(){
var a = 3
console.log(a)
}
}
f1.call()
console.log(a)
看到代码一定先做声明提升(变量提升)
var a
a = 1
function f1(){
var a
function f2(){
var a
a = 3
console.log(a)
}
f2.call()
console.log(a) //undefined
a = 2
}
f1.call() // 3 undefined
console.log(a) // 1
- 第二题
var a = 1
function f1(){
console.log(a) //undefined
var a = 2
f4.call() // 1
}
function f4(){
console.log(a)
}
f1.call()
var a = 1
function f1(){
console.log(a) //undefined
var a = 2
f4.call() // 3
}
function f4(){
console.log(a) //函数f4作用域内没有a这个变量,所以它会从它的父作用域内找,它的父作用域是全局作用域,其中:var a = 1,但是在执行f1.call()之前(f4.call()是通过f1.call()调用的),a的值被重新赋值为a = 3,所以f4.call()打印出的值为3
}
a = 3
f1.call()
var a = 1
function f4(){
console.log(a)//2
}
a = 2
f4.call()
var a = 1
function f4(){
console.log(a)//1
}
f4.call()
a = 2
-
第三题
当鼠标点击选项3时,console.log(i)打印出的值为6;因为for循环在纳秒级时间内就结束了,当你鼠标去点选项3时,已经是6了。
闭包
如果一个函数使用了它范围外的值,那么(这个函数+这个变量)就叫做闭包
var a = 1
function f(){
console.log(a) // 2
}