亚洲日本永久一区二区_国产精品k频道网址导航_首页aⅴ色老汉中文字幕_免费深夜全片观看_9久久9毛片又大又硬又粗_国产精品成亚洲电影_日韩不用播放器的av_欧美特色特黄视频

標簽:javascript

JavaScript ( JS ) 是一種具有函數優先的輕量級,解釋型或即時編譯型的編程語言,基于原型編程、多范式的動態腳本語言,并且支持面向對象、命令式和聲明式(如函數式編程)風格。

讀 2020 年 Javascript 趨勢報告展望 ES2020

2021年1月14日,Javascript 2020趨勢調查報告發布了。調查結果來自137個國家的23,765名開發者,涵蓋了開發者對Javascript特性、技術、工具等的使用和想法。下面來一起看看這份報告,并加深對Javascript的認識,在新的一年里提升一個檔次。

十個擁有豐富UI組件的JavaScript開發框架

如今,網上有各種各樣的 JavaScript 框架用來簡化 Web 應用開發。這些框架都提供了一些核心的特性,例如 DOM 操作,動畫,事件處理以及 Ajax 交互,但不是都帶有 UI 組件。今天這篇文章向大家推薦的10個 JavaScript 框架提供了豐富的 Web UI 組件,幫助你構建一致,可靠以及高度交互的漂亮用戶界面。

構建WEB項目的 25 個HTML建議

HTML是WEB應用程序的骨架,盡管非常容易上手,但仍有很多需要注意的規則,可能因為沒有遵循這些規則導致WEB應用程序的實踐受到影響,現在對于項目開發,很多規則是可以通過程序來自動完成,對于初學者還是有必要了解一下。

JavaScript 數組展平方法: flat() 和 flatMap()

作為一門主流的WEB編程語言,JavaScript 不斷發展,添加新的語法、功能或抽象,幫助開發人員輕松解決復雜的問題。如數組展平過去需要自己編寫方法來實現,而從 ES2019 中開始引入了一種扁平化數組的新方法,可以展平任何深度的數組,這個方法就是 flat() 。而說起 flat() 的方法,就不得不順便說下 flatMap()。

JavaScript 中的 .forEach() 和 for...of

.forEach() 方法被認為是 JavaScript 中的高階函數,其工作方式是為列表中的每個元素傳入當前元素、索引和列表(正在循環的整個數組),用更專業的術語來說就是對于迭代器的每次調用,函數都會接收三個參數(元素、索引、列表)調用。

在 JavaScript 中創建私有成員

面向對象編程語言中的 private 關鍵字是一個訪問修飾符,可用于使屬性和方法只能在聲明的類中訪問。這使得隱藏底層邏輯變得容易,這些底層邏輯應該被隱藏起來,并且不應該與類的外部交互。

JavaScript數據結構之Object

Object 定義一組屬性的無序集合,可以將其想象成一張散列表,其中的內容就是一組名/值對,值可以是數據或者函數。 而數組是一個有序集合,為了保證元素排列有序,相比 Object 來說會占用更多的內存空間。

JavaScript數據結構之Number

Number 是JavaScript的基本數據結構,是對應數值的應用類型。要創建一個 Number 對象,就使用 Number 構造函數并傳入一個數值。在 JavaScript 中沒有其他語言這么多的數字類型。

JSON 和JavaScript 介紹與區別

JSON 是 JavaScript Object Notation 的縮寫。 JSON JavaScript 也是如此嗎?不完全是。 JSON 是一種獨立于任何編程語言的數據格式,源自于 JavaScript。大部分現代編程語言都包含可以生成和解析 JSON 數據的方法。

2023 年可以考慮學習的 10 種編程語言

如果職業發展或改變職業的計劃完全要求掌握一門編程語言,可能想知道該學哪一種語言。畢竟,學習這門語言需要時間,所以需要做出正確的選擇,特別對于剛出社會的畢業生。 在做出決定時,應該牢記幾個考慮因素,如愿意解決的難度級別、已經擁有的與現有編碼技能相匹配的編程語言知識,或者學習頂級編程語言的原因。

使用OpenAI ChatGPT 進行了編碼嘗試

ChatGPT 是一種以類似聊天的方式進行交互的人工智能網絡,從名字上看起來像是另一個“聊天機器人”,但實際上已經遠超聊天的范疇了,當要求它編寫一些代碼時,結果相等震撼,它可以寫出一些意想不到的連貫代碼,而這些代碼對于開發者很有啟發。

簡述JavaScript異步函數 async/await

ES7 引入的 async/await 是對 JavaScript 異步編程的一種改進,它提供了使用同步樣式代碼異步訪問資源的選項,而不會阻塞主線程。但是,要很好地使用它有點棘手。在本文中,將從不同的角度探索 async/await,并展示如何正確有效地使用它們。

簡述JavaScript鍵盤事件

JavaScript 中的事件,當用戶或瀏覽器嘗試操作頁面時,就會發生事件來處理 JavaScript 與HTML的交互。正如大家所知,JavaScript 與HTML一起工作,因此,頁面加載、單擊按鈕、最小化窗口、單擊鼠標、敲打鍵盤等發生的一切都是事件。就像在單擊按鈕時向用戶顯示任何消息一樣,這是通過事件發生的。

復習前端:JavaScript V8 引擎機制

V8 是谷歌推出的開源 JavaScript 引擎,它是用 C++ 編寫的,支持 Google Chrome、Chromium 網絡瀏覽器和 NodeJS,它負責與環境交互并生成字節碼來運行程序。 V8 和其他引擎之間最顯著的區別是它的即時 (JIT) 編譯器。

關于 JavaScript 定時器

JavaScript 定時器是實現循環行為甚至觸發延遲操作的好功能。無論有什么基于時間的邏輯,定時器都可以提供支持。在 JavaScript 中有兩個定時器函數:setTimeout 和 setInterval 。接下來看看有哪些定時器以及它們是如何工作的。

理解 GraphQL 類型系統

作為一種為靈活性而設計的 API 技術,GraphQL 是 API 的開發人員和消費者以及他們背后的組織的強大推動者。GraphQL 實現的所有細節和功能都在 GraphQL Schema 中列出。為了編寫一個有效的 GraphQL schema,必須理解好 GraphQL 類型系統。

ES6 如何將 Set 轉化為數組

Set 是 ES6 中新增的一種集合類型,類似于數組,但其成員的值是唯一的,即不會重復。關于Set,可以閱讀《JavaScript中的Set數據操作:交集、差集、交集、對稱差集》。Set 對象是一個構造函數,可以使用 new 關鍵字來創建一個 Set 實例。

