前端訓練營第三週

表達式、類型轉換

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
  • 2.2 Reference 引用
    delete
    assign

  • 2.3 Expressions

    • call
      foo()
      super()
      foo()[‘b’] member優先級降低
      foo().b
      foo()abc
  • 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
  • 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))

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章