主頁 > 企業開發 > Dreamweaver基礎教程:學習JavaScript

Dreamweaver基礎教程:學習JavaScript

2021-06-21 06:18:57 企業開發

目錄
  • 簡介
  • 用法
  • 輸出
  • 語法
    • 字面量
    • 變數
    • 運算子
    • 陳述句
    • 關鍵字
    • 注釋
    • 資料型別
    • 函式
      • 函式運算式
      • Function() 建構式
      • 自呼叫函式
      • 箭頭函式
      • arguments 物件
      • 使用建構式呼叫函式
      • 作為函式方法呼叫函式
      • 閉包
  • 物件
    • 物件定義
    • 物件屬性
    • 物件方法
  • 作用域
    • 區域作用域
    • 全域變數
    • 變數生命周期
    • HTML 中的全域變數
  • 事件
    • HTML 事件
    • 常見的HTML事件
  • typeof, null, 和 undefined
    • typeof 運算子
    • null
    • undefined
    • undefined 和 null 的區別
  • 型別轉換
    • 資料型別
    • typeof 運算子
    • constructor 屬性
  • JavaScript 型別轉換
  • 正則運算式
    • 語法
    • 使用字串方法
    • 使用 RegExp 物件
  • 表單
    • 表單驗證
  • this 的多種指向:
  • let 和 const
    • let關鍵字
      • 塊級作用域(Block Scope)
      • 重新定義變數
      • 使用全域變數
      • 重置變數
    • const 關鍵字
      • 重置變數
  • JSON
    • 語法規則
    • JSON 字串和 JavaScript 物件互轉
  • void(0) 含義
  • 包含了一個位置資訊,默認的錨是#top 也就是網頁的上端,
  • 異步編程
    • 異步的概念
    • 什么時候用異步編程
    • 回呼函式
    • 異步 AJAX
  • Promise
    • 構造 Promise
    • Promise 的使用
    • Promise 函式
    • 異步函式

簡介

直接寫入 HTML 輸出流:

document.write("<h1>這是一個標題</h1>");
document.write("<p>這是一個段落,</p>");

注:只能在 HTML 輸出中使用 document.write,如果在檔案加載后使用該方法,會覆寫整個檔案
對事件的反應:

<button type="button" onclick="alert('歡迎!')">點我!</button>

注:alert() 函式對于代碼測驗非常方便,onclick 事件只是眾多事件之一,

改變 HTML 內容:

x=document.getElementById("demo");  //查找元素
x.innerHTML="Hello JavaScript";    //改變內容

注:document.getElementById("some id")這個方法是 HTML DOM 中定義的,DOM (Document Object Model)(檔案物件模型)是用于訪問 HTML 元素的正式 W3C 標準,

改變 HTML 影像:
動態地改變 HTML <image> 的來源(src):

<script>
function changeImage()
{
    var s = document.getElementById('myimage');
    s.src = https://www.cnblogs.com/timefiles/p/s.src.match('bulboff')?"/images/pic_bulbon.gif":"/images/pic_bulboff.gif";
}
</script>
<img loading="lazy" id="myimage" onclick="changeImage()" src="https://img.uj5u.com/2021/06/21/245585210618321.gif" width="100" height="180">

改變 HTML 樣式:

x=document.getElementById("demo")  //找到元素 
x.style.color="#ff0000";           //改變樣式

驗證輸入:

if isNaN(x) { alert("不是數字"); }

用法

標簽:在 HTML 頁面中插入 JavaScript,請使用 <script> 標簽
外部的 JavaScript:外部檔案通常包含被多個網頁使用的代碼,檔案擴展名是 .js,請在 <script> 標簽的 "src" 屬性中設定該 .js 檔案

可以在 HTML 檔案中放入不限數量的腳本,腳本可位于 HTML 的 <body> 或 <head> 部分中,或者同時存在于兩個部分中
通常的做法是把函式放入 部分中,或者放在頁面底部,

輸出

JavaScript 可以通過不同的方式來輸出資料:

  • 使用 window.alert() 彈出警告框,
  • 使用 document.write() 方法將內容寫到 HTML 檔案中,
  • 使用 innerHTML 寫入到 HTML 元素,
  • 使用 console.log() 寫入到瀏覽器的控制臺,

