函数也是一个对象,使用typeof
检查一个函数对象时,会返回function
。
函数声明的方式
//常见的声明方式
//1.函数声明方式
function sum(a, b) {
console.log(a + b);
}
sum(200, 1);
//2.函数表达式声明方式
var sum = function (a, b) {
console.log(a + b);
};
sum(100, 200);
//3.使用Function构造函数
var func = new Function("console.log('大家好');");
func();
arguements对象
arguments仅仅属于函数,arguments是一个伪数组对象(并不是array),有一个callee指针,指向arguments所在的函数。
//原函数
function sum(num1,num2){
console.log(arguments);
}
控制台查看arguments
传入标准的参数后
它会将传入的所有实参都放到arguments对象中的伪数组中
arguments.length表示实参的个数,而function.length表示形参的个数,将两者个数进行对比,即可查看是否相等。
通过arguments.callee来查看当前函数的内容。
函数声明和函数表达式声明的区别
- 函数声明必须有函数名,而函数表达式的函数名可以省略
- JavaScript解析器首先会把当前作用域的函数声明提前到整个作用域的最前面
匿名函数
使用场景:1.绑定事件 2.定时器 3.闭包(立即执行函数)
回调函数
回调函数就是一个通过函数调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。一般用于递归。
//回调函数
//加减乘除函数
function add(num1,num2){
return num1+num2;
}
function sub(num1,num2){
return num1-num2;
}
function mul(num1,num2){
return num1*num2;
}
function div(num1,num2){
return num1/num2;
}
//计算器函数
function cal(num1,num2,func){
return func(num1,num2);
}
var result =cal(2,3,add);
console.log(result);
变量的作用域
全局变量、局部变量
- 不使用var声明的变量是全局变量 局部变量退出作用域之后会销毁
- 全局变量关闭网页或浏览器才销毁。
块级作用域
- 任何一对花括{}中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域
- 在es5之前没有块级作用域的的概念只有函数作用域
作用域链
- 只有函数可以制造作用域结构,那么只要是代码,就至少有一个作用域即全局作用域。
- 凡是代码中有函数,那么这个函数就构成另一个作用域。
- 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
function f1() {
function f2() {
}
}
var str = '我热爱的';
function f3() {
function f4() {
}
}
有三级作用域链, f1、f3、str为同一级
f2属于f1 f4属于f3 f2、f4为同一级
预解析
- JS代码的执行是由浏览器中的JS解析器来执行的
- JS解析器执行JS代码的时候,分为两个过程:预解析过程和代码执行过程
预解析过程
- 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值
- 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用
- 先提升var,在提升function