进阶3-函数与作用域

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

函数声明:
function sayHello(){ console.log('hello') }
调用:sayName()
声明不用放到调用前面,声明时候不执行调用时候才执行
函数表达式:
var sayName = fimction() { console.log('hello') }
调用:sayName()
声明必须放到调用的前面

2.什么是变量的声明前置?什么是函数的声明前置

JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting),也称变量的声明前置。
函数的声明前置指的是声明的函数会提升到当前作用域的顶部。

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);
 }
}
printPeopleInfo('Byron', 26);//Byron 26
printPeopleInfo('Byron', 26, 'male');//Byron 26 male

5.立即执行函数表达式是什么?有什么作用

起到隔离作用,不会产生全局变量污染的问题,形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。
例:
(function(){ var a=1; var b=2; }) ()

6.求n!,用递归来实现

function factor(n){
if(n===1){
return 1
}
else if(n=== -1){
return -1
}
else if(n=== 0){
return 0
}
return n * factor(n-1)
}
调用: factor(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, '男');
    getInfo('小谷', 3);
    getInfo('男');
name: 饥人谷
 age: 2
 sex: 男
(3) ["饥人谷", 2, "男", callee: function, Symbol(Symbol.iterator): function]
 name valley
 name: 小谷
age: 3
sex: undefined
(2) ["小谷", 3, callee: function, Symbol(Symbol.iterator): function]
 name valley
 name: 男
 age: undefined
 sex: undefined
 ["男", callee: function, Symbol(Symbol.iterator): function]
name valley

8. 写一个函数,返回参数的平方和?

function sumOfSquares(){
    var result = 0;
    for(var i = 0;i < arguments.length;i++){
        result += Math.pow(arguments[i],2)
    }
    return result;
   }
   var result = sumOfSquares(2,3,4)
   var result2 = sumOfSquares(1,3)
   console.log(result)  //29
   console.log(result2)  //10

9. 如下代码的输出?为什么

console.log(a);
   var a = 1;
console.log(b); // undefined

输出console.log(a)为undefined,var不是函数前置后,console.log(b)为声明输出为undefined,结果就是undefined

10. 如下代码的输出?为什么

sayName('world');
sayAge(10);
function sayName(name){
   console.log('hello ', name);
}
var sayAge = function(age){
    console.log(age);
}; //hello  world

function sayName(name)是函数声明可以先写调用再写声明,var sayAge = function(age)是函数表达式,声明必须写在调用前面,而且sayAge(10)前置了输出结果是undefined

11. 如下代码输出什么? 写出作用域链查找过程伪代码

var x = 10
bar() 
function foo() {
  console.log(x)
}
function bar(){
  var x = 30
  foo() // 10
}
1.
globalContent ={
AO:{
x: 10
foo: function
bar: function
},
Scope: null
}
//声明foo时 得到下面
foo.[[scope]] = golbalContenxt.AO
//声明bar时 得到下面
bar.[[scope]] = golbalContenxt.AO
2.
barContext ={
AO:{
x: 30
},
Scope: bar.[[scope]] //globalConyext.AO
}
3.
调用foo()时,先从bar执行上下文中的AO里找,找不到再从bar的[[scope]]里找,找到后即调用
fooContext={
AO:{}
Scope: foo.[[scope]] //globalContext.AO
}
foo里没有var、function。AO活动对象就是空的
foo.[[scope]] = golbalContenxt.AO
在自己里面没有找到,就从globalContext里面找,找到x=10, 所以console.log(x)=10

12. 如下代码输出什么? 写出作用域链查找过程伪代码

var x = 10;
bar() 
function bar(){
  var x = 30;
  function foo(){
    console.log(x) 
  }
  foo(); //30
}   
1.
globalContext ={
AO:{
x: 10
bar: function(){}
}
}
bar.[[scope]]= globalContext.AO
2.
barContext={
AO{
x: 30
foo: function(){}
},
Scope: bar.[[scope]]= barContext.AO
}
3.
fooContext={
AO{}
Scope: foo.[[Scope]]= barContext.AO
}
AO里没有值,foo在bar里,就回到barContext里面找到x: 30,则console.log(x)=30.

13. 以下代码输出什么? 写出作用域链的查找过程伪代码

var x = 10;
bar() 
function bar(){
  var x = 30;
  (function (){
    console.log(x)
  })() //30
}
1.
globalContext={
AO:{
x: 10
bar: function(){}
}
}
bar.[[scope]]= globalContext.AO
2.
barContext={
AO:{
x: 30
匿名: function(){}
},
Scope: bar.[[Scope]]= globalContext.AO
Scope: 匿名.[[scope]]= barlContext.AO
}
3.
匿名Context={
AO:{}
Scope: 匿名.[[scope]]= barlContext.AO
}

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)

输出:

undefined
5
1
6
20
200

分析:

1. globalContext={
AO:{
a: 1
fn: function
fn3: function
}
}

fn[[scope]]=globalContext.AO
fn3[[scope]]=globalContext.AO

2.fnContext={
AO:{
a: 6
fn2: function(){}
},
Scope: globalContext.AO
}
fn2[[scope]]=fnContext.AO

3. fn3Context{
AO:{},
Scope: globalContext.AO
}
4. fn2Context{
AO:{},
Scope: fnContext.AO
}
fn(){
 function fn2(){}
 var a
 console.log(a) //  undefined
 a = 5
 console.log(a)  // 5
 a++   // a = 6
 fn3()  //1  赋值globalContext.AO的a=200
 fn2()   //6,赋值fnContext.AO的a=20
 console.log(a) // 20
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容