Category: Front-End JavaScript

JavsScript一些奇怪的點與我寫得時候會出現的疑問。

  • JS-運算元Operands、運算子Operator、優先性Precedence、相依性Associativity

    參考資料: MDN Web, 六角學院

    運算子優先序(Operator precedence)決定了運算子彼此之間被語法解析的方式,優先序較高的運算子會成為優先序較低運算子的運算元(operands)。

    請給予肝肝的工程師一些支持! 'W'

    <運算式與運算子/條件運算子>

    摘錄:

    條件 (三元) 運算子 是 JS唯一用到三個運算元的運算子:在一個條件後面會跟著一個問號 (?),如果條件是 true,在冒號(:)前的表達式會被執行,如果條件是 false,在冒號後面的表達式會被執行,這個運算子常常被用來當作 if 的簡潔寫法.

    function getSalary(isMember) {
      return (isMember ? '$3600.0' : '$4000.0');
    }
    
    console.log(getSalary(true));
    // expected output: "$3600.0"
    
    console.log(getSalary(false));
    // expected output: "$4000.0"
    
    console.log(getSalarye(null));
    // expected output: "$4000.0"

    3600.0 //運算元

    4000.0 //運算元

    運算子語法結構>>

    condition ? exprIfTrue : exprIfFalse

    參數

    condition
    • 值用來做為條件的表達式
    exprIfTrue
    • 如果 condition = trueexprIfTrue 會被執行
    exprIfFalse
    • 如果 condition =falseexprIfFalse 也會被執行

    <優先性>

    先乘除後加減->>

    var valueA =3*2 + 4*3
    var valueB =4*(3*8)
    console.log(valueA,valueB);
    
    // output: 18,96
    
    console.log(3 + 4 * 5); // 3 + 20
    // output: 23
    
    console.log(4 * 3 ** 2); // 4 * 9
    // output: 36
    
    let a;
    let b;
    
    console.log(a = b = 5);
    // expected output: 5

    相依性-由左邊到右邊判斷>>>

    剛剛我們說到了Javascript 遵從先乘除後加減規格, 但我們仍然試圖找尋這些奇怪的地方。這裡很需要各位的拆解能力。
    console.log(1>2>3);
    console.log(3>2>1);

    不要急, 慢慢想!

    不要這麼輕易的就看答案!

    .

    .

    .

    .

    .

    .

    .

    答案揭曉

    神奇的事情發生了~

    console.log(1>2>3);
    console.log(3>2>1);
    // true 
       false
    3>2  //這裡就會變成true
    true > 1 // 按照通識觀念, 這一定會是false。

    表達式賦予值>>

    Object.defineProperty() 用法參考這!

    • The static method Object.defineProperty() defines a new property directly on an object, or modifies an existing property on an object, and returns the object.
    // 物件
    var b = {};
    
    //宣告物件.屬性
    Object.defineProperty(b,'a',{
    
    value: 2,
    writable:false
    
    });
    
    b.a =3; //賦予值 3
    console.log(b.a);
    
    var a=3;
    
    a=b.a =1; //奇怪的地方喔! 
    
    console.log(a,b.a);
    // Output
       2
       1,2

    b.a =3 賦予值, 但是 Object.defineProperty 屬性內是不可更改 = “writable: false”

    a=b.a =1; //奇怪的地方喔!

    走啊! 回去翻翻 JS表達式的特性 文章, 你將會知道答案。
    // 物件
    var b = {};
    
    //宣告物件.屬性
    Object.defineProperty(b,'a',{
    
    value: 2,
    writable:false
    
    });
    
    b.a =3; //賦予值 3
    console.log(b.a);
    
    var a=3;
    
    a=b.a =1; //奇怪的地方喔! 
    
    console.log(a,b.a);
    // Output
       2
       1,2

    我們再建立另外一個物件.屬性

    Object.defineProperty() 用法參考這!

    var b = {};
    Object.defineProperty(b,'a',{
    value: 2,
    writable:false
    });
    
    Object.defineProperty(b,'d',{
        value: 3,
        writable:false
        });
    
    console.log(b);
    
    var a=3;
    
    a=b.d=b.a =1;// 主要是這個地方需要探討
    
    console.log(a);

    程式執行的結果如下:

  • JS-陳述式Statement、表達式Expression

    這篇其實就是簡單表達的方式, 記住陳述式 vs 表達式這兩著不同即可。

    參考資料: MDN_Web 定義 , [JavaScript] Javascript 的表達式 (Expressions)和陳述式 (Statements):一個用說的,一個用做的

    Statement陳述式

    用於命令執行指定的一系列操作最大的特徵則是不會回傳結果。

    • 宣告(var、function)
    • 流程控制(block、if…else)
    • 迴圈(for、for…in)
    • 其它(import, export)
    • 流程控制 (Control flow):if…else, switch, break
    • 變數宣告 (Declarations): var, let, const
    • 函式宣告與類別 (Functtions and classes):function, async function, return, class
    • 其他:debugger, export, import, label
    var a;
    var b;
    let StudentA;
    let StudentB;
    
    if (StudentA > StudentB) {
    console.log(a);
    
    }else (StudentA < StudentB);{
    console.log(b);
    }
    
    function* generator(i) {
      yield i;
      yield i + 10;
    }
    
    const gen = generator(10);
    
    console.log(gen.next().value);
    // expected output: 10
    
    console.log(gen.next().value);
    // expected output: 20
    

    Expression表達式

    稱作表示式、運算式,經常透過一些符號結合上下語句並運算及回傳結果。白話: 只要你輸入數字進函示, 會判斷、會輸出結果來 = 表達式

    var b =1;
    let mine;
    mine ='我的啦'; //後方有運算子, 即是表達式。
    //具名函式表達式
    var myNameSpace =function getName(x){
    console.log(x); 
    }
    
    //不具名函式表達式
    var getNumSpace =function(x){
    console.log(x); 
    }
    function getSalary(isMember) {
      return (isMember ? '$3600.0' : '$4000.0');
    // 這是Javascript 唯一有的三元判斷式, 也屬於 表達式的一種
    }
  • JavaScript-函式宣告Function Declared、函式表達Function Express以及This的觀念。

    本篇章主要是我自己整理出來的 (大多數是爬了各網站、教學文章)

    我把它當作學習筆記, 如果有也侵害著作權

    請留言或是 E-mail: lioajimzen@gmail.com


    Table of Contents
    資料參考來源: 
    1.你不可不知的 JavaScript 二三事#Day19:函數定義 (Function Definition) 的 100 種寫法
    2.MDN_Web
    3.Fooish_Javascript
    4.JS-ES6箭頭函數
    5.Arrow function expressions
    6.六角學院課程

    <函式的概要/Function Outline>

    函式說的白話…

    一連串邏輯判斷+運算式, 將他們寫成一個 “功能容器”, 每次你要用他們的時候, 呼叫他們即可!

    又或者可以將你定義的眾多“屬性“清單包裝在Function 裡面

    <一般函式定義/Function Define>

    一個函式的定義由一系列的函式”關鍵字”組成, 依次為:

    • 用 function 關鍵字來宣告一個函數
    • 我們指定這個函數的名稱 functionName
    • 包圍在括號()中,並由逗號區隔每一個函式參數。
    • 包圍在大括號{}中,用來定義函式內功能的”物件”,而且這些物件已經給予記憶體空間( 通常拿來建立物屬性件使用 )

    函式_結構 Construct Function>>

    function functionName(parameter1, parameter2, ...) {
        statements
        return value;
    }

    可以不包含參數&不回傳/None Return>>

    若你把 return 陳述式刪除, 當這個function 被呼叫之後經處理的結果若沒有 “受眾” , 結果就會顯示 undefined.

    我的文章有寫關於 undefined 就是這篇。

    無Return 結構:

    function functionName() {
    
    //只有陳述式
        statements 
    }
    
    // 輸出結果 : 
    undefined 

    函式範例>>

    函式名稱: squre

    squre函式裡面的算式= number*2 , 運算完成後會把該值 resultVal 作回傳。

    let resultVal;
    let number; 
    
    function square(number) {
              resultVal=number * number;
      return  resultVal
    }
    
    console.log(square(10));
    -----------------------------------
    // 輸出結果
    100

    <函式回傳/Return Satement >

    參考資料:

    MDN_Web_Return

    英文原文: 
    The return statement ends function execution and specifies a value to be returned to the function caller.

    函式回傳:

    當你呼叫這個函式, 此函式的處理功能…. 接手過來處裡你的資料, 處理完之後把這個處理好的值丟到一個內定記憶體區間或式暫存區, 然後再把這個暫存值丟給”呼叫者”, 此時執行到return 陳述式時也代表此函式已經執行完畢!

    function getRectArea(width, height) {
      if (width > 0 && height > 0) {
        return width * height;
      }
      return 0;
    }
    -----------------------------------
    console.log(getRectArea(3, 4));
    // expected output: 12
    
    console.log(getRectArea(-3, 4));
    // expected output: 0
    

    Return的各種表示法>>

    return;
    return true;
    return false;
    return x;
    return x + y / 3;

    <各種函式的寫法/Various Functions Writing>

    1. 宣告式 (Function Declarations)
    2. 匿名表達式 (Function Expressions w/o Function Name)
    3. 具名表達式 (Function Expressions w/ Function Name)
    4. 建構子式 (Function Constructor)
    5. 箭頭函數 (Arrow Function) – ES6 參考資料

    宣告式 (Function Declarations)>>

    • 最標準的寫法。
    • 使用 function 關鍵字作函數的宣告和定義。
    • 具有 Hoisting 提升效果。
    console.log(myFunc);
    console.log(myFunc(3, 6));
    
    function myFunc(a, b) {
        return a + b;
    }
    -----------------------------------
    // 執行結果
    //function myFunc(a, b) {
        return a + b;
    }
    
    //9

    匿名表達式 (Function Expressions without Function Name)>>

    1. 先宣告一個變數,再定義一個函數內容放到該變數裡。
    2. 此方式定義的函數實際上是匿名函數 (a function without a name),將函數定義的主體,存在你定義的變數裡。
    3. 變數名稱不等於函數名稱。
    4. 不具 Hoisting 提升效果。
    console.log(myFunc);
    
    // console.log(myFunc(3, 6)); // TypeError: myFunc is not a function
    
    let myFunc = function (a, b) {
        return a + b;
    };
    
    console.log(myFunc);
    console.log(myFunc(3, 6));
    -----------------------------------
    //執行結果
    //undefined
    //ƒ (a, b) {
        return a + b;
    }
    //9

    具名表達式 (Function Expressions / Function Name)>>

    1. 和「匿名表達式」相似,差別在定義函數內容時,有給予一個函數名稱 (Function name)。
    2. 定義的函數印出來會有函數名稱(不等於變數名稱)。
    3. 無法直接透過該函數名稱呼叫
    4. 不具 Hoisting 提升效果
    console.log(myFunc);
    // console.log(myFunc(3, 6)); // TypeError: myFunc is not a function
    
    var myFunc = function aaa(a, b) {
        return a + b;
    };
    
    console.log(myFunc);
    console.log(myFunc(3, 6));
    // console.log(aaa); // ReferenceError: aaa is not defined
    -----------------------------------
    //執行結果 
    //undefined
    //ƒ aaa(a, b) {
        return a + b;
    }
    //9

    建構子式 (Function Constructor)>>

    說到建構子我們不得不提 new 這個Keyword,因為提到new 我們就要有個概念: 我們正在建立物件!

    1. 先宣告一個變數,再用 JavaScript 內建的函數建構子 Function() 去定義函數內容,放到該變數裡。
    2. 用 Function() 定義的函數自動被給予函數名稱 anonymous但和「具名表達式」一樣,都無法直接透過該函數名稱呼叫
    3. 不具有 Hoisting 提升效果。
    console.log(myFunc);
    // console.log(myFunc(3, 6)); // TypeError: myFunc is not a function
    
    var myFunc = new Function("a", "b", "return a + b");
    console.log(myFunc);
    console.log(myFunc(3, 6));
    -----------------------------------
    //執行結果 // undefined
    // ƒ anonymous(a,b) {
    return a + b
    }
    //9

    JavaScript 最容易考的的題目, 箭頭函式與一般函式的差別!

    箭頭函式 (Arrow Function)>>

    參考資料: MDN_Web_箭頭函式 , 鐵人賽 (Arrow function) 卡斯柏

    An arrow function expression is a compact alternative to a traditional function expression, but is limited and can’t be used in all situations.

    箭頭函式 有著比一般函式表示法更精簡的表示法, 但箭頭函式並非一體適用….

    箭頭函式也有它的極限啊!

    1. Arrow functions don’t have their own bindings to thisarguments or super, and should not be used as methods.
    2. Arrow functions don’t have access to the new.target keyword.
    3. Arrow functions aren’t suitable for callapply and bind methods, which generally rely on establishing a scope.
    4. Arrow functions cannot be used as constructors.
    5. Arrow functions cannot use yield, within its body.
    1. Arrow functions沒有自己的 this、arguments 或 super 可綁定不應該作為 方法 Method
    2. Arrow functions無權造訪 new.target 關鍵字。
    3. Arrow functions不適用於調用、應用和綁定方法,這些方法通常依賴於建立作用域。
    4. Arrow functions不能用在建立建構子。
    5. Arrow functions不能在函式內使用 yield

    Arrow Functions ES5與ES6的不同之處

    底下範例碼參考: Arrow function js_github

    可省略 function 這個關鍵字 !

    FUNCTION(a){} 將改成 (a) =>{}
    //ES5 版本
    var circle = function(r) {
        var PI = 3.14 ;
        return r*r*PI
    }
    console.log(circle(2)) 
    //執行結果  12.56
    
    
    //ES6 版本
    const circle = (r) => {
        const PI = 3.14 ;
        return r*r*PI
    }
    console.log(circle(2)) 
    
    //執行結果  12.56
    

    Arrow Function基本語法結構

    參數1, 參數2, … , 參數N (含Return )

    (參數1, 參數2, …, 參數N) => { 陳述式; }
    
    (參數1, 參數2, …, 參數N) => 表達式;

    陳述式與表達式

    當只有一個參數時, 可去除括號

    (參數1)=> { statements }
    
    //若無參數,就一定要加括號:
    () => { statements }

    Arrow Function進階語法

    // 用大括號將內容括起來,返回一個物件字面值表示法:
    
    params => ({foo: bar})
    
    // 支援其餘參數與預設參數
    
    (param1, param2, ...rest) => { statements }
    (param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
    statements }
    
    // 也支援 parameter list 的解構
    var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); 
    
    //執行結果 6

    Arrow Function有兩個重要的特性:
    1. 更簡潔的函式寫法
     2. this 變數是全域性的

    //物件內的屬性們
    var elements = [
      'Hydrogen',
      'Helium',
      'Lithium',
      'Beryllium'
    ];
    
    // -----這段函式會輸出[8, 6, 7, 9]這個陣列
    elements.map(function(element) {
      return element.length;
    });
    
    // -----上方一般的函式,可以被改寫成下方的箭頭函式
    elements.map((element) => {
      return element.length;
    }); 
    
    
    //執行結果 [8, 6, 7, 9]
    
    
    // -----如果輸入的參數只有一個,我們可以移除掉外面的括號
    elements.map(element => {
      return element.length;
    }); 
    
    //執行結果 [8, 6, 7, 9]
    
    
    // -----當箭頭函式裡的內容只有'return'的時候,我們刪除return和外面的大括號
    elements.map(element => element.length); 
    
    //執行結果 [8, 6, 7, 9]
    
    
    // -----在這個範例中,因為我們只需要length這個屬性,所以也可以使用解構賦值:
    // -----下方的'length'對應到我們想取得的屬性,而'lengthFooBArX'只是很普通的變數名稱,
    // -----可以被任意修改成你想要的名字
    
    elements.map(({ length: lengthFooBArX }) => lengthFooBArX); 
    
    // [8, 6, 7, 9]
    
    // -----上面解構賦值之後的參數也可以被改寫為下面這樣。但要注意的是,在這個範例中,
    // -----我們不是要指定'length'這個值給一個虛構的屬性,而是這個變數的名稱'length'本身就是
    // -----用來當成我們想從物件上取得的屬性
    
    
    elements.map(({ length }) => length); 
    
    //執行結果 [8, 6, 7, 9]
    

    SetTimeout 箭頭函式結構

    setTimeout(() => {
      // -----100 milliseconds 之後執行
    
    }, 100);

    SetInterval 箭頭函示結構

    setInterval(()=> {
     // -----100 milliseconds 這期間一直處裡。
    
    },100);

    This 與我們分不開>>

    參考資料:

    PjChener_Arrow Function_This, PJCHENder
    那些沒告訴你的小細節this

    解釋 JavaScript 中 this 的值?|ExplainThis

    一般函式內,每個新函式是依據如何被呼叫來定義自己的 this 變數。

    This :一般函式內 結構與功能

    • 建構子時是一個新物件 (這很重要)
    • 在呼叫嚴格模式函數時是 undefined
    • 以物件方法呼叫時則為”基礎物件”

    利用建立物件, 函式帶出數值

    function User() {
        this.name = 'Bob';
    }
    
    function AnotherUser() {
        this.name = 'Hugo';
    }
    
    var user1 = new User();
    var user2 = new AnotherUser();
    
    console.log(user1.name);
    console.log(user2.name);
    
    //顯示結果
    Bob
    Hugo

    This :Arrow Function內 結構功能

    //-----一般函式
    function User() {
    
        this.name = "Bob";
        return this;
    }
    
    console.log(this.name);
    
    //-----箭頭函式
    ()=>{
    this.name ="It is Arrow Functions";
    }
    
    console.log(this.name);
    console.log(typeof this.name);
    
    //顯示結果
    (空物件)
    It is Arrow Functions
    string

    This 提取Arrow Function內部值

    // Arrow function 1
    ()=>{
         this.name ="It is Arrow Functions";
    }
    
    console.log(this.name);
    console.log(typeof this.name);
    
    
    //顯示結果
    //It is Arrow Functions
    //It is Arrow Functions
    //string
    
    • 箭頭函數(Arrow Functions) — this是定義時的對象, 不是在使用的物件。
    • 傳統Function語法 — this是使用、呼叫(call)時的對象。

    用setInterval 將一般函式this 物件p帶出

    function Person() {
      // Person() 建構式將 this 定義為它自己的一個實體
      this.agegrowing = 0;
    
      setInterval(function growingUp() {
        // 在非嚴格模式stric mode下, growUp() 函式把 this 定義為全域物件
        // (因為那是 growingUp()執行的所在),
        // 與 Person() 建構式所定義的 this 有所不同
    
        this.agegrowing++;
      }, 3000);
    }
    
    // 在全域做另一個物件 p
    var p = new Person();
    console.log(p);

    在 ECMAScript 3/5 裡面,this 可透過指派 this 值。

    function Person() {
      var me = this;
                     
      me.age = 0;
    
      setInterval(function growUp() {
        // 這個 callback 參考 `self` 變數,為預期中的物件。
        mee.age++;
      }, 1000);
    }

    透過 bind 函式來綁定 this 變數到指定函式(上面為例,就是 growingUp() 函式)。

    箭頭函式不會擁有自己的 this; 箭頭函式遵循 “常規變量查找規則“。

    當前範圍中搜索不到 this 變量時,他們最終會尋找其作用域。


    Strict Mode 嚴格模式的關係

    參考資料: Arrow function expression

    由於 this 變數具有詞彙上綁定意義,故嚴格模式的宣告對 this 的作用將被忽略。

    Arrow function 沒有自己的this

    // Arrow function 1
    
    ()=>{
         
         this.name ="It is Arrow Functions";
         return this;
    }
    
    console.log(this.name);
    
    
    // Arrow function 2
    var ArrowObject =()=>{
    this.name ="It is ArrowObject Functions";
    
    }
    
    ArrowObject();
    console.log(this.name);
    console.log(typeof this.name);

    This: None Strict Mode

    
    const obj = { // does not create a new scope
      i: 10,
      b: () => console.log(this.i, this),
      c() {
        console.log(this.i, this);
      },
    }
    
    obj.b(); // prints undefined, Window { /* … */ } (or the global object)
    obj.c(); // prints 10, Object { /* … */ }

    This: Strict Mode

    'use strict';
    
    const obj = { // does not create a new scope
      i: 10,
      b: () => console.log(this.i, this),
      c() {
        console.log(this.i, this);
      },
    }
    
    obj.b(); // prints undefined, Window { /* … */ } (or the global object)
    obj.c(); // prints 10, Object { /* … */ }
    

    結語

    有點想不太出來結語要寫甚麼, 光是要弄懂一般函式 vs 箭頭函式 + 蒐集資料就挺累人的

  • JS-Array 、Object literal、Object Constructor/陣列、物件表列、物件創造

    https://www.educba.com/javascript-objects/

    Javascript 本身是不是物件導向, 可以在前幾篇的章節看看, 總話說 Javascript 是一個需要被解釋的語言!

    說到陣列我們會重新提一次資料型態( 型別 ), 當你要提取某個元素的時候, 一定要確定該元素的資料型態與你要應用的資料型態, 對應是否相符合。

    • string
    • number
    • boolean
    • null
    • undefined
    • symbol (ES6 新增)

    除了上述這些以外的”型別”,都是物件。

    參考文章

    給我這個肝肝的工程師一些支持吧! ^v^ 

    <陣列-語法結構>

    我們可以把陣列當作一個容器, 容器裡面會有多種的元素, 這些元素供給開發者提取。
    我們利用日常的”顏色”, “書籍” 來舉個例子:
    • 顏色種類: 紅、綠、藍、灰、黃
    • 書籍種類: CS, VB, JS, Python, SQL
    • 型別: String
    let color =['red', 'green', 'blue','gray','yellow' ];
    
    let book =['CS','VB','JavaScript','Python','SQL'];
    
    console.log(color);
    console.log(book);

    <陣列-不同型別顯示>

    當然, 陣列不管是幾維資料, 都可以混合不同型別使用。
    let array00 =['green',100,false];
    
    let bookprices=[320,400,350,250,400];
    
    console.log(array00);
    console.log(bookprices);

    <陣列-讀取>

    目前學過的語言裡面, 陣列的元素順序都是從0起始。
    let array00 =['green',100,false];
    
    let bookprices=[320,400,350,250,400];
    
    
    console.log(array00[0]);
    console.log(array00[1]);
    console.log(array00[2]);
    
    console.log(bookprices[0]);
    console.log(bookprices[1]);
    console.log(bookprices[2]);

    <陣列-提取變數-賦予其他變數>

    既然你都知道如何提取元素, 那我們來練習如何賦予新變數的流程。
    let array00 =['green',100,false];
    
    let liaolikenumber = array00[1];
    
    console.log(liaolikenumber); 
    //  result = 100

    <陣列-資料長度>

    陣列內元素個數。
    let number =[0,1,2,3,4,5];
    
    console.log(number.length);
    // result =6 

    [陣列內容新增、刪除的處理方法]

    如果有做過通訊處理的工程師應該很清楚…

    再來就是看你該如何辨識一整堆資料裡面, 資料的種類、順序… 再來考慮該如何提取”你要的資料” 或者是該 “寫入哪一些資料” !

    [新增陣列內的資料]

    <陣列-Push>

    • 將元素推到最後一個陣列資料

    —–增加元素——

    push 將元素推到最後一個陣列資料

    unshift 將元素寫入最前面一個陣列

    —–刪除元素——

    pop 刪除資料最後一個陣列

    shift 刪除資料最前面一個陣列

    —–刪除特定元素——

    splice 可以規定範圍做刪除

    let number =[0,1,2,3,4,5];
    
    number.push(6);
    
    console.log(number);

    <陣列-unshift>

    • 將元素寫入最前面一個陣列
    let array01 =['2nd','3rd','4th','5th'];
    
    array01.unshift('1st');
    console.log(array01);

    [刪除陣列內的資料]

    <陣列-pop>

    • 刪除陣列最後一筆資料

    pop是一種陣列方法 / Method

    結構: 陣列名稱.pop()

    let bookname =["CS","VB","JS","Python","SQL"];
    
    bookname.pop();
    
    console.log(bookname);
    

    <陣列-shift>

    let bookname =["CS","VB","JS","Python","SQL"];
    
    bookname.shift();
    console.log(bookname);

    [有範圍規範的刪除方法]

    <陣列-splice>

    當陣列資料多到一種程度時, 想必你也不會想一個一個去刪除吧?

    這樣沒有效率又沒有方法….

    let bookname =["CS","VB","JS","Python","SQL"];
    
    bookname.splice(0,2);
    
    console.log(bookname);

    陣列順利 0~1 受到影響, 其餘沒有!


    [物件概要]

    JavaScript 物件 (object) 是一個複合資料型態 (composite data type),可以儲存不定數量的鍵值對 (key-value paris),而一組鍵值對我們稱做物件的一個屬性 (property)。一個屬性的值 (value) 可以是任何資料型態 (也可以是函數);而屬性的名稱 (key / name) 是一個字串型態。

    <物件創造>

    方法1: 利用new來建立自定義抽象名稱之物件

    物件建構式/Object Constructor

    let makenewobject = new object();

    方法2: 物件實字 /Object literal 

    let makenewobject ={};

    <物件屬性>

    我們拿車子零件的例子來陳述

    車子的組成一定是非常多的零件組成, 這些細部的零件 = 屬性( Attribute )

    眾多屬性名單集結成一個完整的電機總成( 物件 Object)。

    https://www.denso.com/tw/zh/about-us/company-information/dntw/

    底下連結有白話版本的範例:
    https://hugohabor.com/?p=1129

    Car.LightHeader
    Car.AirConditionor
    Car.Compressor
    Car.Alternator
    Car.Starter
    Car.Fuelpump

    我們把物件建置的結構寫給你看, 然後試試看他的“全部清單編號” “單一筆資料編號”

    let LightHeader ="NO1";
    let AirConditionor ="NO2"; 
    let Compressor ="NO3";
    let Alternator ="NO4";
    let Starter ="NO5";
    let Fuelpump ="NO6";    
    
    
    let Car ={
        LightHeader,
    AirConditionor,
    Compressor,
    Alternator,
    Starter,
    Fuelpump,
    };
    
    console.log(Car);
    console.log(Car.AirConditionor);

    總結

    資料集結是一個基本的結構, 你可以用陣列或者是物件陣列來達到。

    但資料歸類又是另一回事, 甚至是資料的後續產生以及資料跳島的問題, 那就真的有得玩了。


  • JS-Callback : 等一會再來叫你

    < 參考相關文章 >

    請給予小肝肝工程師支持喔 'v' ETH/ERC20

    JavaScript Callbacks :

    “I will call back later!”

    A callback is a function passed as an argument to another function

    This technique allows a function to call another function

    A callback function can run after another function has finished

    以上為W3C 裡面所小結的敘述。

    < 你還是說中文吧! >

    W3C所說的….

    A callback is a function passed as an argument to another function.

    callback function 藉由當作函式參數帶入另一個功能陳述式.

    中文翻譯字詞會用“回呼””、”回叫”、”回調”

    我的話都習慣叫 “回扣” ( 疑?

    回扣函式, 通常用於在目前的函式呼叫執行最後移交控制權而不使用函式回傳值的方式。

    直接風格的控制權移交是不明確的,它是用回傳值的方式,然後進行到下一行程式碼或呼叫接下來其他函式。

    前幾篇提到的同步的話要函式甲 > 函式乙 > 函式丙 > 函式丁, 你要等前面做完很麻煩 !

    Callback function 的用途就在於可以讓我們的程式在不論同步或是非同步執行的狀況下都還是可以依照你要的順序執行函式

    < 基本的參數帶入函式 >

    我們這裡用直接風格帶入常數來解釋一下~

    function fruitProcessor(apples, oranges) {
    // 陳述式內的處裡方式  = 算式
     const juice = `Juice with ${apples} apples and ${oranges} oranges.`;
     return juice;
    }
    
    //代入參數
    const appleJuice = fruitProcessor(5, 0);
    
    console.log(appleJuice);
    
    //代入參數
    const appleOrangeJuice = fruitProcessor(2, 4);
    
    console.log(appleOrangeJuice);
    
    

    < 如何處理函式 >

    我們範例的結構:

    1. 處理總函式
    2. 蘋果汁處理函式
    3. 柳橙汁處裡函式
    
    let apples;
    let oranges;
    
    function fruitProcessor(callback)
    {
        callback(apples,oranges);
    }
    
    function fruitAppleJuice (apples,oranges){
        apples= 5;
        oranges =0;
        const juice = `Juice with ${apples} apples and ${oranges} oranges.`;
        console.log(juice);
    }
    
    function fruitOrangeJuice (apples,oranges){
        apples= 2;
        oranges =4;
        const juice = `Juice with ${apples} apples and ${oranges} oranges.`;
        console.log(juice);
    }
    
    fruitProcessor( fruitAppleJuice );
    
    fruitProcessor( fruitOrangeJuice );
    

    將你想要處裡的不同參數輸入不同的函式, 爾後只要呼叫過來做處理即可。


    < Callback簡單函式參數帶入+呼叫>

    let juice;
    
    function fruitProcessor(apples,oranges,callback)
    {
        const juice = `Juice with ${apples} apples and ${oranges} oranges.`;
        callback( juice);
    }
    
    function fruitAppleJuice (callback)
    {    
        console.log(juice);
     }
    
     fruitProcessor(5,1, fruitProcessor);
    
    
    //執行結果
    Juice with 5 apples and 1 oranges.
    

    * 可以自己comment : callback( juice ), 試著自己想想看其中差異!

    < Callback用多函式呼叫_控制執行順序 >

    
    let apples;
    let oranges;
    
    function fruitProcessor(callback)
    {
        callback(apples,oranges);
    }
    
    function fruitAppleJuice (Fn){
    
       apples= 5;
       oranges =0;
       const juice = `Juice with ${apples} apples and ${oranges} oranges.`;
       console.log(juice);
       Fn()
    }
    
    function fruitOrangeJuice (apples,oranges){
        
        apples= 2;
        oranges =4;
        const juice = `Juice with ${apples} apples and ${oranges} oranges.`;
        console.log(juice);
    }
    
    fruitProcessor(fruitAppleJuice(fruitOrangeJuice));

    結論: fruitAppleJuice 去呼叫執行 fruitOrangeJuice

    那你會問…. 既然是A函式去呼叫B函式, 這個有甚麼特別的呢??

    有時候阿~ 我們會遇到延遲以及函式需要等待一段時間後執行, 主函式要是遇到錯誤不執行…. 那就是掛點在那了….

    在本處我就不講解延遲執行這個方法了, 可以回去看一下我寫的 SetTimeout 的文章

    < Callback Settimeout執行時間點 >

    我們在主函式裡, 加入 SetTimeout 方式做控制執行.

    
    let apples;
    let oranges;
    
    function fruitProcessor(callback)
    {
        setTimeout(function(){ 
            console.log("這個是最先還是最後?");
             },0)
    
        callback(apples,oranges);
    }
    
    function fruitAppleJuice (Fn){
       apples= 5;
       oranges =0;
       const juice = `Juice with ${apples} apples and ${oranges} oranges.`;
       console.log(juice);
       Fn()
    }
    
    function fruitOrangeJuice (apples,oranges){
        apples= 2;
        oranges =4;
        const juice = `Juice with ${apples} apples and ${oranges} oranges.`;
        console.log(juice);
    }
    
    fruitProcessor(fruitAppleJuice (fruitOrangeJuice));
    
    
    //執行結果
    
    Juice with5apples and 0 oranges.
    Juice with2apples and 4 oranges.
    這個是最先還是最後?
    

    Settimeout不管延遲時間設定多少,它都會最後一個執行! 

    結論
    這章節最主要是給你知道, callback的執行過程

  • JS-If Else, Else if 條件判斷

    眾多程式語言裡面, If Else 判斷式可說是最基礎的。

    寫法邏輯上是一樣, 每一種語言他們的結構不一樣而已。

    給小肝肝工程師一個支持喔~ 'V'  ETH/ERC20

    <If Else 語法結構>

    圖片來源 : 迷因工程

    老實說, 上述迷因(meme) 已經清楚說道If Else 的運作規則

    接下來我們開始講述If Else 的結構

    < If Else 結構 >

    if  (判斷條件) {
    
      條件成立時,預計要陳述出來的結果。
      
    } else {
    
      條件不成立時,預計要陳述出來的結果。
    }

     <If Else 二分法判斷式>

    範例前導:

    湯尼的錢包內的金額數, 會影響他要去吃牛肉麵還是回家吃飯!

    錢包有81元:
    //錢包有81元
    let wallet =81;
    
    
    //如果錢包內 > 110元
    if(wallet>=110){
    
        console.log("湯尼跑去吃牛肉麵");
    
    } else {
    
    //錢包內的錢不夠, 跑回家去吃媽媽煮的。
        console.log("湯尼錢不夠, 跑回家吃飯了");
    }
    錢包有120元:
    //錢包有120元
    let wallet =120;
    
    
    //如果錢包內 > 110元
    if(wallet>=110){
    
        console.log("湯尼跑去吃牛肉麵");
    
    } else {
    
    //錢包內的錢不夠, 跑回家去吃媽媽煮的。
        console.log("湯尼錢不夠, 跑回家吃飯了");
    }

     <If Else, Eles if 3分法 狀況判斷>

    範例前導:

    湯尼的錢包內的金額數, 會影響他要去吃牛肉麵又或者選擇次要的夜市牛排, 在不行的話就是回家吃飯!

    錢包有85元:
    //錢包有85元
    let wallet =85;
    
    if(wallet>=110){
        console.log("湯尼跑去吃牛肉麵");
    
    } else if(wallet>=80){
    
        console.log("湯尼跑去吃夜市牛排了");
    
    } else {
    
        console.log("湯尼錢不夠, 跑回家吃飯了");
    
    }
    • else if 不管如何都一定會執行
    錢包有75元:
    //錢包有75元
    let wallet =75;
    
    if(wallet>=110){
        console.log("湯尼跑去吃牛肉麵");
    
    } else if(wallet>=80){
    
        console.log("湯尼跑去吃夜市牛排了");
    
    } else {
    
        console.log("湯尼錢不夠, 跑回家吃飯了");
    
    }

    < Else if 多個狀況判斷 >

    < Else if 結構 >

    if  (首要判斷條件) {
    
      首要條件成立時,預計要陳述出來的結果。
    
    else if (判斷條件01) {
    
      條件01成立時,預計要陳述出來的結果。
    }
      
    else if (判斷條件02) {
    
      條件02成立時,預計要陳述出來的結果。
    }
    
    else if (判斷條件03) {
    
      條件03成立時,預計要陳述出來的結果。
    
    }
    
    } else {
    
      首要條件不成立時,預計要陳述出來的結果。
    }

    當你需要判斷很多種的狀態時, 當然就用非常手段了

    ( 拜託, 在公司內不要這樣用黑! )

    範例前導:

    湯尼的錢包內的金額數, 面對眾多選擇時的寫法。

    let wallet =82;
    
    //底下預留給各位自己更改 前置條件。
    
    //console.log(wallet >=120);
    //console.log(wallet >=82);
    //console.log(wallet >=87);
    //console.log(wallet >=92);
    //console.log(wallet >=97);
    //console.log(wallet >=105);
    
    
    if(wallet>=110){
        console.log("湯尼跑去吃牛肉麵");
    
    } else if(wallet>=80){
    
        console.log("湯尼跑去吃夜市牛排了");
    
    } else if(wallet>=85){
    
        console.log("湯尼跑去吃食錦麵")
    
    } else if(wallet>=90){
    
        console.log("湯尼跑去吃牛肉湯麵")
    } else if(wallet>=95){
    
        console.log("湯尼跑去吃美式漢堡肉排飯")
    } else if(wallet>=100){
    
        console.log("湯尼跑去吃豪華泰式料理")
    } else {
    
        console.log("湯尼錢不夠, 跑回家吃飯了");
    
    }

    結語

    基礎的底打好, 腦袋才會有程式語言的“共感”

    這種共感可以讓你了解其他的程式語言。

    不過最後的title 所提到的眾多狀況判斷, 拜託去業界不要這樣寫! 千萬不要這樣寫喔!

    若你想要知道更好的寫法, 之後我會來提提看決策樹。

  • JS-同步(Sync)與非同步(Async)-SetTimeout-SetInterval

    JS-執行緒與同步(Sync)非同步(Async)概念 這一篇有概述了同步(Sync)與非同步(Async)。

    所以我們得把以前學得執行堆疊概念拿出來套用一下

    接下來要繼續說明一下, 同步(Sync)與非同步(Async)的應用

    [2022_11_02 新增SetInterval ]

    參考資料: 六角學院

    參考連結: 
    談談JavaScript SetTimeout/SetInterval

    給予小肝肝工程師支持吧'v': ETH/ERC20

    JavaScript

    SetTimeout() 用法

    在講解執行順序之前, 我們會先說明事件佇列

    在你執行到SetTimeout()所在的Function, 內部的陳述式會儲存到事件佇列

    先記起來!

    SetTimeout()方法1

    1. SetTimeout() 的delaytime單位(ms)
    2. SetTimeout() 要整個程式順序跑完以後才會執行
    3. SetTimeout() 只執行一次就會結束!
    4. SetTimeout( 非字串,delaytime ) 用這種方式, 主控台的執行效率會比較好

    SetTimeout()方法2

    不同在於

    SetTimeout( 字串,delaytime) 裡面陳述, 我們用純字串

    這種方式在主控台的執行效率較不好


    執行順序

    執行結果

    SetInterval 用法

    setInterval() 固定延遲了某段時間之後,才去執行對應的程式碼,然後「不斷循環」

    SetInterval 結構

  • JS-執行緒與同步(Sync)與非同步(Async)概念

    在Javascript世界裡面, 它仍然是依照同步的概念去執行程式

    意思就是Javascript單執行續(Single-Thread) 的語言

    請給予肝肝的小工程師支持吧 'v': ETH/ERC20

    甚麼是同步? 甚麼是非同步?

    同步

    同步⌟這一詞, 懵懂的我剛開始以為是Multi-thread, 或者因為中文翻譯而將意思誤解為同時進行

    *Multi-thread 之後我會在寫一篇來說說

    簡單來說就是把事情編排好順序, 藉由一些方式讓它按照你編排的順序去執行

    每次只做一件事情, 這才叫做 ⌜同步⌟。

    ⌜非同步

    ⌜非同步⌟的字面意思就很好了解

    指派任務的可以多個母線開頭, 做完這件事情, 你還能再去做其他的被指派任務

    同步(Sync)

    每天當你起床之後, 你腦袋一定會想等下要先刷牙、煮咖啡、吃早餐。

    但是你只能烤完吐司, 再來煮咖啡, 咖啡煮完再來刷你的牙。

    這樣不是很麻煩嘛! 還要屈就之前的任務?

    同步

    非同步(Async)

    但是我不想要做完A再來做B再來做C… 很浪費時間!

    所以我們利用下圖流程來解釋非同步

    1. 要刷牙之前, 我們將吐司烤爐啟動
    2. 再將咖啡機啟動
    3. 然後自己跑去刷牙
    4. 刷牙的同時, 機器仍然運作中
    5. 刷完牙, 吐司烤好,咖啡也煮好了!
    非同步

    結語

    同步非同步的概念先建構好, 之後會用單一篇章來說說SetTimeout、Callback、AJAX 

  • JS-Not Defined VS undefined 還有Null

    當看完JS-提升之後, 為了加深記憶體區塊”空的”概念, 我們來探討一下

    下方有一篇原文網站GeeksforGeeks, 內容講述此現象:

    https://www.geeksforgeeks.org/javascript-referenceerror-variable-is-not-defined/

    給予肝肝的工程師小額捐款'V': ETH/ERC20
    0xd20c50c82450ee288711bf5e3f9238bc816c168a

    主要區分以下

    • Not Defined
    • Undefined

    <Not Defined >

    // let a;  
    console.log(a);
    console.log(typeof a);
    

    解釋:

    當你的記憶體區塊 let a , 並沒有宣告時

    你的瀏覽器將抓不到”a”

    這就是所謂的: Not Defined

    <Undefined >

    let b;
    console.log(b);

    解釋:

    當你的記憶體區塊 let b 存在時

    你的瀏覽器將抓到的是這個 記憶體區塊

    但是你並沒有賦予值

    所以只會有: Undefined

    *那你會想問… null 的特性怎麼跟undefined那麼像??

    <Null > 空值

    一般我們在VB.Net、C#JAVA 這些程式語言裡面…

    VB.Net :

    Dim C As Interger = 32

    C#:

    Int C =32; 

    JAVA:

    Int C =32;

    你會發現, 以上語言都必須先“宣告型態”,也就是我們本文章所講的記憶體區塊.

    後面按照需求, 賦予該記憶體區塊一個.

    但是 Javascript不一樣, Javascript本身是一種需要被解釋的語言, 而且不用宣告型態就可以直接賦予值

    let a ;
    a=1;
    c=null;
    d=11;
    
    console.log(a);
    console.log(c);
    console.log(d);

    解釋

    你會發現… c 被賦予 null(空值), 通常這個變數內有值時, 就可以用這個方式清空.

    d 沒有記憶體區塊, 卻照樣可以直接被賦予值

    為求謹慎, 我們來看看 c、d 的Type 是甚麼好了

    let a ;
    a=1;
    c=null;
    d=11;
    
    console.log(a);
    console.log(c);
    console.log(d);
    console.log(typeof c);
    console.log(typeof d);

    解釋

    c 的型態為object (物件)

    d 單純就是變量

    結語

    看似很簡單, 講起來卻很繞口…

    藉由探討 Javascript語言特性記憶體區塊 對後續優化網站有很大的幫助.

    希望這樣看到文章的Programmer 能夠有所幫助喔!

  • JS-Hoisting提升

    想必這個是踏入JavaScript第一個大魔王吧!? (疑

    首先我們要提2個階段:

    • 創造階段
    • 執行
    給予肝肝的工程師小額捐款'v' ETH/ERC20
    0xd20c50c82450ee288711bf5e3f9238bc816c168a

    參考資料: 六角學院

    範例1:  
    function callname(){
        console.log('Jen');
        //Jen 這個callname() 裡面的內容已經被完整的創造
    }
    
    callname();
    範例2:  
    callname();
    
    function callname(){
        console.log('Jen');
        //Jen 這個callname() 裡面的內容已經被完整的創造
    }

    範例1~2的輸出結果

    解釋:

    Function 函式會優先被創造( 提升 )

    內容陳述式也是! *不包含記憶體區塊

    你會發現, 函式內容為”字串” 陳述式

    下一段改成”變數內容”, 會怎麼樣呢??

    變數_內容

    範例3
    //創造階段
    function callname(){
        console.log(Jen);
        //Jen沒有創造階段, 沒有記憶體空間, 也沒有執行
    }
    
    //執行
    callname();

    範例3的輸出結果

    我們將範例3 ,var變數進行創造 “記憶體區塊”

    //創造階段
    var  Jen 
    function callname(){
        console.log(Jen);
        //Jen 在創造階段已經有記憶體區塊
    }
    
    //執行
    callname();

    解釋:

    對於var 創造, 會將var 宣告的動作宣稱 “提升”

    會發現僅僅是沒在 記憶體區間內 給予 “數值”

    好啦! 給予Jen 一個數值之後

    範例4
    //創造階段
    var  Jen =1;
    
    ///創造階段
    function callname(){
        console.log(Jen);
        
    }
    
    //執行階段 此時才會把 Jen= 1 賦予值
    callname();

    解釋:

    第一行 var Jen =1; 將記憶體區間宣告出來 = “提升”

    要到了callname() 執行階段, var Jen 才會被賦予 = 1

    我把第一行 var Jen=1

    移動到Function 後方檢驗看看??

    範例5
    function callname(){
        console.log(Jen);
        
    }
    
    var Jen=1;
    callname();

    Funtion 之後, var Jen=1 執行創造階段 (提升)

    再來從執行階段>> callname() 將賦予值給 Jen

    一樣按照 :

    • 創造階段
    • 執行

    結語

    • Function & 內部陳述式, 優先Hoisting /提升
    • var 宣告記憶體區間 Hoisting /提升

    這只是第一階段的提升觀念
    畢竟先了解創造>>執行的順序, 之後把各種觀念加進去, 對於往後對JS的深度語法有很大的幫助喔!