語法

JavaScript 是一個腳本語言,輕量級,但功能強大的編程語言,

字面量

在編程語言中,一般固定值稱為字面量,如 3.14,

  • 數字(Number)字面量 可以是整數或者是小數,或者是科學計數(e),如 123e5 ,
  • 字串(String)字面量 可以使用單引號或雙引號:
"John Doe"
'John Doe'
  • 運算式字面量 用于計算,如5 + 6 、5 * 10 ,

  • 陣列(Array)字面量 定義一個陣列:

 [40, 100, 1, 5, 25, 10] ,
  • 物件(Object)字面量 定義一個物件:
{firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}
  • 函式(Function)字面量 定義一個函式:
function myFunction(a, b) { return a * b;}

變數

JavaScript 使用關鍵字 var 來定義變數, 使用等號來為變數賦值:

var x, length;
x = 5;
length = 6;

注:變數是一個名稱,字面量是一個值,變數通常是可變的,字面量是一個恒定的值,

運算子

JavaScript語言有多種型別的運算子:

型別 實體 描述
賦值,算術和位運算子 = + - * / 在 JS 運算子中描述
條件,比較及邏輯運算子 == != < > 在 JS 比較運算子中描述

陳述句

在 HTML 中,JavaScript 陳述句向瀏覽器發出的命令,陳述句是用分號分隔:

x = 5 + 6;
y = x * 10;

關鍵字

JavaScript 關鍵字用于標識要執行的操作,和其他任何編程語言一樣,JavaScript 保留了一些關鍵字為自己所用,
注:基本上,編程通用的關鍵字盡量不要使用即可

注釋

不是所有的 JavaScript 陳述句都是"命令",注釋后的內容將會被瀏覽器忽略
單行注釋以 // 開頭,多行注釋以 /* 開始,以 */ 結尾,

資料型別

JavaScript 有多種資料型別:數字,字串,陣列,物件等等:

var length = 16;                                  // Number 通過數字字面量賦值
var points = x * 10;                              // Number 通過運算式字面量賦值
var lastName = "Johnson";                         // String 通過字串字面量賦值
var cars = ["Saab", "Volvo", "BMW"];              // Array  通過陣列字面量賦值
var person = {firstName:"John", lastName:"Doe"};  // Object 通過物件字面量賦值

函式

JavaScript 陳述句可以寫在函式內,函式可以重復參考,參考一個函式 = 呼叫函式(執行函式內的陳述句):

function myFunction(a, b) {
    return a * b;                                // 回傳 a 乘以 b 的結果
}

注:JavaScript 對大小寫是敏感的,使用 Unicode 字符集

函式運算式

JavaScript 函式可以通過一個運算式定義:

var x = function (a, b) {return a * b};
var z = x(4, 3);

以上函式實際上是一個 匿名函式 (函式沒有名稱),函式存盤在變數中,不需要函式名稱,通常通過變數名來呼叫

Function() 建構式

函式可以通過內置的 JavaScript 函式構造器(Function())定義:

var myFunction = new Function("a", "b", "return a * b");
var x = myFunction(4, 3);

注:在 JavaScript 中,需要避免使用 new 關鍵字,建議使用函式運算式替換函式構造器(Function())

自呼叫函式

函式運算式可以 "自呼叫",自呼叫運算式會自動呼叫,如果運算式后面緊跟 () ,則會自動呼叫:

(function () {
    var x = "Hello!!";      // 我將呼叫自己
})();

箭頭函式

箭頭函式運算式的語法比普通函式運算式更簡潔:

(引數1, 引數2, …, 引數N) => { 函式宣告 }

(引數1, 引數2, …, 引數N) => 運算式(單一)
// 相當于:(引數1, 引數2, …, 引數N) =>{ return 運算式; }

(單一引數) => {函式宣告}
單一引數 => {函式宣告}

() => {函式宣告}
// ES5
var x = function(x, y) {
     return x * y;
}
 
// ES6
const x = (x, y) => x * y;

注:當使用箭頭函式的時候,箭頭函式會默認系結外層 this 的值,所以在箭頭函式中 this 的值和外層的 this 是一樣的,

arguments 物件

