问答题
-
函数声明和函数表达式有什么区别 (*)
答://函数声明 function hello(){ console.log("hello world"); } //函数表达式 var hello = function(){ console.log("hello world"); }
两种方式都能声明函数,但是函数声明的写法会将函数前置,可以在全局种任何地方调用函数;但是表达式只能前置sayHi变量,如果在表达式之前调用函数则会报错,只能放在表达式后面进行调用。
-
什么是变量的声明前置?什么是函数的声明前置 (**)
答:- 变量的声明前置:变量声明都会被放在代码的头部,只提升变量的声明并不会进行赋值。
//全局中定义变量 var a = 1; var b = 2; //实际是执行起来是这样的 var a; var b; a = 1; b = 2;
//函数中 function say(){ var a = 1; console.log(a); var b = 2; } //实际运行过程 function say(){ var a; var b; a = 1; console.log(a); b = 2; }
- 函数声明前置:函数的声明前置和变量声明一样,会提升到代码头部。但是会提升到变量声明后面,所以可以在函数声明前面调用函数。
f(10);//10 此时该函数是有效的,且结果正确 function f(num){ console.log(num); }
相当于
function f(num){ cconsole.log(num); } f(10);
-
arguments 是什么 (*)
答:
Arguments是个类似数组但不是数组的对象,说他类似数组是因为其具备数组相同的访问性质及方式,能够由arguments[n]来访问对应的单个参数的值,并拥有数组长度属性length。还有就是arguments对象存储的是实际 传递给函数的参数,而不局限于函数声明所定义的参数列表,而且不能显式创建 arguments 对象。
Paste_Image.png
arguments对象的长度是由实参决定的。
-
函数的重载怎样实现 (**)
答:
在JavaScript中没有函数重载的概念,函数通过名字确定唯一性,参数不同也被认为是相同的函数,后面的覆盖前面的。函数调用没必要把所有参数都传入,只要你函数体内做好处理就行,但前提是传的参数永远被当做前几个。
Paste_Image.png
-
立即执行函数表达式是什么?有什么作用 (***)
答:(function(){ //第一种 })(); (function(){ //第二种 }());
作用是:立即执行函数可以避免函数内的变量暴露在全局环境下,避免全局变量的污染。可以令其函数中声明的变量绕过JavaScript的变量置顶声明规则,还可以避免新的变量被解释成全局变量或函数名占用全局变量名的情况,在函数内部内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。
-
什么是函数的作用域链 (****)
答:
在一个函数执行过程中如果某个变量在该函数自己的作用域中没有,那么它会寻找父级的作用域,直到全局作用域,这样就形成了一个作用域链。
Paste_Image.png
执行ss()时,作用域链是: ss()->t()->window,所以name是”桶饭"
代码题
-
以下代码输出什么? (难度**)
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('hunger', 28, '男'); getInfo('hunger', 28); getInfo('男');
输出结果:
形参和实参的数量可以不一样,用arguments可以改变实参的值。
-
写一个函数,返回参数的平方和?如 (难度**)
function sumOfSquares(){ var num; for(var i = 0;i<arguments.length;i++){ num = num+arguments[i]*arguments[i]; } return num; } sumOfSquares(2,3,4); // 29 sumOfSquares(1,3);
-
如下代码的输出?为什么 (难度*)
console.log(a); var a = 1; console.log(b); //运算过程 var a; console.log(a);//输出undefined,因为变量提升,会把变量a的声明提升到console.log(a);之前,当console.log(a);执行的时候,变量a还没有被赋值,所以console.log(a);输出undefined。 a = 1; console.log(b);//报错,因为没有变量b。
输出结果:
-
如下代码的输出?为什么 (难度*)
sayName('world'); sayAge(10); function sayName(name){ console.log('hello ', name); } var sayAge = function(age){ console.log(age); }; //运算过程 //在执行上面代码的时候会将函数的声明前置,而函数表达式只会将变量的声明前置,函数不会前置。实际上述代码在执行的时候会变成这样: var sayAge; function sayName(name){ console.log('hello ', name); } sayName('world'); sayAge(10);//sayAge(10);的时候,sayAge只是个变量不是函数,所以会报错。最终会输出hello world和报错。 sayAge = function(age){ console.log(age); };
Paste_Image.png -
如下代码的输出?为什么 (难度**)
function fn(){} var fn = 3; console.log(fn);//输出3 //当在同一个作用域内定义了名字相同的变量和方法的话,无论其顺序如何,变量的赋值会覆盖方法的赋值。
-
如下代码的输出?为什么 (难度***)
function fn(fn2){ console.log(fn2); var fn2 = 3; console.log(fn2); console.log(fn); function fn2(){ console.log('fnnn2'); } } fn(10);
输出:
//过程
function fn(fn2){
var fn2;//变量声明前置
function fn2(){
console.log('fnnn2');
}//函数声明前置
console.log(fn2);//log fn2()函数
fn2 = 3;//赋值
console.log(fn2);//log fn2 此时 fn2是3
console.log(fn);//此作用域找不到 fn,向上寻找打印 fn 函数
}
fn(10);
//函数执行命名有冲突的时候,函数执行载入顺序是变量、函数、参数
```
7. 如下代码的输出?为什么 (难度***)
```
var fn = 1;
function fn(fn){
console.log(fn);
}
console.log(fn(fn));
```
输出:

因为给变量声明进行赋值操作后,同名的变量声明的优先级会大于同名函数声明,会覆盖同名的函数声明,所以fn现在是一个变量不是函数,执行函数fn就会报错。
8. 如下代码的输出?为什么 (难度**)
```
//作用域
console.log(j);//输出undefined,因为变量声明前置,i这时候还没有赋值。
console.log(i);//输出undefined,因为变量声明前置,j这时候还没有赋值。
for(var i=0; i<10; i++){
var j = 100;
}
console.log(i);//输出10,因为for循环语句结束循环时,i的值是10 。
console.log(j);//输出100,应为变量j的值是100。
```
输出:

9. 如下代码的输出?为什么 (难度****)
```
fn();
var i = 10;
var fn = 20;
console.log(i);
function fn(){
console.log(i);
var i = 99;
fn2();
console.log(i);
function fn2(){
i = 100;
}
}
```
```
//过程
var i;
var fn;
function fn() {
var i;
function fn2() {
i = 100;
}
console.log(i);// 输出undefined,因为变量i的声明前置,但还没有赋值。
i = 99;
fn2();//执行函数fn2,因为函数中的变量i没有加关键字var,所以它是一个全局变量,它会把100赋值到函数fn的变量i。这时i=100
console.log(i);//输出100,因为变量i的值为100。
}
fn();
i = 10;
fn = 20;
console.log(i);//输出10,因为最后变量i的值是10。
```

10. 如下代码的输出?为什么 (难度*****)
```
var say = 0;
(function say(n){ //立即执行函数,给函数初始的参数n=10,当满足n<3时,执行say(n-1)。
console.log(n);//输出10,9,8,7,6,5,4,3,2,因为当n=2时,函数return。
if(n<3) return;
say(n-1);
}( 10 ));
console.log(say);//输出0.因为立即执行函数say(n)相当于创造了一块私有的作用域,函数say(n)内部可以访问外部的变量,而外部环境不能访问函数say(n)内部的变量,内部定义的变量不会和外部的变量发生冲突,所以变量say一直等于0。