函数与作用域

时间:2021-6-4 作者:qvyue

声明前置和作用域也是JS 部分面试常考点

1.函数声明和函数表达式有什么区别

函数声明:使用function关键字可以声明一个函数。

 function sayHello(){
   console.log('hello')
 }
 //函数调用
 sayHello()```
声明不必放到调用的前面,声明的是一个函数,用时就是调用,该声明位置可放在后面。函数声明最重要的特征就是函数声明提升,意思是在执行代码之前就会读取函数声明。

函数表达式:用函数表达式定义的函数在使用之前必须先赋值。
 ```var sayHello = function(){
   console.log('hello');
 }
 sayHello()```
声明必须放到调用的前面,声明的是一个变量,必须声明过后才能使用。


####2.什么是变量的声明前置?什么是函数的声明前置
- 变量的声明前置:JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,然后给他初始值undefined,然后才逐句执行程序,这就叫做“变量提升”,也即“变量的声明前置”。在一个作用域块中,所有的变量都被放在块的开始出声明,但是变量的赋值不会提升。

- 函数的声明前置:在一个作用域下,同var 声明的变量一样,function 声明的函数也会前置。函数的声明前置优先级高于变量的声明前置。

```console.log(a); 
var a = 3;
console.log(a); 
sayHello();
function sayHello(){
 console.log('hello');
}```
执行时语句顺序如下:
```var a
function sayHello(){}
console.log(a);//undefined
a=3
console.log(a); //3
sayHello();```

####3.arguments 是什么
arguments 是一个类似数组的对象, 对应于传递给函数的参数。在函数内部,可以使用arguments对象获取到该函数的所有传入参数。arguments 对象仅在函数内部有效,在函数外部调用 arguments 对象会出现一个错误。
严格模式下,
1. arguments 不能通过程序语法被绑定(be bound)或赋值。
2.函数的 arguments 对象会保存函数被调用时的原始参数。arguments[i] 的值不会随与之相应的参数的值的改变而变化,同名参数的值也不会随与之相应的 arguments[i] 的值的改变而变化。
3.不再支持 arguments.callee。arguments.callee 是一个不可删除属性,而且赋值和读取时都会抛出异常。

``` function printPersonInfo(name, age, sex){
   console.log(name);
   console.log(age);
   console.log(sex);
 }
可以写为
function printPersonInfo(){
   console.log(arguments[0]);
   console.log(arguments[1]);
   console.log(arguments[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');```

####5.立即执行函数表达式是什么?有什么作用
立即执行函数通常有下面几种写法:
```(function fn0() {})();
(function fn1() {} ()); 
// 在数组初始化器内只能是表达式
[function fn2() {}];
// 逗号也只能操作表达式
1, function fn3() {};```

在Javascript中,一对圆括号“()”是一种运算符,跟在函数名之后,表示调用该函数。比如,print()就表示调用print函数。
作用:
一是不必为函数命名,避免了污染全局变量;
二是隔离作用域,IIFE内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。

####6.求n!,用递归来实现
```function fn1(i){
 if(i===1){
   return 1;
 }
 return i*fn1(i-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,'sex']  name valley
name:小谷  age:3  sex:undefined   ['小谷',3]  name valley
name:男  age:undefined   sex:undefined    ['男']  name valley

####8. 写一个函数,返回参数的平方和?
```function sumOfSquare() {
   var result = 0;
   for(var i=0; i
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。