JavaScript 函式有個內置的物件 arguments 物件,argument 物件包含了函式呼叫的引數陣列
創建一個函式用來統計所有數值的和:

x = sumAll(1, 123, 500, 115, 44, 88);
 
function sumAll() {
    var i, sum = 0;
    for (i = 0; i < arguments.length; i++) {
        sum += arguments[i];
    }
    return sum;
}

使用建構式呼叫函式

如果函式呼叫前使用了 new 關鍵字, 則是呼叫了建構式:

// 建構式:
function myFunction(arg1, arg2) {
    this.firstName = arg1;
    this.lastName  = arg2;
}
 
// This    creates a new object
var x = new myFunction("John","Doe");
x.firstName;                             // 回傳 "John"

注:建構式中 this 關鍵字沒有任何的值,this 的值在函式呼叫實體化物件(new object)時創建,

作為函式方法呼叫函式

在 JavaScript 中, 函式是物件,有它的屬性和方法,

call() 和 apply() 是預定義的函式方法, 兩個方法可用于呼叫函式,兩個方法的第一個引數必須是物件本身

function myFunction(a, b) {
    return a * b;
}
myObject = myFunction.call(myObject, 10, 2);     // 回傳 20

myArray = [10, 2];
myObject = myFunction.apply(myObject, myArray);  // 回傳 20

call() 和 apply()兩者的區別在于第二個引數: apply傳入的是一個引數陣列,也就是將多個引陣列合成為一個陣列傳入,而call則作為call的引數傳入(從第二個引數開始),

注:通過 call() 或 apply() 方法可以設定 this 的值, 且作為已存在物件的新方法呼叫,

閉包

參考函式自我呼叫:

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();
 
add();
add();
add();
 
// 計數器為 3

變數 add 指定了函式自我呼叫的回傳字值,自我呼叫函式只執行一次,設定計數器為 0,并回傳函式運算式,

add變數可以作為一個函式使用,它可以訪問函式上一層作用域的計數器,這個叫作 JavaScript 閉包

它使得函式擁有私有變數變成可能,計數器受匿名函式的作用域保護,只能通過 add 方法修改,

注:閉包是一種保護私有變數的機制,在函式執行時形成私有的作用域,保護里面的私有變數不受外界干擾,形成一個不銷毀的堆疊環境

物件

JavaScript 物件是擁有屬性和方法的資料,

物件定義

定義和創建 JavaScript 物件:

