JavaScript函数与作用域的知识点

2017-04-13  本文已影响0人  柏龙

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

函数声明使用 function fn(){} 直接写 ,在函数前后都可以调用该函数

fn(); // jirengu
function fn(){
    console.log('jirengu');
}
fn(); // jirengu

函数表达式使用 var fn = function(){} 声明,调用函数必须先声明,再调用

fn(); // 报错 fn is not a function
var fn = function(){
    console.log('jscode')
}
fn(); // jscode

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

在同一个作用域下,声明前置是把该声明的变量和函数提升到自身所在作用域的最顶部。

console.log(str);
var str = 'jirengu';
console.log(str);
fn();
function fn(){
    console.log('jirengu');
}

js解析顺序

var str;
function fn(){
    
}

console.log(str); // undefined
var str = 'jirengu';
console.log(str); // jirengu
fn();
console.log('jirengu');

arguments 是什么

arguments 是一个类数组对象,它包含了函数的所有传入参数,可以用数组下标来获取值,不建议使用,因为可读性很差

function fn(name, age, sex){
    console.log(name);  // 柏龙
    console.log(age);   // 30
    console.log(sex);   // 男
    console.log(arguments); // 获取的是 ['柏龙', 30, '男']
    console.log(arguments[0]);  // 柏龙
}
fn('柏龙', 30, '男');

函数的"重载"怎样实现

在JS中没有重载,同名函数会覆盖
但可以在函数体针对不同的参数调用来执行相应的逻辑

function fn(name, age, sex){
    if(name){
        console.log(name);
    }
    if(age){
        console.log(age);
    }
    if(sex){
        console.log(sex);
    }
}
fn('柏龙', 30);
fn('柏龙', 30, '男');

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

(function(){ var str = 'jirengu'; })();

作用 隔离作用域,让函数里面的变量被保护起来,外部无法访问

求n!,用递归来实现

function fn(n){
    if(n === 1){
        return 1;
    }
    return n * fn(n-1);
}
fn(6); // 720 => 6 * 5 * 4 * 3 * 2 * 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, '男');
getInfo('小谷', 3);
getInfo('男');

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

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

function sumOfSquares(){

}
var result = sumOfSquares(2,3,4)
var result2 = sumOfSquares(1,3)
console.log(result)  //29
console.log(result)  //10

代码:

function sumOfSquares(){
    var result = 0;
    for (var i = 0; i < arguments.length; i++) {
        result += arguments[i] * arguments[i]
    }
    return result;
}

如下代码的输出?为什么

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

依次输出:

undefined 
Uncaught ReferenceError: b is not defined

因为声明的变量会提升到自身所在作用域的最顶部。

console.log(a); // 先声明,在第一行输出是没有赋值,输出undefined
console.log(b); // 没有声明 所以会报错

如下代码的输出?为什么

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

依次输出:

undefined 
Uncaught TypeError: sayAge is not a function

因为 function 声明函数无论写在函数体前面或后面都可以调用,函数表达式在调用时必须先声明,再调用

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

var x = 10
bar() 
function foo() {
  console.log(x)
}
function bar(){
  var x = 30
  foo()
}

代码输出: 10

globalContent = {
    AO: {
        x: 10,
        foo: function,
        bar: function
    },
    scope: null
}
foo.[[scope]] = globalContent.AO;
bar.[[scope]] = globalContent.AO;

barContent = {
    AO: {
        x: 30
    },
    scope : globalContent.AO;
}
fooContent = {
    AO: {
        
    },
    scope : globalContent.AO;
}

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

var x = 10;
bar() 
function bar(){
  var x = 30;
  function foo(){
    console.log(x) 
  }
  foo();
}

代码输出:30

globalContent = {
    AO: {
        x: 10,
        bar: function
    },
    scope: null
}
bar.[[scope]] = globalContent.AO;

barContent = {
    AO: {
        x: 30,
        foo: function
    },
    scope : globalContent.AO;
}
foo.[[scope]] = barContent.AO;

fooContent = {
    AO: {
        
    },
    scope : barContent.AO;
}

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

var x = 10;
bar() 
function bar(){
  var x = 30;
  (function (){
    console.log(x)
  })()
}

代码输出:30

globalContent = {
    AO: {
        x: 10,
        bar: function
    },
    scope: null
}
bar.[[scope]] = globalContent.AO;

barContent = {
    AO: {
        x: 30,
        fn : function 
    },
    scope : globalContent.AO;
}
foo.[[scope]] = barContent.AO;

fnContent = {
    AO: {
        
    },
    scope : barContent.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
globalContent = {
    AO: {
        a: 1, // fn3 调用fnContent.AO a=200
        fn: function,
        fn3: function
    },
    scope: null
}
fn.[[scope]] = globalContent.AO;
fn3.[[scope]] = globalContent.AO;

fnContent = {
    AO: {
        a: undefined, // 第二次打印为 5  
        fn3: function, // 第三次打印 1
        fn2: function, // 第4次打印 6
    }
    scope: globalContent.AO;
}
fn3Content = {
    AO: {
        
    },
    scope: globalContent.AO;
}

fn2Content = {
    AO: {
        a: 20 // 第5次打印 调用fnContent.AO a=20 
    }
    scope: fnContent.AO;
}
上一篇下一篇

猜你喜欢

热点阅读