JavaScript 對象管家 Proxy

JavaScript 在 ES6 中,引入了一個新的對象類型 Proxy,它可以用來代理另一個對象,并可以在代理過程中攔截、覆蓋和定制對象的操作。Proxy 對象封裝另一個對象并充當中間人,其提供了一個捕捉器函數,可以在代理對象上攔截所有的操作,包括訪問屬性、賦值屬性、函數調用等等。通過攔截這些操作,可以對代理對象進行定制和控制。

1["1","2","3"].map(parseInt)返回值是多少?

返回值是:[1,NaN,NaN]

parseIntmap函數都是常用的函數,可是 ["1", "2", "3"].map(parseInt) 為何返回不是[1,2,3]卻是[1,NaN,NaN]

下面我們先來了解一下parseInt函數的使用方法。

parseInt() 函數

parseInt() 函數解析一個字符串參數,并返回一個指定基數的整數 (數學系統的基礎)。

語法

parseInt(string, radix)

參數 描述
string 必需。要被解析的字符串。
radix

可選。表示要解析的數字的基數。該值介于 2 ~ 36 之間。

如果省略該參數或其值為 0,則數字將以 10 為基礎來解析。如果它以 “0x” 或 “0X” 開頭,將以 16 為基數。

如果該參數小于 2 或者大于 36,則 parseInt() 將返回 NaN

返回值

返回解析后的數字。

說明

當參數 radix 的值為 0,或沒有設置該參數時,parseInt() 會根據 string 來判斷數字的基數。

一下情況返回值為NaN

  • radix 小于 2 或大于 36
  • 第一個非空格字符不能轉換為數字。

 

 

 

1JavaScript 怎么定義可變參數的函數

在 JavaScript 中,可以使用 arguments 對象來實現可變參數。 arguments 是一個類數組對象,包含傳遞給函數的所有參數。可以在函數內部通過訪問 arguments 對象來訪問所有參數。

以下是一個使用 arguments 對象實現可變參數的示例:

function sum() {
    let total = 0;
    for (let i = 0; i < arguments.length; i++) {
        total += arguments[i];
    }
    return total;
}

console.log(sum(1, 2, 3)); // 6
console.log(sum(4, 5, 6, 7)); // 22

在 ES6 中還可以通過擴展運算符來實現可變參數。

function sum(...numbers) {
    let total = 0;
    for (let i = 0; i < numbers.length; i++) {
        total += numbers[i];
    }
    return total;
}

console.log(sum(1, 2, 3)); // 6
console.log(sum(4, 5, 6, 7)); // 22

 

1JavaScript 如何使用 valueOf 方法

在 JavaScript 中,valueOf() 方法是一個可以被對象調用的方法,用于返回該對象的原始值。它可以被所有對象類型(包括自定義對象)調用,并返回一個原始值,例如字符串、數字、布爾值等。

對象

下面是一個示例,展示了在 JavaScript 中對象使用 valueOf() 方法:

let myObj = {
    name: "Quintion",
    age: 30,
    toString() {
        return `${this.name} 年齡 ${this.age}`;
    },
    valueOf() {
        return this.age;
    },
};

console.log(myObj.toString()); // Quintion 年齡 30
console.log(myObj.valueOf()); // 30

數字

在 JavaScript 中的數字是 Number 類型的實例,具有 valueOf() 方法,返回一個數字對象的原始值。

例如,如果有一個數字對象 num,可以使用 valueOf() 方法獲取它的原始值,如下所示:

const num = new Number(42);
console.log(num.valueOf()); // 42

大多數情況下,JavaScript 引擎會自動將數字對象轉換為數字類型,因此通常不需要使用 valueOf() 方法來獲取數字對象的值。例如:

const num = new Number(42);
const result = num + 10;
console.log(result); // 52

字符串

字符串是 String 類型的實例,也具有 valueOf() 方法,返回一個字符串對象的原始值。

例如,如果有一個字符串對象 str,可以使用 valueOf() 方法獲取它的原始值,如下所示:

const str = new String("hello");
console.log(str.valueOf()); // 'hello'

同樣,JavaScript 引擎會自動將字符串對象轉換為字符串類型,因此不需要使用 valueOf() 方法來獲取字符串對象的值。例如:

const str = new String("hello");
const result = str + " world";
console.log(result); // 'hello world'

上面代碼 str 會被自動轉換為字符串類型,因此可以將它與另一個字符串連接起來。

1JavaScript 中 null 和 undefined 的意義是什么?

在JavaScript中,null 和 undefined 都表示無值(no value)的含義,但是它們在具體使用中有一些不同之處:

  1. undefined 表示未定義,即聲明了但未賦值的變量的默認值,或者訪問對象不存在的屬性時返回的值。例如:const x; console.log(x); 輸出 undefined
  2. null 表示空值,即一個變量被明確地賦值為空。例如:const x = null; console.log(x); 輸出null

雖然它們都表示無值,但在某些情況下,它們是不等價的。例如,使用雙等號(==)比較時,null 和 undefined 會被視為相等的值,但在使用嚴格相等運算符(===)比較時,它們是不相等的。同時,在使用 typeof 運算符時,null 會被視為一個對象,而 undefined 會被視為未定義的變量。

總結大概如下:

  • null 是一個賦值。這沒有任何意義。
  • undefined 表示變量已聲明但尚未定義。
  • null是一個對象。undefined 是類型 undefined
  • null !== undefined 但是 null == undefined
1JavaScript 設計模式有哪些?
本系列開始系統性的對 20 多種 JavaScript 設計模式進行簡單概述,然后結合 ES6 類的方式來編寫實例代碼展示其使用方式。

什么是設計模式?

設計模式是軟件設計中常見問題的解決方案,這些模式很容易重復使用并且富有表現力。

在軟件工程中,設計模式(design pattern)是對軟件設計中普遍存在(反復出現)的各種問題,所提出的解決方案。它并不直接用來完成代碼的編寫,而是描述在各種不同情況下,要怎么解決問題的一種方案。面向對象設計模式通常以類別或對象來描述其中的關系和相互作用,但不涉及用來完成應用程序的特定類別或對象。—— 維基百科

有三種模式:創建型模式,結構型模式、行為型模式。

  • 創建型模式:解決與創建對象相關的問題。
  • 結構型模式:處理實體之間的關系,以及它們如何共同組成一個更大的結構。
  • 行為型模式:處理對象如何相互通信和交互。

設計模式系列文章:

1JavaScript 如何實現私有變量?