var person = {
    //屬性
    firstName: "John",
    lastName : "Doe",
    id : 5566,
    //方法
    fullName : function() 
	{
       return this.firstName + " " + this.lastName;
    }

物件屬性

可以說 "JavaScript 物件是變數的容器",或者說"JavaScript 物件是鍵值對的容器",
鍵值對通常寫法為 name : value (鍵與值以冒號分割),鍵值對在 JavaScript 物件通常稱為 物件屬性

可以通過兩種方式訪問物件屬性:

//方法1
person.lastName;
//方法2
person["lastName"];

物件方法

物件的方法定義了一個函式,并作為物件的屬性存盤
物件方法通過添加 () 呼叫 (作為一個函式):

name = person.fullName();

如果把函式當成屬性訪問(不添加()),它將作為一個定義函式的字串回傳:

name = person.fullName;

作用域

在 JavaScript 中, 作用域為可訪問變數,物件,函式的集合,

區域作用域

變數在函式內宣告,變數為區域作用域,只能在函式內部訪問:

// 此處不能呼叫 carName 變數
function myFunction() {
    var carName = "Volvo";
    // 函式內可呼叫 carName 變數
}

不同的函式可以使用相同名稱的變數,區域變數在函式開始執行時創建,函式執行完后區域變數會自動銷毀
注:函式引數只在函式內起作用,是區域變數

全局變數

變數在函式外定義,即為全域變數,全域變數有全域作用域—— 網頁中所有腳本和函式均可使用

var carName = " Volvo";
 
// 此處可呼叫 carName 變數
function myFunction() {
    // 函式內可呼叫 carName 變數
} 

如果變數在函式內沒有宣告(沒有使用 var 關鍵字),該變數為全域變數

// 此處可呼叫 carName 變數
 
function myFunction() {
    carName = "Volvo";
    // 此處可呼叫 carName 變數
}

變數生命周期

JavaScript 變數生命周期在它宣告時初始化,區域變數在函式執行完畢后銷毀,全域變數在頁面關閉后銷毀

HTML 中的全域變數

在 HTML 中, 全域變數是 window 物件:所有資料變數都屬于 window 物件,

//此處可使用 window.carName
 
function myFunction() {
    carName = "Volvo";
}

事件

HTML 事件是發生在 HTML 元素上的事情, JavaScript 可以觸發這些事件,

HTML 事件

HTML 事件可以是瀏覽器行為,也可以是用戶行為,以下是 HTML 事件的實體:

  • HTML 頁面完成加載
  • HTML input 欄位改變時
  • HTML 按鈕被點擊

HTML 元素中可以添加事件屬性,使用 JavaScript 代碼來添加 HTML 元素:

<!-- 單引號 -->
<some-HTML-element some-event='JavaScript 代碼'>

<!-- 雙引號 -->
<some-HTML-element some-event="JavaScript 代碼">

常見的HTML事件

下面是一些常見的HTML事件的串列:

事件 描述
onchange HTML 元素改變
onclick 用戶點擊 HTML 元素
onmouseover 用戶在一個HTML元素上移動滑鼠
onmouseout 用戶從一個HTML元素上移開滑鼠
onkeydown 用戶按下鍵盤按鍵
onload 瀏覽器已完成頁面的加載

更多事件串列: JavaScript 參考手冊 - HTML DOM 事件

typeof, null, 和 undefined

typeof 運算子

可以使用 typeof 運算子來檢測變數的資料型別

typeof "John"                // 回傳 string
typeof 3.14                  // 回傳 number
typeof false                 // 回傳 boolean
typeof [1,2,3,4]             // 回傳 object
typeof {name:'John', age:34} // 回傳 object

*注:在JavaScript中,陣列是一種特殊的物件型別,因此 typeof [1,2,3,4] 回傳 object, *

null

null是一個只有一個值的特殊型別,表示一個空物件參考(用 typeof 檢測 null 回傳是object),可以設定為 null 來清空物件:

var person = null;           // 值為 null(空), 但型別為物件

也可以設定為 undefined 來清空物件:

var person = undefined;     // 值為 undefined, 型別為 undefined

undefined

在 JavaScript 中, undefined 是一個沒有設定值的變數,typeof 一個沒有值的變數會回傳 undefined

var person;                  // 值為 undefined(空), 型別是undefined

任何變數都可以通過設定值為 undefined 來清空, 型別為 undefined:

person = undefined;          // 值為 undefined, 型別是undefined

undefined 和 null 的區別

null 和 undefined 的值相等,但型別不等:

typeof undefined             // undefined
typeof null                  // object
null === undefined           // false
null == undefined            // true

型別轉換

資料型別

在 JavaScript 中有 6 種不同的資料型別:

  • string
  • number
  • boolean
  • object
  • function
  • symbol

3 種物件型別:

  • Object
  • Date
  • Array

2 個不包含任何值的資料型別:

  • null
  • undefined

typeof 運算子

可以使用 typeof 運算子來查看 JavaScript 變數的資料型別:

typeof "John"                 // 回傳 string
typeof 3.14                   // 回傳 number
typeof NaN                    // 回傳 number
typeof false                  // 回傳 boolean
typeof [1,2,3,4]              // 回傳 object
typeof {name:'John', age:34}  // 回傳 object
typeof new Date()             // 回傳 object
typeof function () {}         // 回傳 function
typeof myCar                  // 回傳 undefined (如果 myCar 沒有宣告)
typeof null                   // 回傳 object

constructor 屬性

constructor 屬性回傳所有 JavaScript 變數的建構式:

"John".constructor                 // 回傳函式 String()  { [native code] }
(3.14).constructor                 // 回傳函式 Number()  { [native code] }
false.constructor                  // 回傳函式 Boolean() { [native code] }
[1,2,3,4].constructor              // 回傳函式 Array()   { [native code] }
{name:'John', age:34}.constructor  // 回傳函式 Object()  { [native code] }
new Date().constructor             // 回傳函式 Date()    { [native code] }
function () {}.constructor         // 回傳函式 Function(){ [native code] }

可以使用 constructor 屬性來查看物件是否為陣列 (包含字串 "Array")、日期 (包含字串 "Date")

function isArray(myArray) {
    return myArray.constructor.toString().indexOf("Array") > -1;
}
function isDate(myDate) {
    return myDate.constructor.toString().indexOf("Date") > -1;
}

JavaScript 型別轉換

  • 全域方法 String():可以將數字、字母、變數、運算式、布林值、日期轉換為字串
  • Number 方法 toString():可以將數字轉換為字串,
  • Boolean 方法 toString():可以將布林值轉換為字串,"false"、"true",
  • Date 方法 toString():可以將日期物件轉換為字串,回傳 “Thu Jul 17 2014 15:38:19 GMT+0200 (W. Europe Daylight Time)”,
  • 全域方法 Number():可以將字串、布林值、日期轉換為數字,空字串轉換為 0,其他的字串會轉換為 NaN (不是個數字),布林值對應0和1,日期回傳 1404568027739(毫秒數)
  • 一元運算子 +:Operator + 可用于將變數轉換為數字,如果變數不能轉換,則值為 NaN (不是一個數字),
  • **日期方法 getTime() **:可將日期轉換為數字,回傳 1404568027739(毫秒數),

正則運算式

語法

/正則運算式主體/修飾符(可選)

其中修飾符是可選的:

var patt = /runoob/i
  • /runoob/i 是一個正則運算式,
  • runoob 是一個正則運算式主體 (用于檢索),
  • i 是一個修飾符 (搜索不區分大小寫),

使用字串方法

在 JavaScript 中,正則運算式通常用于兩個字串方法 : search() 和 replace(),

  • search() 方法:用于檢索字串中指定的子字串,或檢索與正則運算式相匹配的子字串,并回傳子串的起始位置,
var str = "Visit Runoob!"; 
var n = str.search(/Runoob/i); //不區分大小
var n = str.search("Runoob");
  • replace() 方法:用于在字串中用一些字符替換另一些字符,或替換一個與正則運算式匹配的子串,
var str = document.getElementById("demo").innerHTML; 
var txt = str.replace(/microsoft/i,"Runoob"); //不區分大小
var txt = str.replace("Microsoft","Runoob");

使用 RegExp 物件

在 JavaScript 中,RegExp 物件是一個預定義了屬性和方法的正則運算式物件,

  • test() 方法:用于檢測一個字串是否匹配某個模式,如果字串中含有匹配的文本,則回傳 true,否則回傳 false,
var patt = /e/;
patt.test("The best things in life are free!");

//以上兩行代碼可以合并為一行:
/e/.test("The best things in life are free!");
  • **exec() 方法:用于檢索字串中的正則運算式的匹配,該函式回傳一個存放匹配結果的陣列,未找到匹配則回傳值為 null,
/e/.exec("The best things in life are free!");

參考 JavaScript RegExp 參考手冊,

表單

表單驗證

判斷表單欄位(fname)值是否存在, 如果不存在,就彈出資訊,阻止表單提交:

function validateForm() {
    var x = document.forms["myForm"]["fname"].value;
    if (x == null || x == "") {
        alert("需要輸入名字,");
        return false;
    }
}
<form name="myForm" action="demo_form.php" onsubmit="return validateForm()" method="post">
名字: <input type="text" name="fname">
<input type="submit" value="https://www.cnblogs.com/timefiles/p/提交">
</form>

多表單使用同一驗證函式可以使用以下方法:

function validateForm(form) {
    var x = form.name.value;
    if (x == null || x == "") {
        alert("輸入不能為空!");
        return false;
    }
}

所有表單呼叫時都使用:

onsubmit="return validateForm(this)"

onsubmit="validateForm()" 能夠呼叫 validateForm() 對表單進行驗證,但是在驗證不通過的情況下,并不能阻止表單提交,
onsubmit="return validateForm()" 當驗證不通過時,回傳 false,可以阻止表單提交,

onsubmit="return validateForm()" 相當于復寫了 onsubmit 的默認方法(默認回傳 true),根據 validateForm() 的結果回傳 true 或 false,當驗證不通過時,回傳 false,onsubmit="return false;" 阻止表單提交,

this 的多種指向:

  • 在物件方法中, this 指向呼叫它所在方法的物件,
  • 單獨使用 this,它指向全域(Global)物件,
  • 函式使用中,this 指向函式的所屬者,
  • 嚴格模式下函式是沒有系結到 this 上,這時候 this 是 undefined,
  • 在 HTML 事件句柄中,this 指向了接收事件的 HTML 元素
  • apply 和 call 允許切換函式執行的背景關系環境(context),即 this 系結的物件,可以將 this 參考到任何物件,

let 和 const

let關鍵字

塊級作用域(Block Scope)

使用 var 關鍵字宣告的變數不具備塊級作用域的特性,它在 {} 外依然能被訪問到

{ 
    var x = 2; 
}
// 這里可以使用 x 變數

let 宣告的變數只在 let 命令所在的代碼塊 {} 內有效,在 {} 之外不能訪問

{ 
    let x = 2;
}
// 這里不能使用 x 變數

重新定義變數

使用 var 關鍵字重新宣告變數可能會帶來問題,在塊中重新宣告變數也會重新宣告塊外的變數:

var x = 10;
// 這里輸出 x 為 10
{ 
    var x = 2;
    // 這里輸出 x 為 2
}
// 這里輸出 x 為 2

let 關鍵字可以解決這個問題,它只在 let 命令所在的代碼塊 {} 內有效:

var x = 10;
// 這里輸出 x 為 10
{ 
    let x = 2;
    // 這里輸出 x 為 2
}
// 這里輸出 x 為 10

使用全域變數

使用 var 關鍵字宣告的全域作用域變數屬于 window 物件:

var carName = "Volvo";
// 可以使用 window.carName 訪問變數

使用 let 關鍵字宣告的全域作用域變數不屬于 window 物件:

let carName = "Volvo";
// 不能使用 window.carName 訪問變數

重置變數

  • 使用 var 關鍵字宣告的變數在任何地方都可以修改
  • 在相同的作用域或塊級作用域中,不能使用 let 關鍵字來重置 var 關鍵字宣告的變數
  • 在相同的作用域或塊級作用域中,不能使用 let 關鍵字來重置 let 關鍵字宣告的變數
  • 在相同的作用域或塊級作用域中,不能使用 var 關鍵字來重置 let 關鍵字宣告的變數
  • let 關鍵字在不同作用域,或不同塊級作用域中是可以重新宣告賦值的

const 關鍵字

const 用于宣告一個或多個常量,宣告時必須進行初始化,且初始化后值不可再修改
const定義常量與使用let 定義的變數相似:

  • 二者都是塊級作用域
  • 都不能和它所在作用域內的其他變數或函式擁有相同的名稱

兩者還有以下兩點區別:

  • const宣告的常量必須初始化,而let宣告的變數不用
  • const 定義常量的值不能通過再賦值修改,也不能再次宣告,而 let 定義的變數值可以修改,

注:const 定義的變數并非不可改變,比如使用const宣告物件,可以改變物件值,可以使用Object.freeze()方法來 凍結變數 ,被凍結后的物件只能進行讀操作,

重置變數

  • 使用 var 關鍵字宣告的變數在任何地方都可以修改
  • 在相同的作用域或塊級作用域中,不能使用 const 關鍵字來重置 var 和 let關鍵字宣告的變數
  • 在相同的作用域或塊級作用域中,不能使用 const 關鍵字來重置 const 關鍵字宣告的變數
  • const 關鍵字在不同作用域,或不同塊級作用域中是可以重新宣告賦值的

JSON

JSON 是用于存盤和傳輸資料的格式,通常用于服務端向網頁傳遞資料 ,

語法規則

  • 資料為 鍵/值 對
  • 資料由逗號分隔
  • 大括號保存物件
  • 方括號保存陣列
{"sites":[
    {"name":"Runoob", "url":"www.runoob.com"}, 
    {"name":"Google", "url":"www.google.com"},
    {"name":"Taobao", "url":"www.taobao.com"}
]}

JSON 字串和 JavaScript 物件互轉

要實作從JSON字串轉換為JS物件,使用 JSON.parse() 方法:

var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //結果是 {a: 'Hello', b: 'World'}  一個物件

要實作從JS物件轉換為JSON字串,使用 JSON.stringify() 方法:

var json = JSON.stringify({a: 'Hello', b: 'World'}); //結果是 '{"a": "Hello", "b": "World"}'  一個JSON格式的字串

void(0) 含義

javascript:void(0) 中最關鍵的是 void 關鍵字, void 是 JavaScript 中非常重要的關鍵字,該運算子指定要計算一個運算式但是不回傳值

void(alert("Warnning!"))

href="https://www.cnblogs.com/timefiles/p/#"與href="javascript:void(0)"的區別

  • 包含了一個位置資訊,默認的錨是#top 也就是網頁的上端,

  • javascript:void(0), 僅僅表示一個死鏈接,

在頁面很長的時候會使用 # 來定位頁面的具體位置,格式為:# + id,如果要定義一個死鏈接請使用 javascript:void(0)

<a href="javascript:void(0);">點我沒有反應的!</a>
<a href="https://www.cnblogs.com/timefiles/p/#pos">點我定位到指定位置!</a>
<br>
...
<br>
<p id="pos">尾部定位點</p>

異步編程

異步的概念

異步(Asynchronous, async)是與同步(Synchronous, sync)相對的概念,同步按碼順序執行,異步不按照代碼順序執行,異步的執行效率更高,
通俗地解釋一下異步:異步就是從主執行緒發射一個子執行緒來完成任務

什么時候用異步編程

主執行緒作為一個執行緒,不能夠同時接受多方面的請求,當一個事件沒有結束時,界面將無法處理其他請求,

現在有一個按鈕,如果設定它的 onclick 事件為一個死回圈,那么當這個按鈕按下,整個網頁將失去回應,

子執行緒有一個局限:一旦發射了以后就會與主執行緒失去同步,無法確定它的結束,

為了解決這個問題,JavaScript 中的異步操作函式往往通過回呼函式來實作異步任務的結果處理

回呼函式

回呼函式就是一個函式,在啟動一個異步任務的時候就告訴它:等完成了這個任務之后要干什么

function print() {
    document.getElementById("demo").innerHTML="RUNOOB!";
}
setTimeout(print, 3000);

這段程式中的 setTimeout 就是一個消耗時間較長(3 秒)的程序,它的第一個引數是個回呼函式,第二個引數是毫秒數,這個函式執行之后會產生一個子執行緒,子執行緒會等待 3 秒,然后執行回呼函式 "print",在命令列輸出 "Time out",

不必單獨定義一個函式 print ,常常將上面的程式寫成:

setTimeout(function () {
    document.getElementById("demo").innerHTML="RUNOOB!";
}, 3000);

異步 AJAX

除了 setTimeout 函式以外,異步回呼廣泛應用于 AJAX 編程,參考:https://www.runoob.com/ajax/ajax-tutorial.html

XMLHttpRequest 常常用于請求來自遠程服務器上的 XML 或 JSON 資料,一個標準的 XMLHttpRequest 物件往往包含多個回呼:

var xhr = new XMLHttpRequest();
 
xhr.onload = function () {
    // 輸出接收到的文字資料
    document.getElementById("demo").innerHTML=xhr.responseText;
}
 
xhr.onerror = function () {
    document.getElementById("demo").innerHTML="請求出錯";
}
 
// 發送異步 GET 請求
xhr.open("GET", "https://www.runoob.com/try/ajax/ajax_info.txt", true);
xhr.send();

XMLHttpRequest 的 onload 和 one rror 屬性都是函式,分別在它請求成功和請求失敗時被呼叫

如果使用完整的 jQuery 庫,也可以更加優雅的使用異步 AJAX:

$.get("https://www.runoob.com/try/ajax/demo_test.php",function(data,status){
    alert("資料: " + data + "\n狀態: " + status);
});

Promise

Promise 是一個 ECMAScript 6 提供的類,目的是更加優雅地書寫復雜的異步任務,由于 Promise 是 ES6 新增加的,一些舊的瀏覽器并不支持,

構造 Promise

現在新建一個 Promise 物件:

new Promise(function (resolve, reject) {
    // 要做的事情...
});

用 Promise 來實作三次輸出字串,第一次間隔 1 秒,第二次間隔 4 秒,第三次間隔 3 秒:

new Promise(function (resolve, reject) {
    setTimeout(function () {
        console.log("First");
        resolve();
    }, 1000);
}).then(function () {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log("Second");
            resolve();
        }, 4000);
    });
}).then(function () {
    setTimeout(function () {
        console.log("Third");
    }, 3000);
});

