blog icon indicating copy to clipboard operation
blog copied to clipboard

函数与作用域

Open yongheng2016 opened this issue 8 years ago • 0 comments

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

函数声明:

  • 函数声明必须写函数名,否则无法调用;
  • 函数声明的位置可以放在函数调用的前面或者后面,都可以成功调用;(函数声明方式是整体提升到头部)

函数表达式:

  • 函数表达式中,function后面的函数名可以不写,如果写了也只能在函数内部识别;
  • 函数的调用必须放置在函数表达式后面才能成功调用,否则会报错;(函数表达式的提升知识提升了变量名)
F( )
var F = function ( ){
    console.log('a');
}

等同于:

var F;
F( );     //  报错  F is not a function  无法调用
F=function ( ){
console.log('a')
}

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

  • 变量声明前置: 在一个作用域块当中,以var声明的变量提升到代码作用域的头部;
  • 函数声明前置:在一个作用域块当中,以函数声明的方式声明的函数会在js解析的时候被放置于头部优先解析;
    • 函数名称解析顺序:
      • 语言自身定义(Language-defined): 所有的作用域默认都会包含this和arguments。
      • 函数形参(Formal parameters): 函数有名字的形参会进入到函数体的作用域中。
      • 函数声明(Function decalrations): 通过function foo() {}的形式。
      • 变量声明(Variable declarations): 通过var foo;的形式。

3.arguments 是什么

argumnets是一个类似数组对象,对应传递给函数的参数; arguments对象是所有函数中可用的局部变量; arguments对象不是一个 Array 。它类似于数组,但除了 长度之外没有任何数组属性。

4.函数的"重载"怎样实现

有多个同名函数,但参数不同;调用者可以通过调用函数参数的差异来匹配需要调用的函数; js的同名函数要进行覆盖;但可以通过areguments的length值来模拟‘重载’功能;

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

立即调用函数:

  • 首先声明一个匿名函数
  • 然后马上调用这个函数

作用:

  • 创建一个独立的作用域 外面访问不到这个作用域里面的变量,避免变量污染全局;

参考:https://zhuanlan.zhihu.com/p/22465092

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

function fac(num){
    if(num ===1){
		return num;
    }
    if (num===0){
                return 0;
    }
    if (num===-1){
    	return num;
    }
    if (num<0){
        return num*fac(num+1);
    }
	return num*fac(num-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, '男');  
   name: 饥人谷
   age: 2
   sex: 男
   ['饥人谷',2,'男']
   name valley

getInfo('小谷', 3);
   name: 小谷
   age: 3
   sex: undefined
   ['小谷',3]
   name valley

getInfo('男');
   name: 男
   age: undefined
   sex: unundefined
   ['男']
   name valley

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

 function someOfSquares(){
    var result = 0;
    for (var i=0; i<arguments.length; i++){
    result+=Math.pow(arguments[i],2);
    }
    console.log(result);
    return result;		
 }

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

console.log(a);      //undefined                                       
var a = 1;
console.log(b);     // 报错,b is not definted

以上代码等价于:

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

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

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

以上代码等价于:

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

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

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

//10

伪代码:

globalContex = {
AO: {
x:10
foo: function
bar: function
}
}
foo.[[Scope]] = globalContext.AO
bar.[[Scope]] = globalContext.AO
barContext = {
AO: {
x: 30
foo:function
}
Scope: globalContext.AO
}
fooContext = {
AO: {  }
Scope: globalContext.AO
}

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

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

//输出:30

伪代码:

gloabaContext = {
	AO: {
		x:10
		bar: function
	}
	scope: null
}
bar[[Scope]]:globalContext.AO
barContext = {
	AO: {
	x:30
	foo: function
	}
	scope:globalContext.AO
}
foo[[Scope]]:barContext.AO
foo = {
	AO: {}
	Scope: barContext.AO
}

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

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

//输出:30

伪代码:

  globalContext = {
  AO: {
    x:10
    bar:function
  }
  Scope:null
}

bar[[Scope]]=globalContext.AO

barContext = {
  AO:{
    x:30
    立即调用函数:function
  }
  Scope:globalContext
}
立即调用函数Context={
  AO:{ }
  Scope:barContext.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)

//输出:undifined 5 1 6 20 200

伪代码:

globalContext = {
  AO: {
    a:1 ->200
    fn:function
    fn3:function
  }
  Scope:null
}

fn[[Scope]]=globlaContext.AO
fn3[[Scope]]=globlaContext.AO

fnContext = {
  AO:{
    a:undefined ->5 ->6 ->20
    fn2:function
  }
  Scope:globlaContext.AO
}

fn2[[Scope]]:fnContext.AO
fn2Context = {
  AO: {}
  Scope: fnContext.AO
}
fn3Context = {
  AO: {}
  Scope:globlaContext.AO
}

yongheng2016 avatar Jun 04 '17 13:06 yongheng2016