在 ES6 中,可以使用閉包來模擬私有變量的實現。具體地說,可以使用一個立即執行函數表達式 IIFE 來創建一個函數作用域,在函數作用域內定義私有變量,然后通過返回一個對象,使得外部無法直接訪問私有變量。

例如,以下是一個使用閉包實現私有變量的示例:

const Counter = (() => {
    let count = 0; // 私有變量

    return {
        increment() {
            count++;
            console.log(`count: ${count}`);
        },
        reset() {
            count = 0;
            console.log("count reset");
        },
    };
})();

Counter.increment(); // 輸出 "count: 1"
Counter.increment(); // 輸出 "count: 2"
Counter.reset(); // 輸出 "count reset"

在上述示例中,count 變量是私有的,外部無法直接訪問它,但是可以通過調用返回的對象中的方法來操作它。這里使用了箭頭函數和對象字面量來定義返回的對象,使得代碼更加簡潔。

1JavaScript 如何對 Cookie 進行操作

HTTP Cookie(也叫 Web Cookie 或瀏覽器 Cookie)是服務器發送到用戶瀏覽器并保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶并發送到服務器上。是WEB項目開發需要涉及的內容。

Cookie操作

如果應用程序是完全客戶端 SPA(單頁應用程序),可能不需要 cookie,使用 localStorage 可以解決問題。如果是使用 Next.js 或者 Node.js 提供服務器接口需要身份驗證 Token 的可以考慮使用 cookie

通常認為 cookie 是復數形式,但事實是它們存儲在單個字符串值中,必須對其進行解析才能將它們分解為單獨的鍵/值對

console.log(document.cookie); // _gcl_au=1.1.1660316496.1636468606; _ga=GA1.2.221099298.1636468607; _gid=GA1.2.1474751041.1636468607;

可以通過 ; 拆分字符串來將它們分開,然后映射每個值并使用 = 將其拆分為 ,最終將得到相應的鍵/值對。下面是一個完整的方法集:

const useCookie = (options = { days: 30, path: "/" }) => {
    const { days: expiresDays, path: cookiePath } = options;

    const set = (name, value) => {
        const exp = new Date();
        exp.setTime(exp.getTime() + expiresDays * 24 * 60 * 60 * 1000);
        const strExpires = exp.toGMTString();
        const cookieValue = escape(value);
        document.cookie = `${name}=${cookieValue};expires=${strExpires};path=${cookiePath}`;
    };
    const get = (name) => {
        let arr;
        const reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
        if ((arr = document.cookie.match(reg))) {
            return unescape(arr[2]);
        } else {
            return null;
        }
    };
    // 刪除cookie
    const remove = (name) => {
        document.cookie = name + "=;expires=" + new Date(0).toGMTString();
    };
    // 清除所有 cookie
    const clear = () =>
        document.cookie
            .split(";")
            .forEach(
                (cookie) =>
                    (document.cookie = cookie
                        .replace(/^ +/, "")
                        .replace(
                            /=.*/,
                            `=;expires=${new Date().toUTCString()};path=${cookiePath}}`
                        ))
            );
    /**
     * 獲取所有的 cookie
     * @returns
     */
    const all = () =>
        document.cookie
            .split(";")
            .map((item) => item.split("="))
            .reduce(
                (acc, [k, v]) => (acc[k.trim().replace('"', "")] = v) && acc,
                {}
            );
    return {
        set,
        get,
        clear,
        remove,
        all,
    };
};
const cookieHelper = useCookie();
cookieHelper.set("name", "DevPoint");
cookieHelper.set("city", "Shenzhen");
console.log(cookieHelper.get("name")); // DevPoint
console.log(cookieHelper.all()); // { name: "DevPoint", city: "Shenzhen" }
cookieHelper.remove("name");
console.log(cookieHelper.all()); // { city: "Shenzhen" }

出于安全考慮,某些 cookie 可能被標記為 僅 HTTP ,這意味著此類 cookie 不能從客戶端的 JavaScript 代碼中獲取到。

Cookie 安全主要涉及以下兩個方面:

防止竊取

攻擊者可以通過竊取用戶的 Cookie 來實現會話劫持等攻擊,因此在設置 Cookie 時應當注意以下安全問題:

  • 在服務器端設置 HttpOnly 屬性,防止腳本獲取 Cookie。
  • 使用 secure 屬性,只允許在 HTTPS 連接中傳輸 Cookie。
  • 設置 SameSite 屬性,防止跨站請求偽造攻擊(CSRF)。

防止篡改
攻擊者還可以通過修改 Cookie 的值來實現攻擊,因此在使用 Cookie 時應當注意以下安全問題:

  • 在服務器端對 Cookie 的值進行加密和簽名,防止篡改。
  • 對于關鍵操作,應當在服務端進行校驗,避免因為 Cookie 被篡改而造成安全漏洞。

綜上所述,Cookie 安全需要從多個方面進行考慮和防護。

應用開發一般都少不了身份驗證,而身份驗證機制的穩定性對所有應用程序都變得至關重要。具體選擇何種方式進行身份驗證可以根據項目及團隊情況來衡量,在決定之前需要先理解WEB身份驗證常見的兩種方式:基于 Cookie 的身份驗證和基于令牌(Token)的身份驗證。

1JavaScript 如何將字符串轉為二進制?

以下是一個將字符串轉換為二進制字符串的 JavaScript 函數:

function stringToBinary(string) {
    let binaryString = "";
    for (let i = 0; i < string.length; i++) {
        // 將字符轉換為 Unicode 編碼
        const charCode = string.charCodeAt(i);
        // 將 Unicode 編碼轉換為二進制字符串
        const charBinary = charCode.toString(2);
        // 將二進制字符串補齊 8 位
        const paddedCharBinary = charBinary.padStart(8, "0");
        // 將每個字符的二進制字符串拼接到總的二進制字符串中
        binaryString += paddedCharBinary;
    }
    return binaryString;
}

函數接受一個字符串作為參數,返回一個二進制字符串。通過遍歷字符串中的每個字符,將其轉換為 Unicode 編碼,再將 Unicode 編碼轉換為二進制字符串,最后將每個字符的二進制字符串拼接到總的二進制字符串中。如果一個字符的二進制字符串不足 8 位,函數會在左側用 0 填充,使其成為 8 位二進制字符串。

使用方法如下:

const chineseString = stringToBinary("全棧工匠");
console.log(chineseString); // 101000101101000110100000001000101110111100101101001100100000
const englishString = stringToBinary("hu");
console.log(englishString); // 0110100001110101
1JavaScript 代碼如何實現進制轉換?

