this/闭包/作⽤域

this/闭包/作⽤域
专业术语
  • 常量、变量、数据类型
  • 形参、实参
  • 匿名函数、具名函数、自执行函数
  • 函数声明、函数表达式
  • 堆、栈
  • 同步、异步、进程、线程
执行上下文

当函数执行时,会创建一个称为执行上下文(execution context)的环境,分为创建和执行两个阶段

创建阶段

创建阶段,指函数调用但未执行任何代码时,此时创建了一个拥有三个属性的对象:

executionContext = {
    scopeChain: {}, // 创建作用域链(scope chain)
    variableObject: {}, // 初始化变量、函数、形参
    this: {} // 指定this  
}
代码执行阶段

代码执行阶段主要的工作是:1、分配变量、函数的引用,赋值。2、执行代码。

// 执行这段代码
function demo(num) {
    var name = 'jinxing';
    var fn = function fn() {};
    function a() {}
}
demo(500);

// 创建阶段,在这个阶段就出现了变量提升(Hoisting)
executionContext = {
    scopeChain: { ... }, // 作用域链是一个引用数组
    variableObject: {
        arguments: { // 创建了参数对象
            0: 100,
            length: 1
        },
        num: 500, // 创建形参名称,赋值/或创建引用拷贝
        a: pointer to function a(), // 有内部声明的话,创建引用指向函数体
        name: undefined, // 有内部声明变量a,初始化为undefined
        fn: undefined // 有内部声明变量fn,初始化为undefined
    },
    this: { ... }
}
    
// 代码执行阶段,在这个阶段主要是赋值并执行代码
executionContext = {
    scopeChain: { ... },
    variableObject: {
        arguments: {
            0: 100,
            length: 1
        },
        num: 500,
        a: pointer to function a(),
        name: 'jinxing', // 分配变量,赋值
        fn: pointer to function fn() // 分配函数的引用,赋值
    },
    this: { ... }
}
执行上下文栈
  • 浏览器中的JS解释器是单线程的,相当于浏览器中同一时间只能做一个事情。
  • 代码中只有一个全局执行上下文,和无数个函数执行上下文,这些组成了执行上下文栈(Execution Stack)。
  • 一个函数的执行上下文,在函数执行完毕后,会被移出执行上下文栈。
作用域链

作用域链是一个引用数组,当一个块或函数嵌套在另一个块或函数中时,就发生了作用域的嵌套。在当前函数中如果js引擎无法找到某个变量,就会往上一级嵌套的作用域中去寻找,知道找到该变量或抵达全局作用域,这样的链式关系就称为作用域链(Scope Chain)。js 是基于词法作用域的,是静态分析的,并不是执行的时候向上找,而是定义的时候向上找。

闭包

闭包是指有权访问另个一个函数作用域中变量的函数。

// 举例:
function create() {
    var a = 0
    return function () {
		var c = 1
        console.log(a)
    }
}
var b = create()
b()
// create函数执行,创建了自己的执行上下文环境和作用域链,create的作用域链数组中,0号位放的是create函数自己的活动变量(对象){a: 0}的引用,1号位放的是全局变量对象(window)的引用。
// 当create函数执行完毕,返回一个新的匿名函数赋值给b,此时create函数的执行上下文环境的作用域链会被销毁,但是b函数的作用域链中还存在对create函数活动变量(变量)的引用,所以内存中的{a: 0}不会被销毁。
// b函数执行,创建自己的执行上下文环境及相应的作用域链,b函数作用域链的0号位是自己的活动变量(对象){c: 1}的引用,1号位是create函数的活动变量(对象){a: 0}的引用,2号位放的是全局变量对象(window)的引用。
// b函数执行完毕,销毁b函数的执行上下文环境和作用域链。

this

谁用点操作符调用函数,函数内的this就指向谁。


// 例 1: 函数直接调⽤时
function myfunc() { 
    console.log(this) // this是widow 
}
myfunc()

// 例 2:函数被别⼈调⽤时
function myfunc() { 
    console.log(this) // this是对象a 
}
var a = { 
    myfunc: myfunc 
}
a.myfunc()

// 例 3:new⼀个实例时
function Person(name) { 
    this.name = name; 
    console.log(this); // this是指实例p 
}
var p = new Person('jinxing');

// 例 4:有apply、call、bind时
function getColor(color) { 
    this.color = color;
    console.log(this); 
}
function car(name, color) { 
    this.name = name; // this指的是实例car 
    getColor.call(this, color); // 这⾥的this从原本的getColor,变成了car 
}
var car = new Car('卡⻋', '绿⾊');

// 例 5:有箭头函数时
var a = { 
    myfunc: function() { 
        setTimeout(() => { 
            console.log(this); // this指向父级作用域中的this,也就是a 
        }, 0) 
    } 
};
a.myfunc();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值