JavaScript_原型_作用域?qū)W習(xí)筆記

JavaScript原型 & 原型鏈
構(gòu)造函數(shù)(大寫字母開頭的普通函數(shù))
function Person() {}
const person = new Person()
person.name = 'idea'
console.log(person.name) ?// idea
// 返回 true
console.log(person.constructor === Person)
console.log(person.__proto__ === Person.prototype)
console.log(Person.prototype.constructor === Person)
console.log(person.__proto__.constructor === Person)
console.log(Object.getPrototypeOf(person) == Person.prototype)
console.log(Object.getPrototypeOf(person) == person.__proto__) ?
console.log('對(duì)象', Object.prototype) //對(duì)象 [Object: null prototype] {}
console.log('對(duì)象', Object.__proto__) //對(duì)象 {}
Person.prototype.age = 18
const person1 = new Person()
const person2 = new Person()
console.log(person1.age, person2.age) ?// ?18 18
函數(shù)Person的prototype屬性指向的是一個(gè)對(duì)象 person1 person2 , new Person() 創(chuàng)建實(shí)例的原型里
實(shí)例上找不到屬性,去原型上找, person.__proto__
或則Person.prototype
,原型查找不到會(huì)向原型的原型查找,直到查找到Object
繼承: JavaScript 只是在兩個(gè)對(duì)象之間創(chuàng)建一個(gè)關(guān)聯(lián),這樣,一個(gè)對(duì)象就可以通過(guò)委托訪問(wèn)另一個(gè)對(duì)象的屬性和函數(shù),所以與其叫繼承,委托的說(shuō)法反而更準(zhǔn)確些。
作用域
指程序源代碼中定義變量的區(qū)域
JS作用域:靜態(tài)作用域
靜態(tài)作用域、詞法作用域:函數(shù)的作用域基于函數(shù)創(chuàng)建的位置。
動(dòng)態(tài)作用域:函數(shù)在調(diào)用時(shí)確定的
var value = 1
function foo() {
?console.log(value)
}
function bar() {
?var value = 2
?foo()
}
bar()
// 返回 1
var scope = 'global Scope'
function CheckScope() {
?var scope = 'local Scope'
?function f() {
? ?return scope
?}
?return f()
}
CheckScope()
、作用域鏈?zhǔn)窃诤瘮?shù)定義的時(shí)候創(chuàng)建的。嵌套的函數(shù) f() 定義在這個(gè)作用域鏈里,其中的變量 scope 一定是局部變量,不管何時(shí)何地執(zhí)行函數(shù) f(),這種綁定在執(zhí)行 f() 時(shí)依然有效。
bash采用動(dòng)態(tài)作用域
value=1
function foo () {
? ?echo $value;
}
function bar () {
? ?local value=2;
? ?foo;
}
bar
執(zhí)行上下文
execution context
var fn = function () {
?console.log('fn1')
}
fn() // fn1
var fn = function () {
?console.log('fn2')
}
fn() // fn2
function foo() {
?console.log('foo1')
}
foo()
function foo() {
?console.log('foo2')
}
foo()
// 輸出兩個(gè) ‘foo2’
只有function
函數(shù)可以在聲明之前調(diào)用
console.log(add2(1, 1)) //輸出2
function add2(a, b) {
?return a + b
}
console.log(add1(1, 1)) //報(bào)錯(cuò):add1 is not a function
var add1 = function (a, b) {
?return a + b
}
// 用函數(shù)語(yǔ)句創(chuàng)建的函數(shù)add2,函數(shù)名稱和函數(shù)體均被提前,在聲明它之前就使用它。
// 但是使用var表達(dá)式定義函數(shù)add1,只有變量聲明提前了,變量初始化代碼仍然在原來(lái)的位置,沒法提前執(zhí)行。
可執(zhí)行代碼
executable code:
全局代碼
函數(shù)代碼
eval
執(zhí)行上下文棧
execution context stack ESC
棧:FILO,先進(jìn)后出
變量對(duì)象
可執(zhí)行代碼 創(chuàng)建 ----> 執(zhí)行上下文
執(zhí)行上下文的三個(gè)核心屬性
變量對(duì)象 variable object VO
作用域鏈 scope chain
this
變量對(duì)象:存儲(chǔ)上下文中定義的變量和函數(shù)的聲明????global
????function
全局上下文:
this ----> 全局對(duì)象 (瀏覽器中指的是window對(duì)象),指向作用域鏈的頭部
函數(shù)上下文
activiaction object AO ???????? 活動(dòng)對(duì)象 ===????變量對(duì)象
執(zhí)行代碼
進(jìn)入執(zhí)行上下文環(huán)境 分析
代碼執(zhí)行 執(zhí)行
作用域鏈
找VO,先在當(dāng)前上下文找,找父級(jí)上下文的VO,直到找到全局變量????this window,沿著上下文找 VO 的過(guò)程鏈,就是作用域鏈