1-1
作用域 & 上下文
作用域链
let a = 'global'
function course(){
let b = 'zhangsan'
session()
function session() {
let c = 'session'
teacher()
function teacher() {
console.log('ds', d)
var d = 'yyu' // 变量提升 && 范围: 当前作用域
console.log('d': d) // 作用域生效
console.log('b', b) // 作用域向上查找
}
}
}
let 具有块级作用域, 没有变量提升
var 具有变量提升, 变量提升的 范围在当前作用域下
执行栈:
提升优先级问题
函数会需要变量 变量, 函数同时提升时 提升维度: 变量优先 执行维度: 函数先被打印
函数是天然的隔离方案(模块化), if不形成作用域
if (true) {
var f =222
}
console.log(f) // 222
-
- 对于作用域链, 我们可以直接通过创建态去定位链条中的某一环,
-
- 手动取消链条环甚至全局作用域链的时候, 可以利用块级作用域做性能优化
this 上下文 context
- this 是在执行时动态读取上下文所决定的
函数直接调佣: this指向window
function foo() {
console.log('函数内容this', this)
}
foo() // window
隐式绑定 - this 的指向是调用堆栈的上一级
function fn() {
console.log('隐式绑定', this)
}
const obj = {
a: 1,
fn
}
obj.fn = fn
obg.fn()
面试题
const foo = {
bar: 10,
fn: function(){
console.log(this.bar)
console.log(this)
}
}
// 取出
let fn1 = foo.fn
fn1() // this 指向window, 看执行时处于哪个环境
// 追问:
const o1 = {
text: 'o1',
fn: function(){
// 直接使用上下文 => 传统分活
console.log('o1_this', this)
return this.text
}
}
const o2 = {
text: 'o2',
fn: function() {
// 部门协助
console.log('o2_this', this)
return o1.fn()
}
}
const o3 = {
text: 'o3',
fn: function(){
// 直接借人
console.log('o3_this', this)
let fn = o1.fn
return fn()
}
}
console.log('o1', o1.fn()) // o1
console.log('o2', o2.fn()) // o1
console.log('o3', o3.fn()) // window
- 1.在执行函数的时候, 函数执行时调用方上一级 => 上下文
- 2.公共函数 | 全局调用指向window
显示绑定(bind | apply | call)
-
- call < = > apply 传参不同 依次传入 / 数组传入
-
- bind 返回值不同 (只是改变了传参, 没有执行)
- 面试: 手写apply & bind
// 1. 需求: 手写bind => bind位置 => Function.prototype => 原型
Function.prototype.newBind = function() {
// 1.2. bind 原理
const _this = this
const args = Array.prototype.slice(arguments) // 类数组 伪数组
const newThis = args.shift()
// 1.3. 返回值不执行, 返回函数
return function() {
// 执行核心
_this.newApply(newThis, args)
}
}
// 2. 内层执行
Function.prototype.newApply = function(context) {
// 参数兜底
const context = context || window
// 临时挂载执行函数
context.fn = this
let result = argument[1] ? context.fn(...arguments[1]): context.fn()
delete context.fn
return result
}
追问: 如何突破作用域
闭包
function mail(){
let content = '信'
return function(){
return content
}
}
const envelop = mail()
envelop()