表達式、類型轉換
1、Float轉爲bit
- 1.1 64位浮點數默認隱藏了一個1.(十進制不可能以0開始,二進制只有0,1,不以0開頭,必然是1,所以隱藏了一個1)。
符號位 + 指數部分 + 小數部分 - 1.2 正0和負0
num/0 — Infinity(-Infinity)
2、Express 表達式
-
2.1 運算符優先級 優先級
表達式生成樹- Member 屬性訪問
a.b
a[b]
foostring
super.b — 構造函數中
super[‘b’]
new.target
new Foo()
function foo(){ console.log(new.target); } new foo()
- new
new Foo
- Member 屬性訪問
-
2.2 Reference 引用
delete
assign -
2.3 Expressions
- call
foo()
super()
foo()[‘b’] member優先級降低
foo().b
foo()abc
- call
-
2.4 Left Handside & Right Handside (LeftHandSideExpression:ECMA-262.pdf 201 頁 12.3)
a.b = c
等號坐邊要求是Reference- update (UpdateExpression:ECMA-262.pdf 178 頁 11.9.1)
a++
a–
–a
++a
- update (UpdateExpression:ECMA-262.pdf 178 頁 11.9.1)
-
2.5 Unary 單目運算符
delete a.b
void foo() void 0; void後面跟任何值都行。
typeof a null
+a
-a
~a
!a ! 做類型轉換
await乘法 * / %
加法 + -
位運算 << >>
比較 < > <= >= instanceof in
Logical 邏輯 || &&
三目
2種加法 number類型 string類型
1種乘法 number類型 -
2.6 裝箱 Number String Object Symbol
Object.getPrototypeof(Object(Symbol(“1”))) == Symbol.prototype -
2.7 拆箱
1+{}
1+{valueOf(){return 2}}
1+{toString(){return 2}}
1+{valueOf(){return 2},toString(){return 2}} 先valueOf
1+{Symbol.toPrimitive{return {}},valueOf(){return 2},toString(){return 2}} 先toPrimitive ECMA-54頁new Date().toJSON() ECMA-464頁
-
2.7 練習
stringToNumber
進制問題
科學計數法問題NumberToString
用戶權限高於前端代碼的權限。
語句、對象
1、簡單語句
ExpressionStatement 表達式語句
EmptyStatement
DebuggerStatement
ThrowStatement
ContinueStatement
BreakStatement
ReturnStatement
2、複合語句
BlockStatement
Iteration
while
do…while
for
for…in
for…of
標籤、循環、break、continue
LabelledStatement
IterationStatement
ContinueStatement
BreakStatement
SwitchStatement
[[type]]: break continue
[[value]]:–
[[target]] : label
try…catch…finally
[[type]]: return
[[value]]:–
[[target]] : label
3、聲明語句
FunctionDeclaration 函數聲明
GeneratorDeclaration
AsyncFunctionDeclaration
AsyncGeneratorDeclaration
VariableStatement 變量 717頁
ClassDeclaration
LexicalDeclaration
Generator跟異步編程沒有關係
Runtime
- Completion Record 完成記錄 語句完成的結果
[[type]]: normal break continue return throw
[[value]]:Types 7種類型,也可能是empty
[[target]] : label - Lexical Enviorment
4、JS對象類型
唯一性、標識性、行爲
class base 基於類
分類&&歸類
Prototype
eg: 狗咬人 – 行爲改變狀態
Object in JS
key — value
[[value]] get
writable set
enumerable enumerable
configurable configurable
Object API
{} . [] Object.defineProperty
Object.create Object.setPrototypeOf Object.getPrototypeOf
new class extends
new function prototype
特殊對象
function Object
使用new的對象用class實現。
按照 ECMAScript 標準,一些特定語句(statement) 必須以分號結尾。分號代表這段語句的終止。但是有時候爲了方便,這些分號是有可以省略的。這種情況下解釋器會自己判斷語句該在哪裏終止。這種行爲被叫做 “自動插入分號”,簡稱 ASI (Automatic Semicolon Insertion) 。實際上分號並沒有真的被插入,這只是個便於解釋的形象說法。
var 最好寫在函數內最前面或變量第一次出現的地方
/**
作業就做了一個
* 將數字的字符串形式轉爲Number類型
* @param {*} string 數字的字符串表示
* @param {*} x 進制(二進制、8進制、十進制、16進制)
*
* 0b
* 0
* 0x
*
* 這裏不考慮進制的前綴
*/
function convertStringToNumber(string, x) {
string = string.toLowerCase();//全部轉爲小寫
if (x === 16) {//十六進制
return hexadecimal(string)
}
return notHexadecimal(string, x) //2 8 10 進制
}
/**
* 科學計數法
* @param {*} string
*/
function scientificCounting(string) {
let chars = string.split('e'); //科學計數法被分爲2部分
let jishu = notHexadecimal(chars[0], 10);//基數部分
console.log(chars[1][0]);
let zhishu = 0;
if (chars[1][0] === '+') {
zhishu = index(chars[1].replace(chars[1][0], ''), '+')
} else if (chars[1][0] === '-') {
zhishu = index(chars[1].replace(chars[1][0], ''), '-')
} else {
zhishu = index(chars[1], '+')
}
console.log(zhishu);
return jishu*zhishu
}
/**
* 科學計數法的指數部分
* @param {*} num
* @param {*} type
*/
function index(num, type) {
let len = notHexadecimal(num);//指數部分 轉成10進制
let number = 1;
for (let i = 0; i < len; i++) {
if (type === '+') {
number *= 10
} else {
number /= 10
}
}
return number
}
/**
* 十六進制的轉換
* @param {*} string
*/
function hexadecimal(string) {
if (!/^[0123456789abcdef]*$/.test(string)) return NaN
let chars = string.split('');
let charNumber = {
a: '10',
b: '11',
c: '12',
d: '13',
e: '14',
f: '15'
}
let number = 0;
let i = 0;
// console.log('chars',chars);
while (i < chars.length && chars[i] !== '.') {
number = number * 16;
if (charNumber[chars[i]]) {
chars[i] = charNumber[chars[i]]
}
// console.log(chars[i]);
number += notHexadecimal(chars[i], 10)
i++
}
if (chars[i] === '.') {
i++
}
let fraction = 1;
while (i < chars.length) {
fraction = fraction / 16;
if (charNumber[chars[i]]) {
chars[i] = charNumber[chars[i]]
}
number += notHexadecimal(chars[i], 10)
i++
}
return number;
}
/**
* 2 8 10 進制的轉換
* @param {*} string
* @param {*} x 默認10進制
*/
function notHexadecimal(string, x = 10) {
if (x === 2) {
if (!/^[01]*$/.test(string)) return NaN
}
if (x === 8) {
if (!/^[01234567]*$/.test(string)) return NaN
}
if (x === 10) {
let isScientificCounting = string.match(/e/g);
//有一個字母e 不能再開頭和結尾
if (isScientificCounting && isScientificCounting.length === 1 && string[0] !== 'e' && string[string.length - 1] !== 'e') {
return scientificCounting(string)
}
if (!/^[0123456789]*$/.test(string)) return NaN;
}
let chars = string.split('');
let number = 0;
let i = 0;
while (i < chars.length && chars[i] !== '.') {
number = number * x;
number += chars[i].codePointAt(0) - '0'.codePointAt(0)
i++
}
if (chars[i] === '.') {
i++
}
let fraction = 1;
while (i < chars.length) {
fraction = fraction / x;
number += (chars[i].codePointAt(0) - '0'.codePointAt(0)) * fraction
i++
}
return number;
}
// console.log(convertStringToNumber('050',10)); //50
// console.log(convertStringToNumber('050')); // 50
// console.log(convertStringToNumber('010',2)); //2
// console.log(convertStringToNumber('020',2)); // NaN
// console.log(convertStringToNumber('010',8)); //8
// console.log(convertStringToNumber('090',8)); // NaN
// console.log(convertStringToNumber('010',16)) //16
// console.log(convertStringToNumber('011',16)) //17
// console.log(convertStringToNumber('00a',16)) //10
// console.log(convertStringToNumber('00b',16)) //11
// console.log(convertStringToNumber('00c',16)) //12
// console.log(convertStringToNumber('00d',16)) //13
// console.log(convertStringToNumber('00e',16)) // 14
// console.log(convertStringToNumber('00f',16)) //15
// console.log(convertStringToNumber('01A',16)) //26
// console.log(convertStringToNumber('0ab',16)) //171
// console.log(convertStringToNumber('12e5', 10)) //1200000
// console.log(convertStringToNumber('12e+5', 10))//1200000
console.log(convertStringToNumber('12e-5', 10))