JavaScript 可以使用以下代碼實現進制轉換:

1、十進制轉二進制

使用 toString() 方法,將十進制數轉換為二進制字符串,如下:

const decimalToBinary = (decimalNumber) => decimalNumber.toString(2);

console.log(decimalToBinary(11)); // 1011

2、十進制轉八進制

const decimalToOctal = (decimalNumber) => decimalNumber.toString(8);

console.log(decimalToOctal(11)); // 13

3、十進制轉十六進制

const decimalToHex = (decimalNumber) => decimalNumber.toString(16);

console.log(decimalToHex(11)); // b

4、二進制轉十進制

const binaryToDecimal = (binaryString) => parseInt(binaryString, 2);

console.log(binaryToDecimal(1011)); // 11

5、八進制轉十進制

const octalToDecimal = (binaryString) => parseInt(binaryString, 8);

console.log(octalToDecimal(13)); // 11

6、十六進制轉十進制

const hexToDecimal = (binaryString) => parseInt(binaryString, 16);

console.log(hexToDecimal("b")); // 11

7、二進制轉十六進制

const binaryToHex = (binaryString) => {
    const decimalNumber = parseInt(binaryString, 2);
    return decimalNumber.toString(16);
};

console.log(binaryToHex(1011)); // b

8、八進制轉二進制

const octalToBinary = (octalString) => {
    const decimalNumber = parseInt(octalString, 8);
    return decimalNumber.toString(2);
};

console.log(octalToBinary(13)); // 1011

9、十六進制轉二進制

const hexToBinary = (hexString) => {
    const decimalNumber = parseInt(hexString, 16);
    return decimalNumber.toString(2);
};

console.log(hexToBinary("b")); // 1011

10、八進制轉十六進制

const octalToHex = (octalString) => {
    const decimalNumber = parseInt(octalString, 8);
    return decimalNumber.toString(16);
};

console.log(octalToHex(13)); // b

下面將上述代碼封裝成一個類,完整代碼如下:

class NumberConverter {
    static decimalToBinary(decimalNumber) {
        return decimalNumber.toString(2);
    }

    static decimalToOctal(decimalNumber) {
        return decimalNumber.toString(8);
    }

    static decimalToHex(decimalNumber) {
        return decimalNumber.toString(16);
    }

    static binaryToDecimal(binaryString) {
        return parseInt(binaryString, 2);
    }

    static octalToDecimal(octalString) {
        return parseInt(octalString, 8);
    }

    static hexToDecimal(hexString) {
        return parseInt(hexString, 16);
    }

    static binaryToHex(binaryString) {
        const decimalNumber = parseInt(binaryString, 2);
        return decimalNumber.toString(16);
    }

    static octalToBinary(octalString) {
        const decimalNumber = parseInt(octalString, 8);
        return decimalNumber.toString(2);
    }

    static hexToBinary(hexString) {
        const decimalNumber = parseInt(hexString, 16);
        return decimalNumber.toString(2);
    }

    static octalToHex(octalString) {
        const decimalNumber = parseInt(octalString, 8);
        return decimalNumber.toString(16);
    }
}

console.log(NumberConverter.decimalToBinary(11)); // 1011
console.log(NumberConverter.decimalToOctal(11)); // 13
1HTML、CSS、JavaScript、PHP、 MySQL 的學習順序是什么?

關于這個問題,現在應該有新的認知,先回到問題本身,最佳的學習順序應該是:

學習順序

  1. HTML:HTML是構建Web頁面的基礎語言,學習HTML可以熟悉如何創建文本、圖像、鏈接等基本內容,并且組織網頁結構,這是WEB交互的基礎,有了這個基礎才能設計獨特的交互效果。
  2. CSSCSS 是用來美化Web頁面的樣式表語言。通過CSS,可以控制文本、圖像、背景、布局等各個方面的樣式,讓頁面更加美觀和易于閱讀。掌握其基礎,在現代WEB開發中建議不用原生 CSS ,而是使用 LESS、SASS 等,其具有變量、基礎、函數組織能力可以更好的維護項目。
  3. JavaScript:JavaScript 是一種腳本語言,是用來控制Web頁面的交互和動態效果,例如響應用戶操作、驗證表單、創建動畫、處理數據等等。熟練掌握應該是前端開發者應該具備的技能,現代WEB開發中,更多的使用工程化框架來構建,如React、Vue等等。
  4. PHP:PHP是一種服務器端腳本語言,用來處理Web應用程序的數據和邏輯。通過PHP,你可以實現用戶注冊、登錄、發送電子郵件、處理表單數據、連接數據庫等功能。這是過去WEB開發架構中常見的后端服務開發技術,現階段實際上有很多可替代的架構,如Next.js、Node.js、Go等等。
  5. MySQL:MySQL是一種流行的開源關系型數據庫管理系統,用來存儲和管理Web應用程序的數據。學習MySQL可以讓你了解如何創建和管理數據庫、存儲和查詢數據等。

上面提到的應該是過去WEB開發中比較常見技術架構,現在應該有更多的選擇,如 HTML+CSS+JavaScript+Node.js+Mongodb;如果是React,則應該是 HTML+CSS+JavaScript+Next.js+Mongodb

當然不管那種技術架構,HTML+CSS+JavaScript 是基礎,更高階的可以往 HTML+CSS+TypeScript 的方向去。

除了上面的這些技能,對于開發者來說,建議掌握 Docker,過去對于開發者來說,環境的配置通常是比較繁瑣的,就拿PHP來說,配置開發環境需要安裝 Apache、PHP版本,存儲需要安裝 Mysql,如果掌握了 Docker ,環境配置就變得簡單,并且不會污染自己本機的環境。

學習資料推薦

對于HTML和CSS,建議從模仿開始,去閱讀一些開源代碼和比較不錯的HTML模版,從模仿這些模版開始。開始之前可以先看下基礎的東西:

CSS權威指南(第四版)(上下冊):國際公認的HTML、CSS和Web標準領域的專家全新力作。Web視覺呈現技術。全面闡述CSS的實現方式,深入分析全新的CSS規范。

對于JavaScript,就有很多的書籍,下面書籍自己都閱讀學習過了,不多,書籍算是掌握基本功的重要途徑,剩下主要提升就是 GitHub。

JavaScript 指南原書第7版犀牛書:在過去的十年中,Node.js 使得 JavaScript 編程可以在 web 瀏覽器之外進行,Node 的巨大成功意味著 JavaScript 現在也是軟件開發人員最常用的編程語言。無論你是從零開始還是已經開始專業地使用 JavaScript,這本書都會幫助你掌握這門語言。

