Learning Records JavaScript进阶( 四 )


  1. 创建f函数执行上下文,f函数被压入上下文栈ECStack = [fContext,checkscopeContext,globalContext];
  2. f函数上下文初始化,跟之前那一步一样
fContext = {AO: {arguments: {length: 0}},Scope: [AO, checkscopeContext.AO, globalContext.VO],this: undefined}后面就是函数执行完赋值弹出出栈的过程
闭包一般来说,闭包指的是函数+函数所能访问的自由变量自由变量是除了函数参数和函数中的局部变量,可以在函数中使用的变量在ECMAScript中,闭包指的是理论上:所有的函数 。因为在创建函数时,其上下文的数据就都被保存起来了,函数在访问全局变量时其实就是在访问自由变量实践上:即使创建它的上下文已经摧毁,它依然存在(比如内部函数从父函数返回)在代码中引用了自由变量引入之前的一个例子
var scope = "global scope";function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f;}var foo = checkscope();foo();在这个例子中,我们可以复习一下之前学习的执行上下文
? 进入全局代码,创建全局执行上下文,全局执行上下文压入执行上下文栈? 全局执行上下文初始化? 执行 checkscope 函数,创建 checkscope 函数执行上下文,checkscope 执行上下文被压入执行上下文栈? checkscope 执行上下文初始化,创建变量对象、作用域链、this等? checkscope 函数执行完毕,checkscope 执行上下文从执行上下文栈中弹出? 执行 f 函数,创建 f 函数执行上下文,f 执行上下文被压入执行上下文栈? f 执行上下文初始化,创建变量对象、作用域链、this等? f 函数执行完毕,f 函数上下文从执行上下文栈中弹出
可以发现执行f时,checkscope其实已经被销毁了(出栈了)但是f还是可以通过作用域链找到对应的AO,所以即使checkscopeContext被销毁了,但是JavaScript却能让其AO一直在内存中,这就是实践中的闭包
两个例子:
var data = https://www.huyubaike.com/biancheng/[];for (var i = 0; i < 3; i++) { data[i] = function () { console.log(i); };}data[0]();data[1]();data[2]();var data = [];for (var i = 0; i < 3; i++) { data[i] = (function (i) { return function(){ console.log(i); } })(i);}data[0]();data[1]();data[2]();第一段代码的输出都是3,而第二段代码输出分别为0,1,2主要的区别就是第二段代码中多了个匿名函数的作用域链,大家可以自行去解读
call,bind浅析callvar foo = { value: 1};function bar() { console.log(this.value);}bar.call(foo); // 1可以看出,call函数改变了this的指向(指向了foo),并且bar函数也执行了当foo为null时,视为指向window
bindbind会创建一个新函数,bind的第一个参数会作为它运行时的this
var foo = { value: 1};function bar() { console.log(this.value);}// 返回了一个函数var bindFoo = bar.bind(foo); bindFoo(); // 1类数组对象和arguments类数组对象指拥有一个length属性和若干索引属性的对象如
var array = ['name', 'age', 'sex'];var arrayLike = { 0: 'name', 1: 'age', 2: 'sex', length: 3}可以发现类数组对象和数组的长度,遍历,读写一样但是类数组对象是不能用数组的方法的但是类数组可以通过各种方法转化成数组
argumentsfunction foo(name, age, sex) { console.log(arguments);}foo('name', 'age', 'sex')
Learning Records JavaScript进阶

文章插图
在之前的介绍中我们其实已经对argument有了一定的了解
lengtharguments的length表示实参的个数它所对应函数的length表示形参的个数
callee通过该属性函数可以调用自身
var data = https://www.huyubaike.com/biancheng/[];for (var i = 0; i

经验总结扩展阅读