1. 函数声明和函数表达式有什么区别
函数声明:function functionName(){ }
声明会提前,调用函数时可以放在任何地方。
函数表达式:var printName = function(){ }
调用函数必须放在表达式后。
2. 什么是变量的声明前置?什么是函数的声明前置
声明前置:所有的变量的声明语句,都会被提升到代码的头部。
console.log(a);
var a = 1;
//实际运行的是下面的代码
var a;
console.log(a);
a = 1;
//最后的结果是显示undefined,表示变量a已声明,但还未赋值。
函数的声明前置:和变量的声明前置类似,即使函数写在最后也可以在前面语句调用,前提是函数声明部分已经被下载到本地。
fn(); // "1"
function fn(){
console.log('1');
}
3. arguments 是什么
arguments对象包含了函数运行时的所有参数,可用她获取函数内的所有参数。arguments[0]就是第一个参数,arguments[1]就是第二个参数,以此类推。这个对象只有在函数体内部,才可以使用。
4. 函数的"重载"怎样实现
在JavaScript中没有函数重载的概念,函数通过名字确定唯一性,参数不同也被认为是相同的函数,后面的覆盖前面的。但可以在函数体内针对参数的不同来调用执行相应的逻辑。
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');
5. 立即执行函数表达式是什么?有什么作用
有时需要在定义函数之后,立即调用该函数,就使用立即调用的函数表达式(IIFE)。但不能在函数的定义之后加上圆括号,这会产生语法错误。解决方法就是不要让function出现在行首,让引擎将其理解成一个表达式。
//最简单的处理,就是将其放在一个圆括号里面。
(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();
//任何让解释器以表达式来处理函数定义的方法,都能产生同样的效果
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();
通常情况下,只对匿名函数使用这种“立即执行的函数表达式”。它的目的有两个:一是不必为函数命名,避免了污染全局变量;二是IIFE内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。
6. 求n!,用递归来实现
function factorial(n){
if(n === 1){
return 1;
}
return n*factorial(n-1);
}
factorial(5);
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, '男');
/*
name : 饥人谷
age : 2
sex : 男
['饥人谷', 2, '男']
name valley
*/
getInfo('小谷', 3);
/*
name : 小谷
age : 3
sex : undefined
['小谷', 3]
name valley
*/
getInfo('男');
/*
name : 男
age : undefined
sex : undefined
['男']
name valley
*/
8. 写一个函数,返回参数的平方和?
function sumOfSquares(){
var sum = 0;
for(var i = 0; i < arguments.length; i++){
sum = sum + arguments[i]*arguments[i];
}
return sum;
}
var result = sumOfSquares(2,3,4)
var result2 = sumOfSquares(1,3)
console.log(result) //29
console.log(result) //10
9. 如下代码的输出?为什么
console.log(a); //undefined
var a = 1;
console.log(b); //报错
10. 如下代码的输出?为什么
sayName('world'); //'hello' 'world'
sayAge(10); //报错
function sayName(name){
console.log('hello ', name);
}
var sayAge = function(age){
console.log(age);
};
11. 如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
}
/*
1.
globalContext = {
AO: {
x: 10
foo: function
bar: function
},
Scope: null
}
foo.[[scope]] = globalContext.AO
bar.[[scope]] = globalContext.AO
2.调用bar
barContext = {
AO: {
x: 30
},
Scope: bar.[[scope]] //globalContext.AO
}
3.调用foo
fooContext = {
AO: { },
Scope: foo.[[scope]] // globalContext.AO
}
输出10
*/
12. 如下代码输出什么? 写出作用域链查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
/*
1.
globalContext = {
AO: {
x: 10
bar: function
},
Scope: null
}
bar.[[scope]] = globalContext.AO
2.调用bar
barContext = {
AO: {
x: 30
foo: function
},
Scope: bar.[[scope]] // globalContext.AO
}
foo.[[scope]] = barContext.AO
3.调用foo
fooContext = {
AO: { },
Scope:foo.[[scope]] // barContext.AO
}
输出30
*/
13. 以下代码输出什么? 写出作用域链的查找过程伪代码
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x)
})()
}
/*
1.
globalContext = {
AO: {
x: 10
bar: function
},
Scope: null
}
bar.[[scope]] = globalContext.AO
2.调用bar
barContext = {
AO: {
x: 30
function
},
Scope: bar.[[scope]] // globalContext.AO
}
function.[[scope]] = barContext.AO
3.调用function
functionContext = {
AO: { },
Scope:function.[[scope]] // barContext.AO
}
输出30
*/
14. 以下代码输出什么? 写出作用域链查找过程伪代码
var a = 1;
function fn(){
console.log(a)
var a = 5
console.log(a)
a++
var a
fn3()
fn2()
console.log(a)
function fn2(){
console.log(a)
a = 20
}
}
function fn3(){
console.log(a)
a = 200
}
fn()
console.log(a)
作用域链
1.
globalContext = {
AO: {
a: 1 //fn3赋值为200
fn: function
fn3: function
},
Scope: null
}
fn.[[scope]] = globalContext.AO
fn3.[[scope]] = globalContext.AO
2.调用fn
fnContext = {
AO: {
a: undifined //赋值为5、a++为6、fn2赋值为20
fn2: function
},
Scope: fn.[[scope]] //globalContext.AO
}
fn2.[[scope]] = fnContext.AO
3.调用fn3
fn3Context = {
AO: {
a: 200
},
Scope: fn3.[[scope]] // globalContext.AO
}
4.调用fn2
fn2Context = {
AO: {
a: 20
},
Scope: fn2.[[scope]] // fnContext.AO
}
输出:
undefined
5
1
6
20
200