JavaScript程序設計 第4版 第四版 紅寶石書:第4版涵蓋ECMAScript 2019,全面、深入地介紹了JavaScript開發者必須掌握的前端開發技術,涉及JavaScript的基礎特性和特性 。

數據結構與算法JavaScript描述:用JavaScript描述數據結構與算法的開山之作,匯聚了作者多年的實戰經驗。這本實戰指南通過豐富的示例,向讀者透徹講解了在JavaScript環境下,如何通過一系列存儲機制(包括鏈表、棧、隊列和圖)高效地達到編程目的。

除了閱讀書籍閱讀源代碼外,還可以去刷刷算法題。

JavaScript設計模式與開發實踐:設計模式是軟件設計中經過了大量實際項目驗證的可復用的優 秀解決方案,它有助于程序員寫出可復用和可維護性高的程序。許多優 秀的JavaScript開源框架都運用了不少設計模式,越來越多的程序員從設計模式中獲益,也許是改善了自己編寫的某個軟件,也許是更好地理解了面向對象的編程思想。

學習設計模式的目的是:為了代碼可重用性、讓代碼更容易被他人理解、保證代碼可靠性。 設計模式使代碼編寫真正工程化;設計模式是軟件工程的基石脈絡,如同大廈的結構一樣。

 

1有哪些短小卻令人驚嘆的 JavaScript 代碼?

每天學習10個實用JavaScript代碼片段,加深對 JavaScript 語法的理解,積累代碼優化經驗。

1、FizzBuzz

下面代碼用于實現經典的 FizzBuzz 問題,將1100的數字遍歷,如果是3的倍數則輸出 Fizz ,如果是5的倍數則輸出 Buzz,如果既是3的倍數又是5的倍數則輸出 FizzBuzz

const fizzBuzz = () => {
    for (let i = 1; i <= 100; )
        console.log((i % 3 ? "" : "Fizz") + (i % 5 ? "" : "Buzz") || i), i++;
};
console.log(fizzBuzz());

2、斐波那契數列

斐波那契數列(Fibonacci sequence),又稱黃金分割數列,因數學家萊昂納多·斐波那契(Leonardo Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數列”,指的是這樣一個數列:1、1、2、3、5、8、13、21、34、…… 在數學上,斐波那契數列以如下被以遞推的方法定義:F(0)=1,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*),在現代物理、準晶體結構、化學等領域,斐波那契數列都有直接的應用

斐波那契數列通常是面試常見的問題,下面代碼是用一個非常簡短的遞歸函數,返回斐波那契數列中第n個數字的值。

const fib = (n) => (n <= 2 ? 1 : fib(n - 1) + fib(n - 2));

const createFibNumber = (count = 10) => {
    const arrayFibs = [];
    for (let i = 0; i < count; i++) {
        arrayFibs.push(fib(i));
    }
    return arrayFibs;
};

console.log(createFibNumber(10)); // [ 1, 1,  1,  2,  3, 5, 8, 13, 21, 34 ]

3、快速排序

下面代碼實現了快速排序,通過遞歸將數組分割成較小和較大的兩個子數組,最終將它們合并以獲得排序的結果。

const quickSort = (arrayNums) =>
    arrayNums.length
        ? [
              ...quickSort(arrayNums.slice(1).filter((x) => x <= arrayNums[0])),
              arrayNums[0],
              ...quickSort(arrayNums.slice(1).filter((x) => x > arrayNums[0])),
          ]
        : [];

const arrayNumbers = [1, 3, 5, 6, 2, 4, 11, 30, 100, 40];
console.log(quickSort(arrayNumbers)); // [ 1,  2,  3,  4,   5, 6, 11, 30, 40, 100 ]

4、判斷是否為回文

下面代碼用于判斷一個字符串是否為回文,它將字符串轉換為一個字符數組并翻轉它,然后將它們重新連接起來,并將其與原字符串進行比較。

const isPalindrome = (str) => str == str.split("").reverse().join("");

console.log(isPalindrome("deved")); // true
console.log(isPalindrome("devedev")); // false

5、數組去重

下面代碼用于對一個數組進行去重操作,使用ES6中的Set數據結構,將數組轉換為一個Set,然后再將其轉換為一個數組。

const unique = (arr) => [...new Set(arr)];

const arrayNumbers = [1, 2, 3, 4, 2, 1];
console.log(unique(arrayNumbers)); // [ 1, 2, 3, 4 ]

6、打印九九乘法表

下面代碼可以打印出九九乘法表,它通過兩個嵌套的for循環遍歷每個數字,然后打印出相應的乘法表達式及其結果。

const createNumbers = () => {
    const array = [];
    for (let i = 1; i <= 9; i++)
        for (let j = 1; j <= i; j++)
            array.push(`${j}*${i}=${j * i}${j === i ? "\n" : "  "}`);
    return array.join("");
};
console.log(createNumbers());

輸出結果如下:

1*1=1
1*2=2  2*2=4
1*3=3  2*3=6  3*3=9
1*4=4  2*4=8  3*4=12  4*4=16
1*5=5  2*5=10  3*5=15  4*5=20  5*5=25
1*6=6  2*6=12  3*6=18  4*6=24  5*6=30  6*6=36
1*7=7  2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49
1*8=8  2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64
1*9=9  2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81

7、數組求和

下面代碼用于對一個數組中的數字進行求和,使用 reduce 方法將數組中的所有數字相加起來,并返回最終的結果。

const sum = (arr) => arr.reduce((acc, current) => acc + current, 0);
console.log(sum([1, 3, 5, 7, 9, 10])); // 35

8、獲取URL參數

下面代碼用于從URL中獲取特定的參數值,使用 URLSearchParams API來獲取URL查詢參數,并使用get方法獲取特定的參數值。

const getParam = (url, name) =>
    new URLSearchParams(new URL(url).search).get(name);

console.log(getParam("http://m.46649.cn?name=devpoint", "name")); // devpoint

9、判斷一個數字是否為質數

下面代碼用于判斷一個數字是否為質數,使用一個for循環遍歷2到數字的平方根之間的所有數字,并檢查它們是否可以整除該數字。

const isPrime = (n) => {
    if (n <= 1) return false;
    for (let i = 2; i <= Math.sqrt(n); i++) {
        if (n % i === 0) return false;
    }
    return true;
};
console.log(isPrime(1)); // false
console.log(isPrime(2)); // true
console.log(isPrime(3)); // true

