Skip to content

Latest commit

 

History

History
323 lines (273 loc) · 7.53 KB

File metadata and controls

323 lines (273 loc) · 7.53 KB

運算子、型別與文法(1)

陳述式與表達式

https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Expressions_and_Operators

Statement 陳述式:

Javascript 的語句類型,用於命令執行指定的一系列操作
最大特徵則是不會回傳結果

Expression 表達式:

又可稱為表示式、運算式
經常透過一些符號結合上下語句並運算及回傳結果

所以表達式會回傳結果
陳述式不會回傳結果,不能賦值在其他變數上面

// 函式陳述式,具名函式
function callName() {
}

// 函式表達式,匿名函式
var callName = function () {
}

上面hoist 結果會不一樣

// block語句(函式陳述式)
{
    const ming = '小明';
}
// const 只有在block語句內才有作用

// 物件實字(函式表達式)
var a = {
    ming: '小明'
}

ASI 自動插入分號

ASI: 當 js 語句沒有加入分號時,則會受到自動插入分號(ASI規則影響)

function callName() {
    return 
    '叫我小明';
}
console.log(callName()); // undefined

因為return 其實後方自動加上分號,變成下面

function callName() {
    return;
    '叫我小明';
}
console.log(callName()); // undefined

所以正確寫法為以下

function callName() {
    return '叫我小明';
}
console.log(callName()); // 叫我小明

立即函式介紹

http://www.victsao.com/blog/81-javascript/287-javascript-function-iife

ASI 補充說明

https://www.udemy.com/course/javascript-adv/learn/lecture/15793656#questions

動態型別

js 是動態型別

記住!!執行階段才會賦予建立型別

typeof可以檢查型別

var name; // hoist,創造階段準備一個空間
name = '小明'; // 賦於給小明

console.log(typeof name); // string

js 有分為顯性轉換和隱性轉換

顯性轉換(Explicit conversion)

就是變數的值直接被賦於另一個值

var num = 1;
console.log(typeof num);
num = '文字';
console.log(typeof num);

隱性轉換(Implicit conversion),要懂 js 的規則!!

運算子就是很好的例子

var num = 1;
console.log(num, typeof num); // 1 "number"
num = num + '';
console.log(num, typeof num); // 1 string

num = num * 3;
console.log(num, typeof num); // 3 "number"

原始型別與物件型別

小技巧: 記原始型別有7種,其他就是物件型別

原始型別7種
String 字串
Number 數值
Boolean 布林
Null 空
Undefined 未定義
=========前面5個比較主要===========
Symbol (new) Symbol (new)
BigInt (new) 整數數值 (new )

原始型別都有方法
會有額外的包裹物件,去取得型別的方法,例如string有大小寫或者算出長度...等

!!!只有null 、undefined 是沒有包裹物件

new Boolean()
new String()
new Number()
Symbol()
BigInt()
原始型別要注意兩點
1.d = null;  雖然印出為 obj 物件型別,但因為官方無法修正會導致一些錯誤...等,所以這邊是原始型別
2.console.log(typeof e); // 這邊沒有宣告 e 主要是 js 的保護機制,不出現 not defined,所以才會印出 undefind
var a,
    b,
    c,
    d;

a = 1;
a = '文字';
b = true;
c = {};
d = null; // 記住!! 雖然印出為obj 物件型別,但因為官方無法修正會導致一些錯誤...等,
// 所以這邊是原始型別
console.log(typeof e); // 這邊沒有宣告e 主要是js的保護機制,所以才會印出undefind

若是要查詢原始型別查詢有哪些方法可以用,就必須用包裹型別

a = 'ming';
console.log(a.length);
console.log(a.toLocaleUpperCase());
var e = new String(a);
console.log(a, e); // e 展開會有個_proto_  js 的方法都在裡面

注意!!! 宣告原始型別不要透過var e = new String(a); 因為這個是建構式,所以變成物件型別,通常

用來查詢此原始型別有哪些方法可以用

運算子

介紹一元(ex: typeof...等) 二元(幾乎都是) 三元(條件) 運算子
https://www.udemy.com/course/javascript-adv/learn/lecture/15307534#questions

優先性及相依性

查看運算子優先性與相依性 ex: +*... 等
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

Precedence 優先性

決定運算子彼此之間被語法解析的方式
優先序較高的運算子會成為優先序較低運算子的運算元

Associativity 相依性

相依性決定運算方向

var a = 2 * 2 + 2 * 3;
console.log(a); // 10

因為*優先性+在優先性 =

console.log(1<2<3) // true
console.log(3>2>1) // false

解析出來

3>2 = true
true > 1  true會轉型成number 1 所以1>1 就變成false
var a = 1;
var b = 2;
a = b = 3;
console.log(a, b);// 3 3

一開始我們會誤以為,但觀念是錯誤的

b = 3; // 觀念錯誤
a = b; // 觀念錯誤

重要!!!!!!! 正確來說, 3 賦於給 b 的 "回傳結果"

因為表達式會回傳結果

var b = {};
Object.defineProperty(b, 'a', {
    value: 2,
    writable: false //無法覆寫
});

b.a = 5;
console.log(b.a); // 2

考題1

var a = 3;
a = b.a = 1;
console.log(a, b.a); // 1 2

因為b.a = 1 是表達式回傳結果是1,因為跟b.a沒有關係
所以a = 1;

考題2

Object.defineProperty(b, 'b', {
    value: 3,
    writable: false //無法覆寫
});

var a = 3;
a = b.b = b.a = 1;
console.log(a); // 1

解析

a = b.b = 1;

記住!!! 只要掌握表達式的觀念,就不會被陷阱題唬住!!!!!!

寬鬆相等、嚴格相等以及隱含轉型

嚴格相等(===): 型別和值都要ㄧ樣

有特別情況,須注意

1.console.log( NaN === NaN ); // false
NaN 表示不是數值,所以兩個比對為 false

2.console.log( +0 === -0 ); //true

寬鬆相等(==): 會透過轉換,才去比對

影片有許多考題可以練習!!!
https://www.udemy.com/course/javascript-adv/learn/lecture/15307538#questions

console.log(1 == '1'); // true

記住!!!! 將布林、字串轉為數值 Number()

解析

Number('1') = 1;
console.log(1 == Number('1'));

延伸考題1

console.log(17 == '0x11'); // true
Number('0x11') // 16 + 1

延伸考題2

console.log( true == 'true' ); // false
Number('true') // NaN
1 == NaN 就是 false

許多考題在影片

null undefined 不會轉換數字型別

小技巧: null == undefind 記住在寬鬆相等兩者是ㄧ樣,嚴格相等是不一樣,其他判斷就直覺比對就可以了

ex: console.log(null == 0); // false

物件與非物件,使用包裹物件轉換

console.log([10]);
console.log(10 == [10]); // true

因為陣列是用包裹物件的Number([10]) 做轉換 等於10

console.log('A' == ['A']); // string

因為陣列是用包裹物件的String(['A']) 做轉換 等於'A'

console.log(String({A: 'A'})); // [object Object]
console.log('[object Object]' == {A: 'A'}); // true

物件與物件,主要是參考位置不一樣

console.log([] == []); // false
console.log({} == {}); // false

這邊後面物件會有更詳細介紹,這邊規則需要背下來

整理:
非物件與非物件比對,string and boolean 會根據Number()轉數值
null == undefined 但 === 會不一樣 ,且不會根據Number()轉數值
非物件與物件比對,物件會根據包裹物件轉換
物件與物件比對,會根據參考位置不同,所以[]==[] 為false {}=={} 為false