1,函数声明和函数表达式有什么区别
- 函数声明是使用function关键字声明一个函数,声明可以不必放在调用前面。
- 函数表达式声明必须放在调用前面。
2,什么是变量的声明前置?什么是函数的声明前置
- 变量的声明会被提升到作用域的顶部,而赋值则在原地,如:
console.log(a);
var a = 1;
实际上执行是:
var a;
console.log(a);
a=1;
- 函数的声明前置:整个函数体会被提升到作用域的顶部,如:
test(1)
function test(x){console.log(x);}
实际上执行是:
function test(x){console.log(x);}
test(1)
3,arguments 是什么
- 在函数内部,你可以使用arguments对象获取到该函数的所有传入参数
function printPersonInfo(name, age, sex){
console.log(name);
console.log(age);
console.log(sex);
console.log(arguments);
}
4,函数的"重载"怎样实现
- 在 JS 中没有重载,同名函数会覆盖。 但可以在函数体针对不同的参数调用执行相应的逻辑。
function printPeopleInfo(name, age, sex){
if(name){
console.log(name);
}
if(age){
console.log(age);
}
if(sex){
console.log(sex);
}
}
5,立即执行函数表达式是什么?有什么作用
(function(){
var a = 1;
})();
立即执行函数表达式如上面代码所示,特点是定义一个函数同时立即执行,并且此函数不能再次被调用。它的作用是隔离作用域,即执行一段代码,代码中的变量不被外部作用域影响,也不给外部作用域造成任何影响。
6,求n!,用递归来实现
function factor(n){
if(n===1||n===0){
return 1;
}
return n*factor(n-1);
}
7,以下代码输出什么?
function getInfo(name, age, sex){
console.log('name:',name);
console.log('age:', age);
console.log('sex:', sex);
console.log(arguments);
arguments[0] = 'valley';
console.log('name', name);
}
getInfo('饥人谷', 2, '男');
getInfo('小谷', 3);
getInfo('男');
输出结果
name 饥人谷
age 2
sex 男
["饥人谷",2,"男"]
name valley
name 小谷
age 3
sex undefined
[“小谷”,“3”]
name valley
name 男
age undefined
sex undefined
[“男”]
name valley
8. 写一个函数,返回参数的平方和?
function sumOfSquares() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i]*arguments[i];
}
return sum;
}
var result = sumOfSquares(2, 3, 4);
var result2 = sumOfSquares(1, 3);
console.log(result); //29
console.log(result2); //10
9. 如下代码的输出?为什么
console.log(a);//undefined var a 声明前置同时赋值undefined,先读取变量声明。
var a = 1;
console.log(b); //报错,因为b没有声明。
10. 如下代码的输出?为什么
sayName('world');
sayAge(10);
function sayName(name){
console.log('hello ', name);//sayName输出hello world,由于函数声明提升,sayName函数正常执行。
}
var sayAge = function(age){
console.log(age);// 报错 变量sayAge声明提升,但是执行sayAge函数时赋值语句还未执行,所以报错。
};
11. 如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
} //10
作用域链伪代码如下
globalContext = {
AO: {
x: 10,
foo: function
bar: function
},
Scope: null
}
foo.[[scope]] = globalContext.AO
bar.[[scope]] = globalContext.AO
barContext = {
AO: {
x: 30
},
Scope: globalContext.AO
}
fooContext = {
AO: {},
Scope: globalContext.AO
}
- 如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
- 以下代码输出什么? 写出作用域链的查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x)
})()
} //30
作用域链伪代码
globalContext = {
AO: {
x: 10,
bar: function
},
Scope: null
}
bar.[[scope]] = globalContext.AO
barContext = {
AO: {
x: 30,
foo: function
},
Scope: globalContext.AO
}
foo.[[scope]] = barContext.AO
fooContext = {
AO: {},
Scope: barContext.AO
}
- 以下代码输出什么? 写出作用域链查找过程伪代码
var a = 1;
function fn(){
console.log(a) //1 (输出undefined)
var a = 5
console.log(a) //2 (输出5)
a++
var a
fn3()
fn2()
console.log(a) //5
function fn2(){
console.log(a) //4 (输出6)
a = 20
}
}
function fn3(){
console.log(a) //3 (输出1)
a = 200
}
fn()
console.log(a) //6 (输出200)
作用域链伪代码如下:
globalContext = {
AO:{
a: 1;
fn: function(){};
fn3: function(){};
}
Scope: null
}
fn.[[scope]] = globalContext.AO
fn3.[[scope]] = globalContext.AO
fnContext = {
AO:{
a: 5;
fn2: function(){}
}
Scope: globalContext.AO
}
fn2:[[scope]] = fnContext.AO
fn2Context = {
AO:{}
Scope: fnContext.AO
}
fn3Context = {
AO: {}
Scope: globalContext.AO
}
输出a的顺序如图:
输出第1个a时,fn的AO中声明变量a,但是未定义,输出undefined。
输出第2个a时,fn的AO中声明变量a,而且已被赋值为5,输出5,随后a自增为6。
输出第3个a时,fn3的AO中没有变量a,fn3的Scope是globalContext.AO,输出1,同时将全局作用域的a赋值为200。
输出第4个a时,fn2的AO中没有变量a,fn2的Scope是fnContext.AO,fn的AO中变量a的值为6,输出6,随后将a赋值为20。
输出第5个a时,fn的AO中变量a的值为20,输出20。
输出第6个a时,globalContext.AO中的a为200,输出200。