10、數組扁平化

下面代碼用于將一個嵌套的數組扁平化為一個一維數組,使用 reduce 方法遞歸地遍歷嵌套數組,并將其合并為一個新的數組。

const flatten = (arr) =>
    arr.reduce(
        (acc, val) => acc.concat(Array.isArray(val) ? flatten(val) : val),
        []
    );

console.log(flatten([1, [1, 3], [4, 5, 6], [7, [8, [9]]]])); // [ 1, 1, 3, 4, 5, 6, 7, 8, 9 ]

11、階乘

下面代碼用于計算一個數字的階乘,使用遞歸方法,將數字乘以它減一的階乘。

const factorial = (n) => (n < 2 ? 1 : n * factorial(n - 1));
console.log(factorial(4)); // 24

總結

閱讀開源項目是學習提升編碼能力最快捷的方式,當然現在可能可以借助 ChatGPT 來生成一些函數,其生成的函數技巧性也很高。

1JavaScript 怎么截取字符串?

在 JavaScript 中,可以使用 substr()slice()substring() 方法截取字符串。

substring()

substring() 方法返回一個字符串在開始索引到結束索引之間的一個子集,或從開始索引直到字符串的末尾的一個子集。語法如下:

str.substring(indexStart[, indexEnd])

參數說明:

  • indexStart:需要截取的第一個字符的索引,該索引位置的字符作為返回的字符串的首字母。
  • indexEnd:可選。一個 0 到字符串長度之間的整數,以該數字為索引的字符不包含在截取的字符串內。

如果 startIndex 大于 endIndex,則會交換它們的位置。來看一段示例代碼:

let str = "深耕WEB開發10+年,擁有一顆工匠的心";

console.log(str.substring(7)); // 10+年,擁有一顆工匠的心
console.log(str.substring(0, 5)); // 深耕WEB
console.log(str.substring(7, 5)); // 開發
console.log(str.substring(5, 5)); // 空

substr()

substr() 方法返回一個字符串中從指定位置開始到指定字符數的字符。語法如下:

str.substr(start[, length])

第一個參數是截取開始的位置,第二個參數是截取的長度。如下代碼:

let str = "深耕WEB開發10+年,擁有一顆工匠的心";
let result = str.substr(1, 4);
console.log(result); // 耕WEB

上述代碼的 1 表示從第二個字符開始截取,4 表示截取的長度為 4 個字符。

substr() 方法在截取字符串時是基于字符位置的,如果截取長度超過了字符串的長度,它會一直截取到字符串的末尾。如果第一個參數是負數,則從字符串的末尾開始計數。

如果可以的話,建議使用 substring() 來取代 substr()

slice()

slice() 方法提取某個字符串的一部分,并返回一個新的字符串,且不會改動原字符串,與 substring() 方法類似。語法如下:

str.slice(startIndex, endIndex)

其中,startIndex 表示要截取的子字符串的起始位置(包含該位置),endIndex 表示要截取的子字符串的結束位置(不包含該位置)。如果只傳入 startIndex,則會從該位置一直截取到字符串末尾。如果 startIndex 大于 endIndex,則會返回空字符串。例如:

let str = "深耕WEB開發10+年,擁有一顆工匠的心";

console.log(str.slice(7)); // 10+年,擁有一顆工匠的心
console.log(str.slice(0, 5)); // 深耕WEB
console.log(str.slice(7, 5)); // ""
console.log(str.slice(5, 5)); // ""

substring()substr() 的區別

substring()substr() 都是截取字符串的方法,但它們有以下區別:

  1. 參數不同substring() 方法的第一個參數是起始位置,第二個參數是終止位置(不包括該位置的字符);substr() 方法的第一個參數是起始位置,第二個參數是截取的長度。
  2. 負數處理不同substring() 方法不接受負數參數,如果傳入負數,會被自動轉換為0substr() 方法可以接受負數參數,表示倒數計數。
  3. 返回值不同substring() 方法返回從起始位置到終止位置之間的字符;substr()方法返回從起始位置開始指定長度的字符。

ES6中新增了 slice() 方法,但它和 substring() 方法非常相似,也是接受起始位置和終止位置作為參數,不同之處是slice() 方法可以接受負數參數,表示從字符串末尾開始計數。substr() 雖然沒有被完全遺棄,但還是建議使用 substring() 來取代 substr()

1webassembly 能干什么

WebAssembly(縮寫為WASM)是一種二進制格式的代碼,它可以在現代Web瀏覽器中運行。它被設計為一種低級的虛擬機,可以在瀏覽器中運行高性能的程序,可以通過編譯其他語言的代碼來實現。

下面是WebAssembly可以做的一些事情:

  • 前端開發:WebAssembly 可以與JavaScript一起使用,以提高Web應用程序的性能。例如,可以使用WebAssembly編寫一些計算密集型的算法,以替代JavaScript來提高性能。
  • 游戲開發:可以用于在Web瀏覽器中運行游戲。它可以提供比JavaScript更快的運行速度和更好的性能,使得在Web瀏覽器中運行的游戲更加流暢。
  • 跨平臺開發:可以在不同的平臺上運行,包括Web瀏覽器、桌面和移動設備。這使得開發人員可以使用相同的代碼來創建跨平臺應用程序。
  • 數據科學和機器學習:可以用于加速數據科學和機器學習應用程序,使得這些應用程序可以在Web瀏覽器中運行。

除了上述提到的應用場景,WebAssembly還有以下幾個優點:

  • 高性能:WebAssembly代碼可以編譯成原生代碼,因此它可以提供比JavaScript更快的運行速度和更好的性能。這使得它非常適合執行計算密集型的任務,如圖形處理、音視頻處理和機器學習等。
  • 安全性:WebAssembly是一種沙箱化的執行環境,因此它可以提供比JavaScript更高的安全性。它的指令集是基于棧的,而不是基于寄存器的,這使得它更難受到緩沖區溢出等安全漏洞的攻擊。
  • 可移植性:WebAssembly可以在不同的平臺上運行,包括Web瀏覽器、桌面和移動設備。這使得開發人員可以使用相同的代碼來創建跨平臺應用程序,從而減少了開發時間和成本。
  • 擴展性:WebAssembly可以與現有的Web技術(如JavaScript、CSS和HTML)集成使用,從而可以擴展Web應用程序的功能和性能。

WebAssembly 雖然是一門新的技術,但現在有不少區塊鏈項目在使用,用來編寫智能合約,提高智能合約的性能和安全性。

