今天的重點圍繞著兩個問題:
Other than declarations, all occurrences of variables/identifiers in a program serve in one of two "roles": either they're the target of an assignment or they're the source of a value.
先看這段程式碼:
var students = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Amber" },
{ id: 3, name: "Julia" },
{ id: 4, name: "Kelly" },
];
function getStudentName(studentId) {
for (let student of students) {
if (student.id === studentId) {
return student.name
}
}
}
var nextStudent = getStudentName(73);
console.log(nextStudent);
如同上面提到的: ... they're the target of an assignment,所以只要出現在等號左邊,就是 target 了嗎?
這段程式碼,總共有五個 variables 屬於 targets !
1 和 2 可能很容易看;
getStudentName(73) 的 argument 73 被 assign 給 studentId;
在 for loop 裡的 let student of ...
在每一次 iteration 都被賦予新的 value;function getStudentName() {...}
這個函式陳述式,也是 target reference。怎麼說呢?
想像成 var getStudentName = function(studentId)
,只不過 getStudentName
與 function() {...}
的連結會被提升 (hoisting) 到 scope 的最頂端,而不會等到 =
執行才有連結。
基本上,只要不是 target 的變數,就屬於 source 了;
不過要留意,像是 if(student.id === studentId)
student 是 source,id 則是 student 的 property,不是 source 噢!
回想上篇文章,JS engine 處理 program 大致分成:
我們常說的 scope 其實就是 lexical scope,在 lexing 階段就完成了,因此 scope 是固定不變的 (Kyle 有提到兩種方法去做 runtime scope modification,但最好不要這麼做)。
scope 的生成取決於,function, block 放置在哪個地方,變數宣告是用 var (function scope),還是 let, const (block scope)等。
提醒自己的是,在 compilation 並未真正地去執行程式碼,所以 scope, variable 不會佔用到記憶體。想像 compilation 就是在為執行階段預先定義好 scopes (lexical enviroments),還有每一個 scope 的 identifiers (variables)。
也就是說,雖然 scopes 在 compilation 都已經決定好,但在被執行之前 scopes 並未真正地產生。
今天份的學習到這邊