1.函数声明和函数表达式有什么区别
- 函数声明使用function来进行声明,函数声明提升,所以不论执行语句的位置皆可调用该函数。
function sayHello(){
console.log('hello')
}
- 函数表达式通过赋值来声明函数,声明完毕后要加上分号表示该句结束,在表达式执行完后,函数才存在并可被调用
var sayName = function sayHello(){
console.log('hello')
};
sayName()
2.什么是变量的声明前置?什么是函数的声明前置
- 变量提升:只提升声明部分,不提升赋值部分
var name = 'a';
function sayName(){
console.log(name);//输出undefined
var name = 'a';
console.log(name);//输出'a'
}
sayName();
相当于
var name = 'a';
function sayName(){
var a;
console.log(name);//变量提升,但未赋值则输出undefined
name = 'a';//变量赋值
console.log(name);//输出'a'
}
sayName();
- 函数的声明前置:会将函数的声明和定义全都提升至作用域顶部
var say = function(){
console.log('1');
};
function say(){
console.log('2');
};
say(); //输出:'1'
相当于
function say (){
console.log('2'); //函数声明提升
}
var say;//变量声明提升
say = function(){//变量赋值保持原位执行,say函数被覆盖
console.log('1');
};
say(); //输出:'1'
- 函数声明提升的优先级要高于变量声明提升。同名情况下,函数声明提升优先级高于变量声明提升,且提升后该函数声明定义不会被提升后的同名变量声明值覆盖,但会被后续执行的同名变量赋值所覆盖
console.log(say); //输出:[Function: say]
function say(){
console.log('1');
};
var say = '2';
console.log(say); //输出'2'
3.arguments 是什么
- 在函数内部你可以使用arguments对象获得所有该函数的传入参数
arguments就是传递进函数的参数列表,它是一个类数组对象-Array-Like Object.
类数组对象,简单来说就是拥有length属性,如我们常用的NodeList,arguments,但却不能使用数组方法,如forEach,map等
var foo = function () {
console.log(arguments.length)
}
foo() // 0
foo(1, 2) // 2
4.函数的"重载"怎样实现
在JS中没有重载!同名函数会覆盖。但可以在函数体针对不同的参数调用执行相应的逻辑
function printPeopleInfo(name, age, sex){
if(name){
console.log(name);
}
if(age){
console.log(age);
}
if(sex){
console.log(sex);
}
}
printPeopleInfo('Byron', 26);
printPeopleInfo('Byron', 26, 'male');
Byron
26
Byron
26
male
undefined
5.立即执行函数表达式是什么?有什么作用
(function(){
var a = 1;
})()
其他写法
true && function(){ /* code */ }();
(function fn1() {});
//在数组初始化器内只能是表达式
[function fn2() {}];
//逗号也只能是操作表达式
1,function fn3() {};
- 作用:
- 立即执行函数表达式内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量,隔离作用域
- 不必为函数命名,避免了污染全局变量;
6.求n!,用递归来实现
function factor(n){
if(n === 0 ){
return 0
}
if(n === 1){
return 1
}
return n * factor(n - 1)
}
factor(5);