下面是一些使用WebAssembly的區塊鏈項目:

  • EOSIO:EOSIO是一個開源的區塊鏈平臺,可以用于創建高性能的去中心化應用程序。它使用WebAssembly作為其智能合約的執行引擎,從而提高了智能合約的性能和安全性。
  • NEAR Protocol:NEAR Protocol是一個區塊鏈平臺,旨在為開發者提供易于使用、高性能和安全的去中心化應用程序。它使用WebAssembly作為其智能合約的執行引擎,并提供了一些工具和框架來幫助開發者編寫和部署WebAssembly智能合約。
  • Solana:Solana是一個高性能的區塊鏈平臺,可以處理數千個交易,每秒鐘處理數百萬個交易。它使用WebAssembly作為其智能合約的執行引擎,從而實現高性能的智能合約執行。
1Python 和 JavaScript 有什么區別?

從 2022 IEEE 編程語言榜單結果來看,Python 再次摘得桂冠 ,前 10 的排名如下:

  1. Python
  2. C
  3. C++
  4. C#
  5. Java
  6. SQL
  7. JavaScript
  8. R
  9. HTML
  10. TypeScript

python

Python 是一種高級編程語言,由 Guido van Rossum 于 1989 年創造。Python 旨在提供一種簡單、易于閱讀和編寫的語言,同時也具備強大的功能和擴展性,可以用于多種應用程序開發,包括 Web 應用程序、游戲開發、數據分析、科學計算等領域。

Python 具有許多特性,包括:

  • 簡單易學:其語法簡單易懂,容易學習和上手。
  • 可讀性強:采用簡潔的語法和縮進來表示代碼塊,使得代碼易于閱讀和理解。
  • 面向對象:支持面向對象編程,可以定義類和對象,使得代碼組織更加清晰和靈活。
  • 豐富的標準庫:Python 有一個豐富的標準庫,包含了大量的模塊和函數,可以方便地完成各種任務。
  • 跨平臺性:Python 可以在多種操作系統和平臺上運行,包括 Windows、Mac、Linux 等。
  • 強大的第三方庫支持:Python 有大量的第三方庫和框架,可以方便地擴展和增強 Python 的功能。

隨著 ChatGPT 的持續火爆,帶飛了整個 AI 行業,而 Python 在人工智能(AI)領域得到了廣泛的應用和認可。Python 提供了大量的 AI 庫和框架,例如 TensorFlow、PyTorch、Keras、Scikit-learn 等,使得 Python 成為了一個非常流行的人工智能編程語言。

JavaScript

JavaScript 是一種面向對象、動態、弱類型的編程語言,用于在網頁瀏覽器中編寫交互式的前端網頁應用程序。JavaScript 是一種基于原型、事件驅動、函數式編程范式的語言。

JavaScript 最初由 Netscape 公司的 Brendan Eich 在 1995 年創建,用于給網頁增加交互性和動態性。隨著 Web 技術的發展,JavaScript 逐漸成為 Web 前端開發的核心語言之一。

JavaScript 與 HTML 和 CSS 一起構成了 Web 技術的三大基石。JavaScript 通過 DOM(文檔對象模型)和 BOM(瀏覽器對象模型)提供了對網頁內容和瀏覽器功能的訪問和操作,可以實現各種動態效果、交互式操作和數據處理等功能。

隨著 Web 技術的發展,JavaScript 也得到了廣泛的應用和發展。JavaScript 不僅可以用于前端開發,也可以用于后端開發、移動應用開發、桌面應用開發等領域。同時,JavaScript 的生態系統非常豐富,有大量的庫、框架和工具可以用于開發各種應用程序。

JavaScript 在人工智能(AI)領域的應用相對較少,但也有一些相關的應用場景。JavaScript 主要應用于 Web 前端開發,包括網頁應用程序和移動應用程序的開發。在這些應用程序中,JavaScript 主要用于實現交互式操作和數據處理等功能。

隨著 Web 技術的發展和 AI 技術的普及,JavaScript 在 AI 領域的應用也在不斷擴大。一些 AI 庫和框架也提供了 JavaScript 版本,例如 TensorFlow.jsBrain.jsSynaptic.js 等,這些庫和框架可以在網頁瀏覽器中直接運行,方便了 Web 前端開發者使用 AI 技術。

Python VS JavaScript

這里只是簡單的做個比較,有個認識。兩者都是流行的編程語言,但是它們在很多方面也有很大的不同,下面從最基本的知識點出發做個對比。

  • 用途:Python 通常用于后端開發、數據分析、科學計算等領域,而 JavaScript 通常用于前端開發、Web 應用程序、交互式動態效果等領域。
  • 語法:Python 的語法相對簡單,易于學習和閱讀。Python 采用縮進來表示代碼塊,而 JavaScript 則使用花括號來表示代碼塊。
  • 變量:Python 是一種動態類型語言,不需要在代碼中顯式地聲明變量的類型。而 JavaScript 是一種弱類型語言,可以在變量中存儲任何類型的值,也可以在代碼中顯式地聲明變量的類型。
  • 函數:Python 和 JavaScript 的函數都是一等公民,可以作為參數傳遞給其他函數,也可以從函數中返回。但是,Python 中的函數定義需要使用 def 關鍵字,而 JavaScript 中的函數定義可以使用 function 關鍵字或箭頭函數。
  • 模塊:Python 有一個強大的模塊系統,可以方便地組織代碼和共享代碼。JavaScript 也有模塊系統,但是在不同的環境下實現有所不同,例如在瀏覽器中使用 ES6 模塊,而在 Node.js 中主要使用 CommonJS。

總的來說,Python 和 JavaScript 在很多方面都有所不同,但它們都是強大的編程語言,具有廣泛的用途和應用場景。選擇使用哪種語言,取決于具體的需求和項目要求。

1JavaScript 中如何實現一個二叉堆?

在 JavaScript 中,可以通過數組來實現一個二叉堆。二叉堆分為最大堆和最小堆兩種類型,本問將以最大堆為例子。

一個二叉堆可以看做是一顆完全二叉樹,每個節點的值都大于等于其子節點的值(對于最大堆而言)。因此,在使用數組來實現二叉堆時,可以使用數組下標來表示完全二叉樹的節點,并滿足以下規則:

  1. 對于任意節點 i,其左子節點的下標為 2i+1,右子節點的下標為 2i+2
  2. 對于任意節點 i,其父節點的下標為 Math.floor((i-1)/2)

接下來,可以使用數組來實現一個最大堆。具體而言,可以定義一個數組 arr 來保存堆的元素,并定義一些方法來實現堆的常見操作,如插入元素、刪除堆頂元素等。下面是一個簡單的實現示例:

