Open zuppachu opened 5 years ago
例一:
console.log(b)
var b = 10
可以「想像」成這樣的跑法,但不是真的:
var b
console.log(b)
b = 10 // 賦值不會提升,但是宣告會。
兩個得到結果一樣 - undefined
例二:
test()
function test() {
console.log(123)
}
想像跑法如下,函式整個提昇~
funciton test() {
console.log(123)
}
test()
兩個得到結果一樣 - 123
例三:
var test = function(){
console.log(123)
}
test()
你以為會跑成這樣
test()
var test = function(){
console.log(123)
}
// 得 test is not a function
但其實是如下跑法,可將其分為兩步驟: 一個是賦值,一個是宣告。
var test
test()
test = function() {
console.log(123)
}
// test 是 undefined。賦值不會提升,宣告會提升。
上述的表現即是「提升」~
function 佔有優先權。(function 比宣告變數來得高)
fucntion test(){
console.log(a)
function a() {
}
var a = 'local'
}
test()
看成這樣:
fucntion test(){
function a() {
// var a 不重要了,因為這邊已經有 a 了
}
console.log(a)
a = 'local'
}
test()
function test(a) {
console.log(a)
}
test(123)
// 得 123
function test(a) {
console.log(a)
var a = 456
}
test(123)
// 得 123。值不會被改變,因為 a 本來就有值了
function test(a) {
console.log(a)
function a() {
}
}
test(123)
// 得 function a
function test() {
var a
console.log(a)
}
test()
// 得 undefined,因為預設的值就是 undefined。
function test() {
var a = 'test'
var a //這邊會被忽略,因為他只代表我要宣告一個變數 a
var a
console.log(a)
}
test()
// 得 test
小結,提升的順序?
- function
- arguments 參數
- var
那hosting 跑程式碼的順序?
function test(a) {
console.log(a)
var a = 456
console.log(a)
}
test(123)
// 得 123 , 得 456
先解題~題目如下: [圖片出自鋰學院 - JS201]
var a = 1;
function test(){
console.log('1.', a);
var a = 7;
console.log('2.', a);
a++;
var a; //有跟沒有是一樣的,並不會變成 undefiend
inner();
console.log('4.', a);
function inner(){
console.log('3.', a);
a = 30;
b = 200;
}
}
test();
console.log('5.', a);
a = 70;
console.log('6.', a);
console.log('7.', b);
解題:
- undefined => 因為 hoisting
- 7
- 8 => 因為 inner() 裡面沒有 a,只有被賦值 30,所以必須往上找 test() 裡面最後一個 a = 8 (a++)
- 30 => 因為 inner() 裡面的 a 最後被賦值 30
- 1
- 70
- 200 => b = 200 會被渲成全域變數
原理:
VO: {
a: 123,
b: function,
c: undefined
}
function test(a,b) {
function b() {}
var c = 30
}
test(123)
var a = 1;
function test(){
console.log('1.', a);
var a = 7;
console.log('2.', a);
a++;
var a; //有跟沒有是一樣的,並不會變成 undefiend
inner();
console.log('4.', a);
function inner(){
console.log('3.', a);
a = 30;
b = 200;
}
}
test();
console.log('5.', a);
a = 70;
console.log('6.', a);
console.log('7.', b);
執行真正原理如下!
--- step 3 ---
test EC
test VO {
}
---- step 1 進去 EC 的時候,step 2 之後進行程式碼 ---
global EC
global VO {
test: func,
a: undefined => 變成 1
// 1. 找參數 2. 找 func 的宣告 3. 變數的宣告
}
沒看很懂 QQ
閉包 跟 scope chain 有深深關係~
// ES5
function Dog(name) {
this.name = name
}
Dog.prototype.getName = function() {
return this.name
}
Dog.prototype.sayHello = function() {
console.log(this.name)
}
var d = new Dog('abc')
d.sayHello()
var b = new Dog('123')
b.sayHello()
//ES6
Class Dog {
constructor(name) {
this.name = nam
}
getName() {
return this.name
}
sayHello() {
console.log(this.name)
}
}
var d = new Dog('abc')
d.sayHello()
var b = new Dog('123')
b.sayHello()
為什麼要改變? 因為 ES5 的方法每次都要從新弄一個 function ,這樣太沒效率了。。
// ES5
function Dog(name) {
this.name = name
}
Dog.prototype.getName = function() {
return this.name
}
Dog.prototype.sayHello = function() {
console.log(this.name)
}
var d = new Dog('abc')
console.log(d.__proto__ === Dog.prototype)
// true
尋找 d.sayHello() 會執行的方式:
(以下為原型鍊)
d.proto = Dog.prototype d.proto.proto = object.prototype Dog.prototype.proto = object.prototype
class Dog {
constructor(name) {
this.name = name
}
sayHello() {
console.log(this.name)
}
}
class BlackDog extends Dog { //extends 繼承
constructor() {
super() // = Dog.constructor
this.sayHello()
}
test() {
console.log('test', this.name)
}
}
const d = new BlackDog('hello')
什麼時候使用? 共同的屬性時,例如:名字、種類... etc
七種資料型態
primitive types 原始型態 (immuable 不能改變)
其他的都是屬於
用來測驗為哪種屬性,可用 ?
typeof 其中最為知名的 bug 是 typeof null === object 但是不能更改,因為牽一髮動全身
console.log(Array.isArry([])) typeof 無法測 array,可改用上面寫法