JavaScript基础6.作用域、作用域链、预编译、闭包基础

6.1 对象

函数也是一种对象类型 引用类型 引用值 eg:test.name test.length test.prototype 对象
->有一些属性是我们无法访问的(JS引擎内部固有的属性)eg:[[scope]]

6.2隐式属性 [[scope]]

[[scope]]
1.函数创建时,生成的一个JS内部的隐式属性
2.函数存储作用域链的容器,作用域链有AO/GO AO:函数的执行期上下文 GO:全局的执行期上下文 函数执行完成以后,AO要被销毁,也就是说AO是一个即时的存储容器

6.3作用域链

function a(){
  function b(){
    var b = 2;
  }
  var a = 1;
  b();
}
var c = 3;
a();

当a函数被定义时

系统生成[[scope]]属性,[[scope]]保存该函数的作用域链,该作用域链的第0位存储当前环境下的全局执行上下期上下文GO,GO里面存储全局下的所有对象,其中包含函数a和全局变量c

function a(){}
var c = 3;

image.png

当a函数被执行时(前一刻)

作用域的顶端(第0位)存储a函数生成的函数执行期上下文AO,同时第1位存储GO。查找变量是到a函数的作用域从顶端开始依次向下查找。

function a(){
  function b(){}
  var a = 1;
}
var c = 3;
a();

image.png

当b函数被定义时

是在a函数环境下,所以b函数这时的作用域链就是a函数被执行期的作用域链

function a(){
  function b(){}
  var a = 1;
}
var c = 3;
a();

image.png

当b函数被执行时(前一刻)

生成函数b的[[scope]],存储函数b的作用域链,顶端第0位存储b函数的AO,a函数的AO和全局的GO依次向下

function a(){
  function b(){
    var b = 2;
  }
  var a = 1;
  b();
}
var c = 3;
a();

image.png

当b函数被执行结束后

b函数的AO被销毁,回归被定义时的状态

image.png

当a函数执行结束后

a函数的AO被销毁的同时,b函数的[[scope]]也将不存在。 a函数回归到被定义时的状态。

image.png

function a() {
  function b() {
    function c() {

    }
    c();
  }
  b();
}
a();

a 定义:a.[[scope]] -> 0 : GO
a 执行:a.[[scope]] -> 0 : a->AO-> 1: GO
b 定义:b.[[scope]] -> 0 : a->AO-> 1: GO
b 执行:b.[[scope]] -> 0 : b->AO-> 1 : a->AO-> 2 : GO
c 定义:c.[[scope]] -> 0 : b->AO-> 1 : a->AO-> 2 : GO
c 执行:c.[[scope]] -> 0 : c->AO-> 1: b->AO-> 2 : a->AO -> 3 : GO
c 结束:c.[[scope]] -> 0 : b->AO-> 1 : a->AO -> 2 : GO
b 结束:b.[[scope]] -> 0 : a->AO -> 1 : GO c.[[scope]] x 没有了
a 结束:a.[[scope]] -> 0:GO b.[[scope]] x 没有了

6.4闭包

function test1() {
  function test2() {
    var b = 2;
    console.log(a);
  }
  var a = 1;
  return test2();
}
var c = 3;
var test3 = test1();
test3();

当test1函数被定义时

系统自动生成[[scope]]属性,[[scope]]保存该函数的作用域,该作用域的第0位存储当前环境下的全局执行期上下文GO,GO里存储全局下的所有对象,其中包含函数test1和全局变量c和test3

function test1(){}
var c = 3;
var test3 =test1();

image.png

当test1函数被执行时(前一刻)

test2被定义

function test1() {
  function test2() {  
  }
  var a = 1;
  return test2();
}
var c = 3;
var test3 = test1();

image.png

当test1函数执行结束时

因为test2被返回到外部,且被全局变量test3接收。 这时的test1的AO并没有被销毁,只是把线剪断,test2的作用域链还与之相连。

image.png

当test3执行时

test2的作用域链增加自己的AO

image.png

当test3执行结束后

test2的AO被销毁,但原来test1的AO仍然存在且被test2连着

image.png

应用

  1. 实现累加、累减
function test() {
  var n = 100;
  console.log(n);
  function add() {
    n++;
    console.log(n);
  }
  function reduce() {
    n--;
    console.log(n);
  }
  return [add, reduce];
}

var arr = test();
arr[0](); // 101
arr[1](); // 100
arr[1](); // 99

// 闭包也是一种数据缓存
  1. 实现一个面包管理器
function breadMgr(num){
  var breadNum = arguments[0] || 10; // 或者用 num || 0
  function supply(){
    breadNum += 10;
    console.log(breadNum);
  }
  function sale(){
    breadNum -= 1;
    console.log(breadNum);
  }
  return [supply, sale];
}

var breadMgr = breadMgr(50);
breadMgr[0]();
breadMgr[1]();
breadMgr[1]();

3.星期天计划管理

function sunSched() {
  var sunSched = '';
  var operation = {
    setSched: function(thing) {
      sunSched = thing;
    },
    showSched: function() {
      console.log("Schedule on sunday is " + sunSched);
    }
  }
  return operation;
}

var sunSched = sunSched();
sunSched.setSched('studying');
sunSched.setSched('walking');
sunSched.showSched();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值