class MaxHeap {
    constructor() {
        this.heap = [];
    }

    // 插入元素
    insert(value) {
        this.heap.push(value);
        this.bubbleUp(this.heap.length - 1);
    }

    // 刪除堆頂元素
    extractMax() {
        const max = this.heap[0];
        const end = this.heap.pop();

        if (this.heap.length > 0) {
            this.heap[0] = end;
            this.sinkDown(0);
        }

        return max;
    }

    // 上浮操作
    bubbleUp(index) {
        const element = this.heap[index];
        while (index > 0) {
            const parentIndex = Math.floor((index - 1) / 2);
            const parent = this.heap[parentIndex];
            if (element <= parent) {
                break;
            }
            this.heap[parentIndex] = element;
            this.heap[index] = parent;
            index = parentIndex;
        }
    }

    // 下沉操作
    sinkDown(index) {
        const left = 2 * index + 1;
        const right = 2 * index + 2;
        let largest = index;

        if (left < this.heap.length && this.heap[left] > this.heap[largest]) {
            largest = left;
        }

        if (right < this.heap.length && this.heap[right] > this.heap[largest]) {
            largest = right;
        }

        if (largest !== index) {
            const temp = this.heap[index];
            this.heap[index] = this.heap[largest];
            this.heap[largest] = temp;
            this.sinkDown(largest);
        }
    }
}

在上述代碼中,MaxHeap 類定義了一個數組 heap 來保存堆的元素,同時實現了 insertextractMaxbubbleUpsinkDown 方法,分別用于插入元素、刪除堆頂元素、上浮操作和下沉操作。

bubbleUp 方法中,使用循環來不斷將新插入的元素上浮,直到滿足堆的條件;sinkDown 方法中,首先找出當前節點的左子節點和右子節點,然后將當前節點與兩個子節點中的最大值進行比較,如果當前節點的值小于最大值,則交換兩個節點的值,并遞歸進行下沉操作,直到滿足堆的條件。

上面定義類的使用方式如下:

const maxHeap = new MaxHeap();

maxHeap.insert(26);
maxHeap.insert(103);
maxHeap.insert(721);
maxHeap.insert(911);
maxHeap.insert(202);

console.log(maxHeap.heap); // [ 911, 721, 103, 26, 202 ]

const max = maxHeap.extractMax();
console.log(max); // 911
console.log(maxHeap.heap); // [ 721, 202, 103, 26 ]

上面代碼首先創建了一個最大堆 maxHeap,插入了一些元素。然后,調用 extractMax 方法來刪除堆頂元素,得到最大值并打印。最后,打印修改后的堆結構,可以看到堆頂的元素已經被刪除并且堆的結構已經滿足最大堆的條件。

 

1怎么在 ECMAScript 6 中定義一個類和對象?

在ES6中,可以使用 class 關鍵字來定義一個類,然后使用 new 關鍵字創建該類的對象。

下面是一個簡單的例子:

// 定義一個Person類
class Person {
    // 構造函數,用于創建Person對象時初始化其屬性
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    // 方法,用于返回Person對象的名字
    getName() {
        return this.name;
    }

    // 方法,用于返回Person對象的年齡
    getAge() {
        return this.age;
    }
}

// 創建一個Person對象
const person = new Person("全棧工匠", 30);

// 調用Person對象的方法
console.log(person.getName()); // 全棧工匠
console.log(person.getAge()); // 30

在上面的例子中,首先使用 class 關鍵字定義了一個 Person 類,該類包含了一個構造函數和兩個方法。然后使用 new 關鍵字創建了一個 Person 對象,并將其賦值給 person 變量。最后,通過調用 person 對象的兩個方法來獲取該對象的名字和年齡。

值得注意的是,在ES6中類是基于原型的,因此類的方法定義在類的原型對象上。另外,ES6中的類也支持繼承,可以通過 extends 關鍵字來創建一個子類,并且可以使用 super 關鍵字來調用父類的構造函數和方法。

對象在JavaScript中是一種非常重要的數據類型,它們有很多有用的方法,在平常項目開發中可以使用這些方法容易地處理對象。關于對象推薦閱讀下面文章

1JavaScript 編程項目中如何使用 this 指針?

JavaScript中的 this 是一個非常重要的概念,它指向當前執行上下文的對象。由于JavaScript是一門動態語言,this 的指向在運行時才能確定,可能會因為調用方式和執行環境的不同而有所變化。

this 的指向可以通過四種調用方式來決定:

  • 作為函數調用時,this 指向全局對象(瀏覽器中為window對象,Node.js中為 global 對象)。
  • 作為方法調用時,this 指向調用該方法的對象。
  • 使用 call()apply() 方法調用時,this指向第一個參數傳入的對象。
  • 使用new關鍵字調用構造函數時,this指向新創建的對象。

除了上述四種方式,還有一些特殊情況需要注意,例如箭頭函數中的 this 指向是定義函數時的上下文,不會隨著調用環境的改變而改變。

總之,JavaScript中的this是一個非常靈活和有用的概念,可以根據不同的調用方式來決定其指向,需要開發者在實際開發中靈活應用。

舉一個具體的例子,假設有一個對象 person,它有兩個方法 sayHellointroduce

const person = {
    name: "Quintion",
    age: 32,
    sayHello() {
        console.log(`Hello, my name is ${this.name}`);
    },
    introduce() {
        console.log(`I'm ${this.age} years old.`);
    },
};

如果以方法調用的方式調用 sayHello()introduce()

person.sayHello(); // Hello, my name is Quintion
person.introduce(); // I'm 32 years old.

此時 this 分別指向 person 對象,因為這兩個方法是在 person 對象中定義的。

如果以函數調用的方式調用 sayHello()introduce()

const sayHello = person.sayHello;
const introduce = person.introduce;

sayHello(); // Hello, my name is undefined
introduce(); // I'm undefined years old.

此時 this 指向全局對象,因為函數調用是在全局上下文中執行的。由于全局對象并沒有 nameage 屬性,所以輸出結果為 undefined

如果將上面的函數使用 call() 方法來調用,如下:

const sayHello = person.sayHello;
const introduce = person.introduce;

sayHello.call(person); // Hello, my name is Quintion
introduce.call(person); // I'm 32 years old.

此時 this 指向 person 對象,因為在 call() 方法的第一個參數中傳入了 person 對象。

需要注意的是,如果在嚴格模式下使用函數調用方式,this 指向的是 undefined,而非全局對象。