函数与作用域

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

  • 函数声明必须带有标示符(Identifier)(即函数名称),而函数表达式则可以省略这个标示符。
  • 函数声明:function functionName(){}
    function 函数名称 (参数:可选){ 函数体 }
  • 函数表达式:var functionName = function(){}
    function 函数名称(可选)(参数:可选){ 函数体 }
  • 函数声明的调用函数,可以在函数声明之前或之后,而函数表达式的调用函数必须在函数表达式之后。

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

  • 变量声明前置:JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部。
console.log(a);
var a = 1;
即
var a;
console.log(a);//undefined
a = 1;
  • 函数声明前置:JavaScript引擎将函数名视同变量名,所以采用function命令声明函数时,整个函数会像变量声明一样,被提升到代码头部。
function fn() {
  console.log('hello')
}
var a = 1;
即
function fn() {}
var a
function fn() {
  console.log('hello')
}
a=1
  • 函数内部的声明前置也遵循上面的规则,只不过是提升到函数体的头部。

3、arguments 是什么

  • arguments对象包含了函数运行时的所有参数,arguments[0]就是第一个参数,arguments[1]就是第二个参数,以此类推。这个对象只有在函数体内部,才可以使用。
function fn(){
  console.log(arguments[0])
}
fn(1)
fn(1,2)
//1
//1
或
function fn(){
  console.log(arguments)
}
fn(1)
fn(1,2)
// [1]
// [1, 2]

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、立即执行函数表达式是什么?有什么作用

  • 立即执行函数表达式(Immediately-Invoked Function Expression),简称IIFE。表示定义函数之后,立即调用该函数。
常见写法:
(function fn1() {})();
(function fn2() {}());
  • 作用:隔离作用域

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

function fn(n){
  if(n>1){
  return n*fn(n-1)
  } else if(n==1 || n==0){
    return 1
    } else 
      console.log('Input Error')
}
fn(5)
fn(0)
fn(-4)

7、以下代码输出什么?

function getInfo(name, age, sex){
        console.log('name:',name);
        console.log('age:', age);
        console.log('sex:', sex);
        console.log(arguments); 
        arguments[0] = 'valley'; // var name='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 result=0; // result2
  for(i=0;i<arguments.length;i++){
    result =result+arguments[i]*arguments[i]   // result2
    } return result   // result2
   }
   var result = sumOfSquares(2,3,4)
   var result2 = sumOfSquares(1,3)
   console.log(result)  //29
   console.log(result2)  //10

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

console.log(a); //此时a已经被声明,undefined
var a = 1;
console.log(b); //b没被声明,报错
// undefined   报错

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

sayName('world'); //不报错, 声明函数前置,调用后面的声明函数
sayAge(10); //报错,此时只声明了变量sayAge,并没有声明函数sayAge()
    function sayName(name){
        console.log('hello', name);
    }
    var sayAge = function(age){
        console.log(age);
    };
// hello world  报错

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

var x = 10
bar() 
function foo() {
  console.log(x)
}
function bar(){
  var x = 30
  foo()
}
// 10
/*
1.
GlobalContext{
  AO{
    x:10
    function foo()
    function bar()
  }
}
foo()[scope]=GlobalContext.AO
bar()[scope]=GlobalContext.AO
2.
barContext{
  AO{
    x:30 
  }  scope:GlobalContext.AO
}
3.
fooContext{
  AO{
  }  scope:GlobalContext.AO
}
//输出:10
*/

12、

var x = 10;
bar() 
function bar(){
  var x = 30;
  function foo(){
    console.log(x) 
  }
  foo();
}
// 30
/*
1.
GlobalContext{
  AO{
    x:10
    function bar()
  }
}
bar()[scope]=GlobalContext.AO
2.
barContext{
  AO{
    x:30 
     function foo()
  }  scope:GlobalContext.AO
}
foo()[scope]=barContext.AO
3.
fooContext{
  AO{
  }  scope:barContext.AO
}
//输出:30
*/

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

var x = 10;
bar() 
function bar(){
  var x = 30;
  (function (){
    console.log(x)
  })()
}
// 30
/*
1.
GlobalContext{
  AO{
    x:10
    function bar()
  }
}
bar()[scope]=GlobalContext.AO
2.
barContext{
  AO{
    x:30 
  }  scope:GlobalContext.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)
// undefined 5 1 6 20 200
/*
1.
GlobalContext{
  AO{
    a:1 // 200
    function fn()
    function fn3()
  }
}
fn()[scope]=GlobalContext.AO
fn3()[scope]=GlobalContext.AO
2.
fnContext{
  AO{
    a: undefined // 5 // 6 // 20
    function fn2()
  }scope:GlobalContext.AO
}
fn2()[scope]=fnContext.AO
3.
fn3Context{
  AO{
  }scope:GlobalContext.AO
}
4.
fn2Context{
  AO{
  }scope:fnContext.AO
}
//输出:undefined 5 1 6 20 200
*/
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 函数声明和函数表达式有什么区别? 函数声明和函数表达式是EMACScript规定的两种不同的声明函数的方法。1.函...
    LeeoZz阅读 355评论 0 1
  • 1. 函数声明和函数表达式有什么区别 使用function关键字声明一个函数时,声明不必放到调用的前面。//函数声...
    _李祺阅读 287评论 0 0
  • 1,函数声明和函数表达式有什么区别 1、背景介绍 定义函数的方法主要有三种: 1:函数声明(Function De...
    进击的前端_风笑影阅读 453评论 0 0
  • 任务 函数声明和函数表达式有什么区别答:函数声明:function functionName(){}  函数表达式...
    mhy_web阅读 424评论 0 0
  • 1.函数声明和函数表达式有什么区别 函数声明不必放在调用前面 函数表达式必须放在调用前面 2.什么是变量的声明前置...
    LINPENGISTHEONE阅读 306评论 0 0