函数与作用域 知识点总结

2017-02-10  本文已影响8人  osborne

一:函数声明和函数表达式的区别

注:区别是函数声明会提前,即可以在函数声明之前调用函数。而函数表达式只会将变量先提升,此时的变量是undefined,所以不能在函数表达式前调用函数。

二:什么是变量的声明前置?什么是函数的声明前置

console.log(a) //undefined
var a = 1;
console.log(a); //1
//相当于
var a;
console.log(a);
a = 1;
console.log(a);
fn(); //3 因为函数声明提前,所以不会报错
function fn() {
    console.log(3);
}

三:arguments 是什么

var f = function(one) {
  console.log(arguments[0]);
  console.log(arguments[1]);
  console.log(arguments[2]);
}
f(1, 2, 3)
// 1
// 2
// 3

四:函数的"重载"怎样实现

  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');

五:立即执行函数表达式是什么,作用呢

(function(){
  var a  = 1;
})()

其他写法:

(function fn1() {});
[function fn2() {}];
1, function fn3() {};

六:求n!,用递归来实现

function factor(n){
  if(n === 1) {
    return 1
  }
  return n * factor(n-1)
}

七:以下代码输出什么

    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:undefiend sex:undefined ["男"] name valley */

八:写一个函数,返回参数的平方和

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

九:如下代码的输出?为什么

    console.log(a);
    var a = 1;
    console.log(b);
    /* 输出:undefined 报错:b is not defined 原因:变量提升,没有b变量的声明*/

十:如下代码的输出?为什么

    sayName('world');//输出:hello world 函数声明前置
    sayAge(10);//报错:sayAge is not a function 函数表达式不前置
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };

十一:如下代码输出什么? 写出作用域链查找过程伪代码

var x = 10
bar() 
function foo() {
  console.log(x)
}
function bar(){
  var x = 30
  foo()
}
/* 输出:10
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
} */

十二:如下代码输出什么? 写出作用域链查找过程伪代码

var x = 10;
bar() 
function bar(){
  var x = 30;
  function foo(){
    console.log(x) 
  }
  foo();
}
/* 输出:30
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
} */

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

var x = 10;
bar() 
function bar(){
  var x = 30;
  (function (){
    console.log(x)
  })()
}
/* 输出:30
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
} */

十四:以下代码输出什么? 写出作用域链查找过程伪代码

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.首先将声明都提前,然后1赋值给a,调用函数fn(),第一个console.log(a)由于a还没有赋值5,但已经声明(var a)所以输出undefined;第二个console.log(a)则已经赋值5,所以输出5;
2.接着调用函数fn3(),因为函数fn3()并不在函数fn()的作用域,所以输出全局变量a=1,并且把全局变量a“污染“为200;
3.紧接着调用函数fn2(),在函数fn()的作用域里,之前由于a++,所以输出6,且对函数fn()的作用域的a进行赋值20;
4.然后又是一个console.log(a),在函数fn()的作用域里,上一步已经调用为20了,所以输出20;
5.最后又是一个在函数fn()的作用域里,这次在全局作用域里,函数体外,之前第二步解释了全局变量a为200,所以输出200;
综上输出结果就是:undefined 5 1 6 20 200

- 参考 作用域链视频讲解(2017.08.21更新)
上一篇 下一篇

猜你喜欢

热点阅读