一、函数声明和函数表达式的区别
-
声明方式不同n
function fn(){} //函数声明 var fn = function(){}//函数表达式 (function () { })();// 也是函数表达式,表示立即执行函数,常用于匿名函数的调用;
- js解析器会优先解析函数声明,确保所有代码执行之前已经全部被解析
- js在解析函数表达式的时候会和普通的表达式一样,先声明,然后执行到某一句的时候再解析
- 当使用函数声明的形式来定义函数时,可将调用语句写在函数声明之前,而函数表达式这样做的话会报错。
二、什么是变量的声明前置?什么是函数的声明前置
变量声明(var,VariableDeclaration) 变量对象的一个属性,其属性名即为变量名,其值为undefined;如果变量名和已经声明的函数名或者函数的参数名相同,则不会影响已经存在的属性。任何变量的声明都在当前的执行环境下代码的顶部,即使声明代码写在后面,前面的代码也可以调用。
console.log(a) //这里会输出undefined
var a = 1;//上面代码就相当于
var a;
console.log(a)
a = 1;函数的声明前置:js解析器会优先解析函数声明,确保所有代码执行之前已经全部被解析,无论在哪里调用此函数都会执行
fuc()
function fuc(){ console.log (ok
) }
效果相当于
function fuc(){ console.log (ok
) }
fuc()
三、arguments 是什么 ?
- arguments是一个包含函数运行时的所有参数的对象,只有在函数开始时才可用,不能被显式创建,可通过arguments[i]依次对参数进行访问和修改,与数组元素的方式相同,但并不是一个数组。
- arguments是函数的内置对象,可以用于检测参数个数
function a(){ console.log(arguments.length); }
a("1","2"); //2 - 在函数内部,你可以使用arguments对象获取到该函数的所有传入参数
function test(){
for(key in arguments){
console.log(arguments[key])
}
}
test() //undefined
test(1,2,3) //1 2 3
test(1,2,3,4,5) //1 2 3 4 5 (test可以传入任何参数) - arguments也可用于模拟函数重载。函数的重载:是指两个或多个函数的参数类型,顺序和数量以及返回值不一样。在javascript中没有重载的概念,但是可以通过arguments模拟函数重载。
function sum(){
var sum=0;
for(var i=0;i<arguments.length;i++){
sum+=arguments[i];
}
return sum;
}
sum(1,2);//3
四、函数的重载怎样实现
- js并没有真正意义上的重载,都是后面的覆盖前面的,所以函数内部处理好可以模拟重载。
func () //打印"覆盖前面的函数"
function func(){
console.log("被覆盖的函数")
}
function func(){
console.log("覆盖前面的函数")
}
五、立即执行函数表达式是什么?有什么作用
- 在一个表达式后面加上括号()*,该表达式会立即执行 ;但是在一个语句后面加上括号(),是完全不一样的意思,他的只是分组操作符。
- 立即执行里函数是一个表达式,执行完内部变量便销毁,如果声明的函数只需要调用一次,建议使用。
- 独立模块。开发时,它能做到各模块的低耦合,减少对全局作用域的污染,防止与外部变量冲突,外部访问不到内部的变量。
六、什么是函数的作用域链
- 任何执行上下文时刻的作用域, 都是由作用域链来实现.
- 当一个函数被声明的时候,会给这个函数添加一个scope属性.
- js中变量分为全局变量和局部变量,函数内部能访问到全局变量,函数外部不能访问局部变量
- 作用域链的原理和原型链很类似,当在一个函数内部时,会优先在作用域里找变量是否定义,没有就向上一级找,如果在window下(window就是全局)也没有就报错
- 所以尽量多用局部变量,一方面不会影响其它函数,另一方面全局变量是最后找用多了影响速度
理解 JavaScript 作用域和作用域链