Promise 的使用

下面通過剖析這段 Promise "計時器" 代碼來講述 Promise 的使用:

Promise 建構式只有一個引數,是一個函式,這個函式在構造之后會直接被異步運行——稱之為起始函式

**起始函式包含兩個引數 resolve 和 reject*8,當 Promise 被構造時起始函式會被異步執行:

new Promise(function (resolve, reject) {
    console.log("Run");
});

resolve 和 reject 都是函式,其中呼叫 resolve 代表一切正常reject 是出現例外時所呼叫的

new Promise(function (resolve, reject) {
    var a = 0;
    var b = 1;
    if (b == 0) reject("Divide zero");
    else resolve(a / b);
}).then(function (value) {
    console.log("a / b = " + value);
}).catch(function (err) {
    console.log(err);
}).finally(function () {
    console.log("End");
});

Promise 類有 .then() .catch().finally() 三個方法,這三個方法的引數都是一個函式:

  • .then() 可以將引數中的函式添加到當前 Promise 的正常執行序列;
  • .catch() 則是設定 Promise 的例外處理序列;
  • .finally() 是在 Promise 執行的最后一定會執行的序列,

.then() 傳入的函式會按順序依次執行,有任何例外都會直接跳到 catch 序列:

new Promise(function (resolve, reject) {
    console.log(1111);
    resolve(2222);
}).then(function (value) {
    console.log(value);
    return 3333;
}).then(function (value) {
    console.log(value);
    throw "An error";
}).catch(function (err) {
    console.log(err);
});

