在初学阶段,还蛮常碰到明明定义好的变数却回报 error,可能是因为对 Scope 的观念没有理解。
我习惯称 Scope 为作用域,有人称为范畴,是一个用来查找、访问变数及函式的规则。
在 ES6 的 let、const 出现之前,我们只有函式作用域 ( var ),但 ES6 後多了区块作用域,主要是定义了 let、const 作用范围 。
简单来说,作用域表示变数或者函式有作用的地方。
function sayHi(){
var guy = 'Lisa'
function greet(){...}
console.log(guy)
}
console.log(guy)
greet()
上面程序码,我们在全域宣告了一个函式 sayHi ,函式里面宣告变数 guy 以及函式 greet,但当我们想从全域取用 guy 跟 greet 就会报错,因为这两者的作用域在 sayHi 里面。
但为什麽下面的例子,我们可以访问函式以外的变数?
var idol = 'Rose'
function sing(){
console.log(idol)
}
sing()
idol 宣告在全域环境,却能在 sing 函式里呼叫,这是靠作用域链 Scope Chain 查找的结果。
前几篇讲执行环境 Execution context 的时候,我们提到 JS 遇到函式调用时会创建一个属於该函式的执行环境,每个函式内部有自己的 [[scope]],调用函式时的执行环境会把 [[scope]] 跟 Scope Chain 连结。
当全域执行环境建立时,创造阶段初始化了全域的 variable object 以及 scope chain。
globalExecutionContext:{
VO:{
idol:undefined,
sing:function
},
ScopeChain:{
globalExecutionContext.VO
}
}
// 并且宣告 sing 函式时,sing 的作用域会参考由全域给的 scopechain 的内容
sing.[[scope]] = globalExecutionContext.ScopeChain
接着 sing() 被调用,因着 sing 的 scope 可以透过 scoope chain 取得外部全域的变数
此外,若无使用宣告定义变数的话,则 JS 会视为全域变数 ( 这是不好的习惯哦~ )
var idol = 'Rose'
function sing(){
fruit = 'grape'
}
console.log(fruit)
>>: 18.移转 Aras PLM大小事-快速贴入ECR受影响物件
因为我们之後练习需要透过 metasploitable 3 当作靶机,所以要先安装 metaspl...
9/25: 隔一天才发现因为前一天字数不够,草稿发文不成功所以断赛了QQ 还是把昨天测试的结果放上来...
Cursor and Zoom-in 今天继续增加图表功能,其中两个很常需要的功能就是游标和区域放...
全文同步於个人 Docusaurus Blog 当建立私人频道後,下一步,便是将私人频道的讯息发往...
梯度提升树是什麽? 讲人话就是将随机森林的概念更进一步应用,策略性地逐步建构多棵决策树模型,间接让重...