闭包作用域练习题(关于形参赋值默认的练习题)

300 阅读1分钟

1、

/*
/!*
 * EC(G)
 *   var x;
 *   func = 0x0001; [[scope]]:EC(G)
 *!/
var x = 1;
function func(x, y = function anonymous1(){x = 2}){
    /!*
     * EC(FUNC) 
     *  作用域链:<EC(FUNC),EC(G)>
     *  形参赋值:x=5 y=0x0002(anonymous1) [[scope]]:EC(FUNC)
     *  变量提升:--
     *!/
    x = 3; //私有x=3
    y();
    /!*
     * EC(Y)
     *   作用域链:<EC(Y),EC(FUNC)>
     *   形参赋值:--
     *   变量提升:--
     * 
     * 代码执行  x=2  把EC(FUNC)中私有的x修改为2
     *!/
    console.log(x); //=>2
}
func(5);
console.log(x); //=>1

2、

ES6新规则:

 *   前提:
 *     1. 函数有形参赋值默认值,不论是否生效(也就是传递值后不走默认值)都遵循如下的规律
 *     2. 函数体中有声明变量「基于let/const/var」,注意:let/const声明的变量是不允许重复的(不能和形参一致) 不然会报错

规则:

(1)、函数执行会产生一个私有的执行上下文「作用域链->this->arguments->形参赋值」
(2)、它会把函数体中的代码,单独作为一个私有的“块级”上下文,并且其上级上下文是函数的那个私有的上下文

(3)、小知识点:如果函数私有上下文中的某变量和块级上下文中的某变量一致,则块级上下文的最开始时候,会把函数上下文中的值同步给块级上下文中同名变量一份

3、练习题

//debugger;
var x = 1;
function func(x, y = function anonymous1(){x = 2})
{
    var x = 3;
    y();
    console.log(x);
};
func(5);
console.log(x); 

4、

// debugger;
var x = 1;
function func(x, y = function anonymous1(){x=2}){
    var x = 3;
    var y = function anonymous2(){x = 4}
    y();
    console.log(x);
};
func(5);
console.log(x);  

5、如果块级上下文里面是funtion,那么不会产生两个上下文

  debugger;
  function func(x = 3) {
      function x() {}
  }
  func(10);