執行結果:

1111
2222
3333
An error
  • resolve() 中可以放置一個引數用于向下一個 then 傳遞一個值,then 中的函式也可以回傳一個值傳遞給 then,如果 then 中回傳的是一個 Promise 物件,那么下一個 then 將相當于對這個回傳的 Promise 進行操作
  • reject() 引數中一般會傳遞一個例外給之后的 catch 函式用于處理例外
  • **resolve 和 reject 的作用域只有起始函式,不包括 then 以及其他序列,
  • **resolve 和 reject 并不能夠使起始函式停止運行,別忘了 return,

Promise 函式

可以將上面程式的核心部分寫成一個 Promise 函式:

function print(delay, message) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log(message);
            resolve();
        }, delay);
    });
}

然后實作程式功能:

print(1000, "First").then(function () {
    return print(4000, "Second");
}).then(function () {
    print(3000, "Third");
});

異步函式

異步函式(async function)是 ECMAScript 2017 (ECMA-262) 標準的規范,可以上面實作程式功能的代碼變得更好看:

async function asyncFunc() {
    await print(1000, "First");
    await print(4000, "Second");
    await print(3000, "Third");
}
asyncFunc();

異步函式 async function 中可以使用 await 指令,await 指令后必須跟著一個 Promise,異步函式會在這個 Promise 運行中暫停,直到其運行結束再繼續運行,

異步函式實際上原理與 Promise 原生 API 的機制是一模一樣的,處理例外的機制將用 try-catch 塊實作:

async function asyncFunc() {
    try {
        await new Promise(function (resolve, reject) {
            throw "Some error"; // 或者 reject("Some error")
        });
    } catch (err) {
        console.log(err);
        // 會輸出 Some error
    }
}
asyncFunc();

如果 Promise 有一個正常的回傳值,await 陳述句也會回傳它:

async function asyncFunc() {
    let value = https://www.cnblogs.com/timefiles/p/await new Promise(
        function (resolve, reject) {
            resolve("Return value");
        }
    );
    console.log(value);
}
asyncFunc();

輸出:

Return value

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/288219.html

標籤:JavaScript

上一篇:基于webpack5封裝的cli工具packx

下一篇:[測驗]Sprint Boot

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more