JavaScript核心知識點


一、JavaScript 簡介

        一、JavaScript語言的介紹:JavaScript是基於對象和原型的一種動態、弱類型腳本語言

        二、JavaScript語言的組成:JavaScript是由核心語法(ECMAScript)、文檔對象模型(DOM)、瀏覽器對象模型(BOM)組成的

        三、JavaScript語言的應用:實現頁面表單驗證以及頁面交互特效,基於Node.js技術進行服務器端編程等

 

二、JavaScript ECMAScript

        一:基礎語法

                  一:變量

                        1. 變量的聲明

                               1. var變量:var 變量名 = 值;

                               2. let變量:let 變量名 = 值;

                               3. const變量:const 變量名 = 值;

 

                         2. 變量的作用域

                                1. 全局作用域:代碼中任何地方都能訪問到

                                2. 局部作用域:在固定的代碼片段內可訪問到

 

                         3. 變量提升:變量在聲明之前就訪問,var會使用默認值undefined,而let會直接報錯

                         4. var、let、const區別

                             

 

                                           

                 二:運算符

                        1. 算數運算符:加(+),減(-),乘(*),除(/),求余(%)

                        2. 賦值運算符:=,+=,-=,*=,%=

                        3. 關系運算符:>,<,>=,<=,==(只比較值),!=,===(值和數據類型都比較)

                        4. 邏輯運算符:[&&,||](只有左側滿足才計算右側),!,[&,|](不管左側結果如何,都要計算右側)

                        5. 三目運算符:(表達式) ? 值1,值2;

 

                 三:流程控制語句

                        1. 條件分支語句:if語句,switch語句

                        2. 循環語句:while循環,do while循環,for循環,for-in循環

 

        二:數據類型

                 一:原始類型(基本類型):值不可變(原始值)

                        1. Undefined類型:只有一個值undefined,表示未初始化或未聲明的變量,因此我們應該對變量顯示的初始化(不要是undefined)

                        2. Null類型:只有一個值null,表示一個空指針對象,因此我們應該將保存對象的變量初始化為null

                        3. Boolean類型:只有true和false兩個值

                        4. Number類型:表示所有的數值類型,數值范圍在(Number.MIN_VALUE~Number.MAX_VALUE)之間,超出范圍會自動轉化為

                           [-+]Infinity(無窮),NaN是一個非數值

                        5. String類型:  表示一個字符串,其他類型可以使用toString方法轉為字符串

                        6. Symbol類型:表示一個符號,符號類型是唯一的並且是不可修改的

 

                 二:引用類型:值可變

                        1. 概念:引用類型是一種數據結構,用於將數據和功能組織在一起

                        2. 常見引用類型:對象(Object)、數組(Array)、函數(Function)、正則(RegExp)和日期(Date)

 

        三:函數

               一:函數概述

                        1. 函數的概念:具有獨立功能的代碼塊。在js中使用function關鍵字定義函數

                        2. 函數的作用:讓代碼結構更加清晰,提高代碼重用性和可移植性

                        3. js函數的分類:自定義函數和系統函數

 

               二:自定義函數

                        1. 函數的創建和調用

                             1. 函數的創建方式:函數聲明、函數表達式、函數構造函數、屬性函數

                             2. 函數的調用方式:函數調用模式、方法調用模式、構造器調用模式、apply調用模式

/**
 * 1. 函數的創建 
 *      1. 函數聲明
 *            1. 格式:function 函數名( [參數列表] ) { 要執行的代碼 } 
 *            2. 特點:預編譯時會解釋聲明,所以在函數聲明前后都可以調用函數
 *            
 *      2. 函數表達式
 *            1. 格式:var 函數名 = function( [參數列表] ) { 要執行的代碼 }; 
 *            2. 特點:系統只有加載到該函數時才會聲明,所以只能在函數聲明后調用
 *            
 *      3. 函數構造函數
 *            1. 格式:var 函數名 = function( [參數列表] ) { 要執行的代碼 } 
 *            2. 特點:系統加載到該函數時會自動執行,不需要調用,但是性能差,不推薦使用
 *            
 *      4. 屬性函數:屬性名 : function( [參數列表] ) { 要執行的代碼 } 
 *       
 */

// 1. 函數聲明
function create1() {
    alert("函數聲明");
}
create1();

// 2. 函數表達式
var create2 = function() {
    alert("函數表達式");
};
create2();

// 3. 函數構造函數
var create3 = new function() {
    alert("函數構造函數");
}

//4. 屬性函數
var People = {
    name : function() {
        console.log("對象函數屬性1");
    },
    age : function() {
        console.log("對象函數屬性2");
    }
}
People.name();


/**
 * 2. 函數的調用
 *      1. 函數調用模式
 *            1. 函數聲明后直接調用,一般是由函數聲明和函數表達式創建的函數
 *            2. this指向window對象
 *            
 *      2. 方法調用模式
 *            1. 對象調用屬性函數,一般是由屬性函數創建的函數
 *            2. this指向當前對象
 *            
 *      3. 構造器調用模式
 *            1. 必須實例化對象后才能調用其原型方法
 *            2. 如果沒有return則返回this,this指向當前實例化對象;如果有return則返回return的值
 *            
 *      4. apply調用模式
 *            1. apply和call第一個如果使用null就是函數模式,使用對象就是方法模式
 *            2. apply第二個參數是傳入一個參數數組,call的參數是直接傳入
 *        
 *      5. 事件響應調用
 *            1. 在HTML標簽的事件屬性中調用
 *                  <input type="button" value="點我測試" onclick="函數名()" />
 *                  
 *            2. 在js事件響應中調用
 *                  DOM對象.onclick = function(){要執行的代碼}
 *                   
 *            3. 在js事件監聽中調用
 *                   DOM對象.addEventListener(onclick,function(){要執行的代碼}, false);
 *               
 *      6. 超鏈接調用
 *             <a href="javascript: 函數名()">超鏈接調用</a>
 *             
 */

// 1. 函數調用模式
function funCall1() {
    alert("函數調用模式1:函數聲明");
}
funCall1();

var funCall2 = function() {
    alert("函數調用模式2:函數表達式");
};
funCall2();

// 2. 方法調用模式
var Menthods = {
    filed : function() {
        alert("方法調用模式:屬性函數")
    }
}
Menthods.filed();

// 3. 構造器調用模式
function Fileds(name, value) {
    this.name = name;
    this.value = value;
    this.sayHello = function() {
        return this.name + ":" + this.value;
    }
}
var filed = new Fileds("address", "高老庄");
filed.sayHello();

// 4. apply調用模式
function add(a, b) {
    return a + b;
}
console.log(add.apply(add, [ 2, 3 ])); // apply調用模式
console.log(add.call(add, 2, 3)); // call調用模式
js函數的創建和調用代碼實現

 

                       2. 匿名函數

                            1. 概念及作用:沒有名字的函數,創建閉包,避免造成全局變量的污染

                            2. 使用場景:函數表達式、對象屬性、事件及其參數,返回值

                            3. 匿名自執行函數

                                  1. 概念:匿名函數的定義完成后立即執行,執行函數表達式

                                  2. 作用:實現閉包和創建獨立的命名空間

                                  3. 使用:分組操作符(),void操作符,~操作符,!操作符等等

/**
 * 1. 匿名函數的使用場景
 *       1. 函數表達式
 *       2. 對象屬性
 *       3. 事件
 *       4. 事件參數
 *       5. 返回值
 */
window.onload = function() {
    // 1. 函數表達式
    let funcObj = function() {
        alert("我是在函數表達式中使用的匿名函數");
    };
    funcObj();

    // 2. 對象屬性
    let Obj = {
        name : function() {
            alert("我是在對象屬性中使用的匿名函數")
        }
    }
    Obj.name();

    // 3. 事件
    let btn1 = document.getElementById("btn1");
    btn1.onclick = function() {
        alert("我是在事件中使用的匿名函數");
    }

    // 4.1 事件參數
    setInterval(function() {
        alert("我是在事件參數中使用的匿名函數");
    }, 10000);
    
    // 4.2 事件監聽參數
    // 1. 基於IE內核瀏覽器
    let btn2 = document.getElementById("btn2");
    btn2.attachEvent(onclick, function() {
        alert("我是在事件監聽中使用的匿名函數");
    }, false);

    // 2.  基於W3C內核的事件監聽
    let btn3 = document.getElementById("btn3");
    btn3.addEventListener(onclick, function() {
        alert("我是在事件監聽中使用的匿名函數");
    }, false);
    

    // 5. 返回值
    function test(){
        return function(){
            return "哈哈";
        }
    }
    console.log(test()());
}

/**
 * 2. 匿名自執行函數:將函數轉為表達式
 *       1. 分組操作符(0
 *       2. void操作符
 *       3. ~操作符
 *       4. !操作符
 */

//函數表達式
var funcObj6 = function(){
    alert("我是函數表達式");
}();

// 1. 分組操作符
// 1.1 第一種:()在外面
(function funcObj1(){
    alert("我是由分組操作符使用匿名自執行函數1");
})();

// 1.2 第二種:()在里面
(function funcObj2(){
    alert("我是()操作符");
}());


// 2. void操作符
void function funcObj3(){
    alert("我是void操作符")
}();

// 3. ~操作符
~function funcObj4(){
    alert("我是~操作符");
}();

// 4. !操作符
!function funcObj5(){
    alert("我是!操作符");
}();
js匿名函數代碼實現

 

                三:系統函數(內置函數)

                          1. 常規函數

                                     js常規函數

/**
 * js常規函數
 */

window.onload = function() {
    // 1. 顯示一個警告框
    alert("我是一個警告框");

    // 2. 顯示一個確認框
    confirm("我是一個確認框");

    // 3. 顯示一個輸入框
    prompt(name, "張三");

    // 4. 判斷是否為數字
    if (!isNaN("a")) {
        alert("這是一個數值");
    } else {
        alert("這不是一個數值");
    }
    
    // 5. 將字符串轉為數值
    const str = "123";
    if(!isNaN(Number(str))){
        alert("這是一個數值");
    } else {
        alert("這不是一個數值");
    }
    
    // 6. 將一個字符串轉為整數
    console.log(parseInt("112.22", scrollX)); // 123
    
    // 7. 將一個字符串轉為浮點數
    console.log(parseFloat("121.33"));
    
    // 8. 計算表達式的結果
    console.log(eval("5+7*2-15")); // 4
    
    // 9. 判斷一個數是不是無窮大
    function finite(value){
        if(isFinite(value)){
            alert("這不是無窮大");
        } else{
            alert("這是無窮大的");
        }
    }
    finite(12);
    finite(Number().MAX_VALUE);
}
js常規函數代碼實現

 

                       2. 數組函數

                                    js數組函數                               

function array() {
    /**
     * 1. js數組的創建及遍歷
     */

    // 1. 使用字面量創建數組
    let arr1 = [];
    let arr2 = [ 1, 5, 3, 2, 6 ];

    // 2. 使用Array構造函數創建數組
    let arr3 = new Array();
    let arr4 = new Array(1, 5, 3, 2, 6);

    // 3. 向數組添加元素
    arr1[0] = 1;
    arr1[1] = 2;
    console.log(arr1); // [ 1, 2 ]
    arr3[0] = 3;
    arr3[1] = 4;
    console.log(arr3); // [ 3, 4 ]

    // 4. 遍歷集合
    // 4.1 普通for循環
    for (let i = 0; i < arr2.length; i++) {
        console.log(arr2[i]); 
    }
    
    // 4.2 for-in循環
    for (let i in arr2) {
        console.log(arr2[i]);
    }
    
    
    /**
     * 2. js數組常用方法
     */

    // 1. 添加元素在數組首部
    console.log(arr1.unshift(2)); // 3
    console.log(arr1); // [ 2, 1, 2 ]
    
    // 2. 添加元素在數組末尾
    console.log(arr1.push(1)); // 4
    console.log(arr1); // [ 2, 1, 2, 1 ]
    
    // 3. 刪除數組第一個元素
    console.log(arr1.shift(1)); // 2
    console.log(arr1); // [ 1, 2, 1 ]
    
    // 4. 刪除數組最后一個元素
    console.log(arr1.pop(1)); // 1
    console.log(arr1); // [1, 2]
    
    // 5. 刪除指定位置i后的n個元素
    console.log(arr1.splice(1,2)); // [ 2 ]
    console.log(arr1); // [ 1 ]
    
    // 6. 刪除指定位置start到end的元素
    console.log(arr1.slice(1, 2)); // []
    console.log(arr1); // [ 1 ]
    
    // 7. 連接兩個數組
    let arr5 = arr1.concat(arr2);
    console.log(arr5); // [ 1, 1, 5, 3, 2, 6 ]
    
    // 8. 判斷數組是否包含指定元素
    console.log(arr5.indexOf(5)); // 2
    console.log(arr5.indexOf(10)); // -1
    console.log(arr5.includes(5)); // true
    console.log(arr5.includes(10)); // false
    
    // 9. 數組排序
    let arrAscSort = arr5.sort((a, b) => a-b); // 升序排序
    console.log(arrAscSort); // [ 1, 1, 2, 3, 5, 6 ]
    
    let arrDescSort = arr5.sort((a, b) => b-a); // 降序排序
    console.log(arrDescSort); // [ 6, 5, 3, 2, 1, 1 ]
    
    // 10. 數組反轉
    console.log(arrAscSort.reverse()); // [ 1, 1, 2, 3, 5, 6 ]
    
    // 11. 將偽數組轉為數組
    let str = "12345";
    console.log(Array.from(str)); // [ "1", "2", "3", "4", "5" ]
    let str1 = "我是一只小小鳥";
    console.log(Array.from(str1)); // [ "我", "是", "一", "只", "小", "小", "鳥" ]
    
    // 12. 判斷此變量是否為數組
    console.log(Array.isArray(str)); // false
}
js數組函數代碼實現

 

 

                       3. 日期函數

                                   js日期函數

/**
 * 日期函數
 */
window.onload = function(){
    // 創建日期對象
    var now = new Date();
    
    // 1. 獲取年份
    console.log(now.getFullYear());
    
    // 2. 獲取月份
    console.log(now.getMonth() + 1);
    
    // 3. 獲取日期
    console.log(now.getDate());
    
    // 4. 獲取小時
    console.log(now.getHours());
    
    // 5. 獲取分鍾
    console.log(now.getMinutes());
    
    // 6. 獲取秒
    console.log(now.getSeconds());
    
    // 7. 獲取毫秒
    console.log(now.getMilliseconds());
    
    // 8. 獲取時間戳
    console.log(now.getTime());
    
}
js日期函數代碼實現

                                 

                       4. 數學函數

                                    js數學函數

/**
 * 數學函數
 */

// 1. 絕對值
console.log(Math.abs(-5)); // 5

// 2. 向上取整
console.log(Math.ceil(5.1)); // 6

// 3. 向下取整
console.log(Math.floor(5.9)); // 5

// 4. 四舍五入
console.log(Math.round(5.5)); // 6

// 5. 求平方根
console.log(Math.sqrt(4)); // 2

// 6. 生成指定位的隨機數
function getRandomNumber(min, max){
    return Math.floor(Math.random()*(max - min)) + min;
}
console.log(getRandomNumber(1000, 9999));
js數學函數代碼實現

 

                       5. 字符串函數

                                         js字符串函數

/**
 * 字符串函數
 */
window.onload = function() {
    const str = "雞,你,太,美";

    // 1. 搜索字符串,返回索引值
    console.log(str.indexOf("太")); // 4

    // 2. 將字符串按照指定的分隔符分成字符串
    var arr = str.split(',');
    for (var i in arr) {
        console.log(arr[i]);
    }
    
    // 3. 清空字符串兩側空格
    console.log(" 我是懶洋洋 ".trim()); // 我是懶洋洋
    
    // 4. 返回字符串首次出現的位置
    console.log(str.search("太")); // 4
    
    // 5. 按照指定規則查找值
    console.log(str.match(/太/i)); // ["太", index: 4, input: "雞,你,太,美", groups: undefined]
    
    // 6. 字符替換
    console.log(str.replace("雞", "及")); // 及,你,太,美
    
    // 7. 從指定位置切割字符串,左閉右開
    console.log(str.substring(2, 5)); // 你,太
    
    // 8. 從指定位置切n個字符
    console.log(str.substr(2, 5)); // 你,太,美
}
js字符串函數代碼實現

 

 

        四:面向對象

                   一:js面向對象概述

                        js是基於原型基於面向對象編程也即OOP(Object Oriented Programming),它沒有類的概念,而是直接使用對象來編程

 

                二:js創建對象的方式

                        1. 創建Object實例和對象字面量

                               缺點:重復實例化對象時代碼冗余高

 

                        2. 工廠模式

                              1. 優點:解決重復實例化對象的問題
                              2. 缺點:無法識別對象的類型,因為所有的實例指向一個原型(Object)

 

                       3. 構造函數模式

                             1. 優點:實例可以識別為一個特定的類型,解決工廠模式的缺點
                             2. 缺點:多個實例重復創建方法,無法共享

 

                       4. 原型模式

                             1. 優點:方法不會被重復創建,解決了構造函數模式的缺點
                             2. 缺點:所有實例共享它的屬性和方法,不能傳參和初始化屬性值

 

                       5. 混合模式(3+4)推薦

                             1. 優點:構造函數共享實例屬性,原型共享方法和想要共享的屬性,可傳遞參數,初始化屬性值
                             2. 缺點:基本沒有

/**
 * 創建對象的方式
 *     1. 創建Object實例和對象字面量
 *           缺點:重復實例化對象時代碼冗余高
 *     
 *     2. 工廠模式
 *           1. 優點:解決重復實例化對象的問題
 *           2. 缺點:無法識別對象的類型,因為所有的實例指向一個原型(Object)
 *       
 *     3. 構造函數模式
 *           1. 優點:實例可以識別為一個特定的類型,解決工廠模式的缺點
 *           2. 缺點:多個實例重復創建方法,無法共享
 *   
 *     4. 原型模式
 *           1. 優點:方法不會被重復創建,解決了構造函數模式的缺點
 *           2. 缺點:所有實例共享它的屬性和方法,不能傳參和初始化屬性值
 *   
 *     5. 混合模式(構造函數和原型模式)
 *           1. 優點:構造函數共享實例屬性,原型共享方法和想要共享的屬性,可傳遞參數,初始化屬性值
 *           2. 缺點:基本沒有
 */

window.onload = function() {
    // 1. 創建Object實例
    let Person = new Object();
    Person.name = "張三";
    Person.age = "18";
    Person.showInfo = function() {
        console.log(this.name + "今年" + this.age + "了");
    }
    Person.showInfo();

    // 2. 對象字面量
    let Student = {
        name : "張三",
        age : "18",
        showInfo : function() {
            console.log(this.name + "今年" + this.age + "了");
        }
    };
    Student.showInfo();


    // 3. 工廠模式
    function createObjFactory(name, age) {
        const obj = new Object();
        obj.name = name;
        obj.age = age;
        obj.showInfo = function() {
            console.log(this.name + "今年" + this.age + "了");
        }
        return obj;
    }
    let obj = createObjFactory("張三", 17);
    obj.showInfo();
    // 缺點驗證
    console.log(obj instanceof Object); // true
    console.log(obj instanceof createObjFactory); // false


    // 4. 構造函數模式
    function Teacher(name, age) {
        this.name = name;
        this.age = age;
        this.showInfo = function() {
            console.log(this.name + "今年" + this.age + "了");
        }
    }
    let tea1 = new Teacher("張三", 28);
    let tea2 = new Teacher("李四", 10);
    // 優點驗證
    console.log(tea1 instanceof Object); // true
    console.log(tea1 instanceof Teacher); // true
    // 缺點驗證
    console.log(tea1.showInfo == tea2.showInfo); // false
    
    

    // 5. 原型模式
    function Worker() {
    }
    Worker.prototype = {
        constructor : Worker,
        name : "張三",
        age : 18,
        showInfo : function() {
            console.log(this.name + "今年" + this.age + "了");
        }
    };
    let wor1 = new Worker();
    let wor2 = new Worker();
    // 優點驗證
    console.log(wor1.showInfo == wor2.showInfo); // true
    // 缺點驗證
    console.log(wor1.name == wor2.name); // true

    
    
    // 6. 混合模式(構造函數模式和原型模式)
    function People(name, age) {
        this.name = name;
        this.age = age;
    }
    People.prototype = {
        constructor : People,
        showInfo : function() {
            console.log(this.name + "今年" + this.age + "了");
        }
    };
    let p = new People("王五", 50);
    let p2 = new People("李四", 20);
    // 優點驗證
    console.log(p.showInfo == p2.showInfo); // true
    console.log(p.name == p2.name); // false

    
}
js創建對象代碼實現

 

                三:原型和原型鏈

                       1. 原型對象

                              1. 函數對象都具有prototype屬性,它指向函數的原型對象(瀏覽器內存創建的對象),原型對象都具有constructor屬性,它指向

                                  prototype屬性所在的函數對象(構造函數)

                              2. 當調用構造函數創建一個實例后,該實例會有一個隱藏屬性__proto__ ([[prototype]] ),它指向構造函數的原型對象。  

                              3. 所有構造函數的prototype都是object類型,而Function的prototype是一個空函數,所有內置函數的_proto_指向這個空函數。

                              4. 為實例添加一個屬性時,這個屬性會屏蔽原型對象中的同名屬性(不會重寫),若想訪問原型對象中的屬性值,需要使用delete將

                                  這個同名屬性在實例中徹底刪除

                              5. hasOwnProperty("屬性名")可以檢測一個屬性是存在於實例還是原型對象中,true表示存在於實例中,false表示存在於原型對象中

                              6. in操作符用來判斷一個屬性是否存在於這個對象中(無論是實例還是原型對象)

                              7. 當使用對象字面量來重寫原型對象時,會改變其constructor屬性,使其指向Object構造函數,而不是原有的對象

/**
 * 1. 原型
 */
window.onload = function() {
    // 函數對象
    function People(name, age) {
        this.name = name;
        this.age = age;
    }
    People.prototype = {
        constructor : People,
        showInfo : function() {
            console.log(this.name + "今年" + this.age + "歲了");
        }
    };

    let p = new People();
    p.showInfo();

    /**
     * 1. 驗證第一條
     */
    // 1.1 構造函數的prototype屬性指向原型對象
    console.log(People.prototype); // {constructor: ƒ, showInfo: ƒ}

    // 1.2 原型對象的constructor屬性指向構造函數
    console.log(People.prototype.constructor); // ƒ People()

    /**
     * 2. 驗證第二條
     */
    // 構造函數的實例有__proto__屬性,他指向構造函數的原型對象
    console.log(p.__proto__ === People.prototype); // true

    /**
     * 3. 驗證第三條
     */
    // 3.1 所有構造函數的prototype都是object
    function A() {
    }
    console.log(typeof People.prototype); // object
    console.log(typeof A.prototype); // object
    console.log(People.prototype instanceof Object); // true
    console.log(A.prototype instanceof Object); // true

    // 3.2 Function的prototype是個空函數
    console.log(Function.prototype); // ƒ ()

    // 3.3 所有內置函數的__proto__屬性都指向這個空函數
    console.log(Array.__proto__); // ƒ ()
    console.log(Date.__proto__); // ƒ ()
    console.log(Math.__proto__); // ƒ ()
    console.log(String.__proto__); // ƒ ()

    /**
     * 4. 驗證第四條
     */
    // 1. 為實例添加一個屬性時會屏蔽原型對象的同名屬性值,因為會先在實例中找,找不到才去原型對象中找
    function Teacher(name) {
        this.name = name;
    }
    Teacher.prototype.name = "張三";
    let tea = new Teacher("李四");
    console.log(tea.name); // 李四
    console.log(tea.__proto__.name); // 張三

    // 2. 使用delete刪除實例的同名屬性值
    console.log(
        delete tea.name
    ); // true
    console.log(tea.name); // 張三

    /**
     * 5. 驗證第五條
     */
    // 檢測一個屬性在實例對象中(true)還是原型對象中(false)
    console.log(p.hasOwnProperty(name)); // false

    /**
     * 6. 驗證第六條
     */
    // 判斷實例和原型對象是否有此屬性
    console.log(name in p); // false

    /**
     * 7. 驗證第七條
     */
    //當使用對象字面量來重寫原型對象時,會改變其constructor屬性,使其指向Object構造函數,而不是原有的對象
    function Worker(name) {
        this.name = name;
    }
    Worker.prototype = {
        // 必須手動指向
        constuctor : Worker,
        showInfo : function() {
            alert(this.name);
        }
    };
    // 沒有手動指向
    console.log(Worker.prototype); // {showInfo: ƒ}
    // 手動指向
    console.log(Worker.prototype); // {constuctor: ƒ, showInfo: ƒ}
    
    /**
     * 8. 判斷一個對象是否在此對象的原型鏈中
     */
    console.log(Object.prototype.isPrototypeOf(p)); // true 
    console.log(People.prototype.isPrototypeOf(p)); // true
    
    /**
     * 9. 返回該對象的原型
     */
    console.log(p.__proto__ === Object.getPrototypeOf(p)); // true
}
原型代碼實現

 

             

                       2. prototype和__proto__的區別

                                    1. prototype屬性只有函數對象有,而__proto__屬性所有對象都有

                             2. prototype是由函數對象指向原型對象,而__proto__屬性是由實例指向函數對象的原型對象

                             

                       3. 原型鏈:將父類型的實例作為子類型的原型對象,以此構成的鏈式關系叫做原型鏈

                                    

          

 

                四:繼承

                          1. 原型鏈繼承

                              1. 優點:父類原型定義的屬性和方法可以復用
                              2. 缺點:子類實例沒有自己的屬性,不能向父類傳遞參數

 

                       2. 構造函數繼承

                              1. 優點:子類實例有自己的屬性,可以向父類傳遞參數,解決原型鏈繼承的缺點
                              2. 缺點:父類原型的屬性和方法不可復用

 

                       3. 組合繼承(推薦1)

                              1. 優點:原型的屬性和方法可以復用,每個子類實例都有自己的屬性。
                              2. 缺點:父類構造函數調用了兩次,子類原型的中的父類實例屬性被子類實例覆蓋

 

                        4. 寄生組合式繼承(推薦2)

                               1. 優點:解決了組合繼承的缺點,效率高
                               2. 缺點:基本沒有

/**
 *   1. 原型鏈繼承
 *       1. 優點:父類原型定義的屬性和方法可以復用
 *       2. 缺點:子類實例沒有自己的屬性,不能向父類傳遞參數
 *         
 *   2. 構造函數繼承
 *       1. 優點:子類實例有自己的屬性,可以向父類傳遞參數,解決原型鏈繼承的缺點
 *       2. 缺點:父類原型的屬性和方法不可復用
 *       
 *   3. 組合繼承
 *       1. 優點:父類原型的屬性和方法可以復用,每個子類實例都有自己的屬性。
 *       2. 缺點:父類構造函數調用了兩次,子類原型的中的父類實例屬性被子類實例覆蓋
 *       
 *   5. 寄生組合式繼承
 *       1. 優點:解決了組合繼承的缺點,效率高
 *       2. 缺點:基本沒有
 *       
 */

/**
 *   1. 原型鏈繼承
 */
function test1() {
    function SuperType() {
        this.city = [ "北京", "上海", "天津" ];
        this.property = true;
    }
    SuperType.prototype = {
        constructor : SuperType, // 保持構造函數和原型對象的完整性
        age : 15,
        getSuperValue : function() {
            return this.property;
        }
    };
    function SonType() {
        this.property = false;
    }

    // 重寫子類的原型指向父類的實例:繼承父類的原型
    SubType.prototype = new SuperType();

    SubType.prototype = {
        constructor : SubType,
        getSonType : function() {
            return this.property;
        }
    };

    // 優點驗證
    let son = new SubType();
    console.log(son.age); // 15
    console.log(son.getSuperValue()); // false

    // 缺點驗證
    let instance1 = new SubType();
    instance1.city.push("重慶");
    console.log(instance1.city); // ["北京", "上海", "天津", "重慶"]

    let instance2 = new SubType();
    console.log(instance2.city); // ["北京", "上海", "天津", "重慶"]

}
//test1();


/**
 *   2. 構造函數繼承
 */
function test2() {
    function SuperType(name) {
        this.name = name;
        this.city = [ "北京", "上海", "天津" ]
    }
    SuperType.prototype = {
        constructor : SuperType,
        age : 18,
        showInfo : function() {
            return this.name;
        }
    };

    function SubType() {
        // 父類調用call()或者apply()方法和子類共用同一個this,實現子類實例屬性的繼承
        SuperType.call(this, "張三");
    }

    // 優點驗證
    let instance = new SubType();
    instance.city.push("重慶");
    console.log(instance.city); // ["北京", "上海", "天津", "重慶"]

    let instance1 = new SubType();
    console.log(instance1.city); // ["北京", "上海", "天津"]

    // 缺點驗證
    console.log(instance.age); // undefined
    instance.showInfo(); // son.showInfo is not a function
}
//test2();


/**
 *   3. 組合繼承
 */
function test3() {
    function SuperType(name) {
        this.name = name;
        this.city = [ "北京", "上海", "天津" ]
    }
    SuperType.prototype = {
        constructor : SuperType,
        showInfo : function() {
            console.log(this.name + "今年" + this.age + "歲了");
        }
    };

    function SubType(name, age) {
        // 1. 通過構造方法繼承實現實例屬性的繼承
        SuperType.call(this, name);
        this.age = age;
    }

    // 2. 通過原型鏈繼承實現原型方法的繼承
    SubType.prototype = new SuperType();

    // 優點驗證
    let instance = new SubType("張三", 15);
    instance.showInfo(); // 張三今年15歲了

    let instance1 = new SubType();
    instance1.city.push("重慶");
    console.log(instance1.city); // ["北京", "上海", "天津", "重慶"]

    let instance2 = new SubType();
    console.log(instance2.city); // ["北京", "上海", "天津"]

}
//test3();


/*
 *   4. 寄生組合式繼承
 */
function test4() {
    function inheritPrototype(subType, superType) {
        // 1. 繼承父類的原型
        var prototype = Object.create(superType.prototype);
        // 2. 重寫被污染的construct
        prototype.constructor = subType;
        // 3. 重寫子類的原型
        subType.prototype = prototype;
    }
    function SuperType(name) {
        this.name = name;
        this.city = [ "北京", "上海", "天津" ];
    }

    SuperType.prototype.sayName = function() {
        console.log(this.name);
    };

    function SubType(name, age) {
        SuperType.call(this, name);
        this.age = age;
    }

    // 將父類原型指向子類
    inheritPrototype(SubType, SuperType);

    SubType.prototype.sayAge = function() {
        console.log(this.age);
    }

    // 優點驗證
    let instance = new SubType("張三", 15);
    instance.sayName(); // 張三

    let instance1 = new SubType();
    instance1.city.push("重慶");
    console.log(instance1.city); // ["北京", "上海", "天津", "重慶"]

    let instance2 = new SubType();
    console.log(instance2.city); // ["北京", "上海", "天津"]
}
test4();
繼承代碼實現

 

                           5. class繼承

                              1. class類中的方法是原型方法不用function聲明
                              2. 子類的__proto__屬性指向父類,表示構造函數的繼承
                              3. 子類的原型的__proto__指向父類的原型,表示方法的繼承
                              4. class類可以繼承Object和null

/**
 * class繼承
 *     1. class類中的方法是原型方法不用function聲明
 *     2. 子類的__proto__屬性指向父類,表示構造函數的繼承
 *     3. 子類的原型的__proto__指向父類的原型,表示方法的繼承
 *     4. class類可以繼承Object和null
 */
class SuperType {
    // 構造方法,只能有一個
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    toString() {
        console.log(this.name + "今年" + this.age + "歲了");
    }
}

class SubType extends SuperType {
    // 子類必須繼承父類構造方法
    constructor(name, age){
        // 調用父類構造方法,只能在第一行
        super(name, age);
    }
}

var obj = new SubType("張三", 15);
obj.toString(); // 張三今年15歲了
// 驗證第一條
console.log(obj.toString === SuperType.prototype.toString); // true
// 驗證第二條
console.log(SubType.__proto__); // class SuperType
// 驗證第三條
console.log(SubType.prototype.__proto__); // {constructor: ƒ, toString: ƒ}
// 驗證第四條
class A extends Object{}
class B extends null{}
console.log(A.__proto__ === Object); // true
console.log(A.prototype.__proto__ === Object.prototype); // true
console.log(B.__proto__ === Function.prototype); // true
console.log(B.prototype.__proto__ === undefined); // true
class繼承代碼實現

 

 

        五:正則表達式    

                 一:概述

                           正則表達式(regular expression)描述了一種字符串匹配的模式(pattern),通常被用來檢索、替換那些符合某個模式(規則)的文本。

 

                 二:語法

                                      正則表達式

 

                 三:js正則表達式     

(function() {
    /**
     * 1. JavaScript使用正則式的函數
     */
    const str = "abchelloasdasdhelloasd";

    // 1. 查找
    console.log(str.search("h")); // 3
    
    // 2. 替換
    console.log(str.replace(/a/, "s")); // sbchelloasdasdhelloasd
    
    // 3. 切割
    console.log(str.split(/ab/)); // ["", "bchello", "sd", "sdhello", "sd"]
    
    // 4. RegExp.prototype.test方法:檢測該字符串是否包含指定串
    console.log(/hello/.test("abchello")); // true
    
    // 5. RegExp.prototype.exec方法:將滿足條件的字符串放到數組
    let reg=/hello/g;
    reg.exec("abchelloasdasdhelloasd");  // ["hello"]

}());
js正則表達式

      

                   四:常用正則表達式

                         1. 校驗郵箱:[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?

                         2. 校驗手機號:^1([38][0-9]|4[579]|5[^4]|6[6]|7[0135678]|9[89])\\d{8}$

                         3. 身份證:

                                1. 15位:^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$

                                2. 18位:^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$

        4.日期和時間:^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$

 

 三、JavaScript DOM

        一:簡介

               一:概念:文檔對象模型(Document Object Model,簡稱DOM),是針對HTML和XML文檔的一個API(應用程序接口),將 HTML 文檔呈現為帶有元素、屬性和文本的樹結構,即節點樹

                 二:作用:JavaScript通過DOM能夠改變頁面中所有的HTML 元素、屬性和 CSS 樣式,並對頁面中所有事件做出響應。

                   三:結構圖

                                

 

        二:節點樹

               一:節點類型及屬性

                         節點類型及屬性

<!DOCTYPE html>
<html>
  <head>
    <title>節點類型</title>
    <meta charset="UTF-8">
  </head>
  
  <body>
      <div id="div1">
          <div id="div2">
              <input type="button" id="btn2" />    
          </div>
          <input type="button" id="btn1" />
          <p>我是一只小小鳥</p>
      </div>
      <script>
          let div1 = document.getElementById("div1");
          let div2 = document.getElementById("div2");
          let btn1 = document.getElementById("btn1");
          let btn2 = document.getElementById("btn2");
          
          // 1. 返回節點的類型
          let name = document.createAttribute("name");
          let content = document.createTextNode("content");
          console.log(div1.nodeType + "--" + name.nodeType + "--" + content.nodeType); // 1--2--3
          
          // 2. 返回節點名稱
          console.log(div1.nodeName + "--" + name.nodeName + "--" + content.nodeName); // DIV--name--#text
          
          // 3. 返回節點值
          console.log(div1.nodeValue + "--"  + content.nodeValue); // null--content
          
          // 4. 返回當前元素節點的所有子節點
          console.log(div1.childNodes); //  [text, div#div2, text, input#btn1, text, p, text]
          
          // 5. 返回當前元素節點的父節點
          console.log(btn2.parentNode); // div2
          
          // 6. 返回當前元素節點的下一個節點
          console.log(div2.nextSibling); // #text
          
          // 7. 返回當前元素節點的上一個節點
          console.log(div2.previousSibling); // #text
          
          // 8. 返回當前元素節點的第一個子節點
          console.log(div2.firstChild); // #text
          
          // 9. 返回當前元素節點的最后一個子節點
          console.log(div2.lastChild); // #text
      </script>
  </body>
</html>
節點類型代碼實現

 

               二:文檔節點(Document對象)

                            document的屬性

                       

                         document的方法

 

<!DOCTYPE html>
<html>
<head>
<title>測試</title>
<meta charset="utf-8" />
</head>

<body>
    <div class="div_01">
        <input type="button" value="btn1" id="btn1" />
        <input type="button" name="uname" value="btn2" />
        <input type="button" name="uname" value="btn3" />
        <input type="button" id="btn4" value="btn4" />
    </div>

    
        1. 獲取
             1. 通過id獲取元素節點
             2. 通過name獲取元素節點,返回值是個數組
             3. 通過標簽名獲取元素節點,返回值是個數組
             4. 通過class獲取元素節點,返回值是個對象數組
             5. 通過選擇器獲取元素節點
             6. 通過選擇器獲取所有元素節點集合
    
    <script>
        // 1. 通過id獲取元素
        let btn1 = document.getElementById("btn1");
        btn1.onclick = function() {
            alert("我是通過id獲取到的元素");
        }
    
        // 2. 通過name獲取元素,返回值是個數組
        let byName = document.getElementsByName("uname");
        for (let i = 0; i < byName.length; i++) {
            console.log(byName[i].value); // btn2,btn3
        }
    
        // 3. 通過標簽名獲取元素,返回值是個對象集合
        let byTagName = document.getElementsByTagName("input");
        for (let i = 0; i < byTagName.length; i++) {
            console.log(byTagName[i].value); // btn1,btn2,btn3
        }
    
        // 4. 通過class獲取元素,返回值是個對象集合
        let byClassName = document.getElementsByClassName("div_01");
        console.log(byClassName); // HTMLCollection(1) [div.div_01]
    
        // 5. 通過選擇器獲取元素
        let btn4 = document.querySelector("btn4");
        alert("我是通過選擇器獲取的");
    
        // 6. 通過選擇器獲取元素集合
        let collection = document.querySelectorAll("input");
        for (let i = 0; i < collection.length; i++) {
            console.log(collection[i].value); // btn1,btn2,btn3,btn4
        }
    </script>

    <div id="div_02"></div>
    
        2. 創建
             1. 創建元素節點
             2. 創建文本節點
             3. 創建屬性節點
             4. 創建注釋節點
             5. 創建文檔片段
    
    <script>
        /**
         *  1. 創建元素節點
         */
        // 1. 創建新節點
        let hr = document.createElement("hr");
        
        // 2. 將新節點添加到父節點中
        let div_02 = document.getElementById("div_02");
        div_02.appendChild(hr);
    
    
        /**
         *  2. 創建文本節點
         */
        // 1. 創建元素節點
        let p = document.createElement("p");
        
        // 2. 創建文本節點
        let content = document.createTextNode("這是創建的文本節點");
        
        // 3. 將文本節點添加到元素節點中
        p.appendChild(content);
        
        // 4. 將元素節點添加到父節點中
        div_02.appendChild(p);
        
        
        /**
         *  3. 創建屬性節點
         */
        // 1. 創建元素節點
        let img = document.createElement("img");
        
        // 2. 創建屬性節點
        let src = document.createAttribute("src");
        
        // 3. 設置屬性值
        src.nodeValue = "../images/a.jpg";
        
        // 4. 將屬性節點添加到元素節點上
        img.setAttributeNode(src);
        
        // 5. 將元素節點添加到父節點中
        div_02.appendChild(img);
         
        
        /**
         *  4. 創建注釋節點
         */
         // 1. 創建注釋節點
         let comment = document.createComment("這是一張圖片");
         
         // 2. 將注釋節點添加到元素節點上
         img.appendChild(comment);
         
         
         /**
          *  5. 創建文檔片段
          */
          // 1. 創建文檔片段
          let df = document.createDocumentFragment();
          // 2. 添加元素
          let a = document.createElement("a");
          let href = document.createAttribute("href");
          href.nodeValue = "https://www.cnblogs.com.mh20131118";
          a.setAttributeNode(href);
          div_02.appendChild(a);
    </script>

    <!-- 
         3. 操作css
     -->
    <div id="div1" class="div_01"></div>
    <script>
        // 1. 通過"."直接操作樣式
        let div1 = document.getElementById("div1");
        div1.style.width = "100px";
        div1.style.height = "100px";
        div1.style.backgroundColor = "gray";
    
        // 2. 通過setAttribute()方法
        div1.setAttribute("style", "width: 100px;height: 100px; background-color: gray");
    
        // 3. 通過style對象的cssText屬性 
        div1.style.cssText = "border: 10px solid black";
        
        // 4. 通過className屬性
        let div_01 = document.getElementsByClassName("div_01");
        div_01.className = "div_02";
    </script>
</body>
</html>
Document對象的方法代碼實現

 

              三:元素節點(Element對象)

                             element的屬性和方法

<!DOCTYPE html>
<html>
  <head>
     <title>Element的方法</title>
     <meta charset="UTF-8" />
  </head>

<body>
    <!-- 
         1.屬性
     -->
    <div id="div_01">
        <input type="button" value="點我測試" id="btn1" />
        <p id="a"></p>
        <p id="b"></p>
        <p id="c"></p>
        <p id="d"></p>
        <div id="div1" class="d">
            <p id="one"></p>
            <p id="two"></p>
        </div>
    </div>
    <script>
    
        /**
             *  1. innerHTML和innerText用法及區別
             *       innerHTML:獲取或設置指定元素標簽內的 html內容,html標簽起作用
             *            1.獲取元素內容:element.innerHTML;
             *            2.設置元素內容:element.innerHTML =htmlString;
             *             
             *       innerText:獲取或設置指定元素標簽內的文本值,html標簽不起作用
             *            1.獲取元素內容:element.innerText;
             *            2.設置元素內容:element.innerText =String;
         */
    
        // 1. 獲取指定標簽內容
        document.write(document.getElementById("a").innerHTML);
    
        // 2. 設置指定標簽內容
        document.write(document.getElementById("b").innerHTML = "<b>你<b/>");
    
        // 3. 獲取標簽文本值
        document.write(document.getElementById("c").innerText);
    
        // 4. 設置指定標簽內容
        document.write(document.getElementById("d").innerText = "<i>美<i/>");
    
    
        /**
         *  2. 節點屬性
         */
        let div_01 = document.getElementById("div_01");
    
        // 1. 返回當前元素節點的子節點的個數 
        console.log(div_01.childElementCount);
    
        // 2. 返回當前元素節點的第一個元素子節點
        console.log(div_01.firstElementChild);
    
        // 3. 返回當前元素節點的最后一個元素節點
        console.log(div_01.lastElementChild);
    
        // 4. 返回當前元素的下一個兄弟元素
        let one = document.getElementById("one");
        console.log(one.nextElementSibling);
    
        // 5. 返回當前元素的上一個兄弟元素
        let two = document.getElementById("two");
        console.log(two.previousElementSibling);
    
        // 6. 返回當前元素節點的所有子節點
        let div1 = document.getElementById("div1").children;
        for (let i in div1) {
            console.log(div1[i]);
        }
    
        // 7. 返回所有子節點集合
        for (let i in div1.childNodes) {
            console.log(div_01[i]);
        }
    
        // 8. 返回當前元素節點的所有屬性節點
        let btn1 = document.getElementById("btn1").attributes;
        for (let i in btn1) {
            console.log(btn1[i]);
        }
    
        // 9. 返回元素的class屬性
        document.write("第一種獲取方式:" + div1.className + "<br />");
        document.write("第二種獲取方式:" + document.getElementsByTagName("div")[1].className + "<br />");
    </script>


    <!-- 
         2. 方法
     -->
    <div id="div_01">
        <input type="button" value="點我" id="btn1" />
        <input type="button" value="點我" id="btn2" />
    </div>
    <script>
        let div_01 = document.getElementById("div_01");
        /**
         *  1. 添加
         */
    
        // 1. 追加插入節點
        let content = document.createTextNode("我是追加插入的節點");
        div_01.appendChild(content);
    
        // 2. 在指定位置插入節點
        let hr = document.createElement("hr");
        div_01.insertBefore(hr, content);
    
        // 3. 替換節點
        let h3 = document.createElement("h3");
        let text = document.createTextNode("我是文章的標題");
        h3.appendChild(text);
        div_01.replaceChild(h3, content);
    
    
        /**
         *  2. 刪除
         */
        // 1. 刪除元素節點:父節點刪除子節點
        div_01.removeChild(hr);
    
        // 2. 刪除屬性節點:元素節點刪除屬性
        let btn1 = document.getElementById("btn2");
        btn1.removeAttribute("value");
    
        // 3. 刪除文本節點
        div_01.removeChild(div_01.childNodes[0]); // 只能獲取第一個子節點
        div_01.innerHTML = ""; // 會刪除子節點
        div_01.innerHTML = "這是文本";
    
    
        /**
         *  3. 判斷
         */
    
        // 1. 判斷兩個元素是否相等
        let btn2 = document.getElementById("btn2");
        console.log(btn1.isEqualNode(btn2)); // false
    
        // 2. 判斷兩個元素是否為相同節點
        console.log(btn1.isSameNode(btn2)); // false
    
        // 3. 判斷該節點是否存在子節點
        console.log(div_01.hasChildNodes()); // true
    
        // 4. 判斷一個節點是否包含指定節點
        console.log(div_01.contains(h3)); // false
    </script>

    <!-- 
         3. 尺寸
     -->
    <div class="div_03">
        <div id="div1">
            <div id="div2"></div>
        </div>
    </div>
    <style>
         #div2{
            width: 120px;
            height: 120px;
            border: 10px solid black;
            padding: 20px;
            background-color: blue;
        }
    
        #div1{
            width: 300px;
            height: 300px;
            padding: 20px;
            border: 10px solid black;
            margin: 20px;
            background-color: gray;
            position: absolute;
            left: 50px;
            top: 50px;
        }
        
        .div_03{
            width: 500px;
            height: 500px;
            background-color: orange;
        }
    </style>
    <script>
        let div_03 = document.getElementsByClassName("div_03");
        let div1 = document.getElementById("div1");
        let div2 = document.getElementById("div2");
        
        // 1. 返回元素節點的內部高度,包括padding 
        console.log(div1.clientHeight + "px"); // 240px
        
        // 2. 返回元素節點的內部寬度,包括padding
        console.log(div1.clientWidth + "px"); // 240px
        
        // 3. 返回元素節點的左邊框的寬度
        console.log(div1.clientLeft + "px"); // 10p 
        
        // 4. 返回元素節點的頂部邊框的寬度
        console.log(div1.clientTop + "px"); // 10px
        
        // 5. 返回元素節點的布局寬度,包括padding,border,滾動條
        console.log(div2.offsetWidth + "px"); // 180px
        
        // 6. 返回元素節點的布局高度,包括padding,border,滾動條
        console.log(div2.offsetHeight + "px"); // 180px
       
        /**
         *  offsetParent: 
         *    1. 當父元素都不沒有使用絕對定位時,元素的距離就是相對於body
         *    2. 當父元素使用絕對定位時,元素的距離就是距離父元素
         */
        function offsetLeft(element){
            let left = element.offsetLeft; // 得到第一層距離
            let parent = element.offsetParent; // 得到第一個父元素
            while (parent !== null) { // 如果還有上一層父元素
                left += parent.offsetLeft; // 把本層的距離累加
                parent = parent.offsetParent; // 得到本層的父元素
            } //然后繼續循環
            return left + "px";
        }
        
        // 8. 返回當前元素節點相對於offsetParent節點的寬度
        console.log(div2.offsetLeft +"px"); // 20px -- 300-padding+border+margin+left
        console.log(offsetLeft(div2)); // 90px -- padding+border+margin+left
        
        // 9. 返回當前元素節點相對於offsetParent節點的高度
        console.log(div2.offsetTop + "px"); // 20px
    </script>
</body>
</html>
Element對象的屬性和方法代碼實現

 

               四:屬性節點(Attr對象)

                            Attr的屬性和方法

<!DOCTYPE html>
<html>
  <head>
    <title>Attr對象</title>
    <meta charset="utf-8" />
  </head>

  </head>
  
  <body>
      <div id="div1">
          <input type="button" id="btn1" value="測試" />
      </div>
      <script>
           let btn1 = document.getElementById("btn1");
           let div1 = document.getElementById("div1");
           
           // 1. 獲取屬性值
           console.log(btn1.getAttribute("type")); // button
           
           // 2. 獲取屬性節點
           console.log(btn1.getAttributeNode("value")); // value="點我測試"
           
           // 3. 設置屬性值
           btn1.setAttribute("value", "點我測試");
           
           // 4. 設置屬性節點
           let name = document.createAttribute("name");
           name.nodeValue = "uname";
           btn1.setAttributeNode(name);
           
           // 5. 刪除屬性節點
           console.log(btn1.removeAttribute("name"));
           
           // 6. 判斷是否存在指定屬性
           console.log(btn1.hasAttribute("value")); // true
           
           // 7. 判斷是否有屬性
           console.log(btn1.hasAttributes()); // true
           
      </script>
  </body>
</html>
Attr對象的方法代碼實現

 

                 五:文本節點(Text)

                             Text類型的屬性和方法

                 

 

        三:事件

               一:概述

                         事件一般是用於瀏覽器和用戶操作進行交互,當用戶執行某些操作的時候才會執行特定的代碼,例如單擊圖片等

 

                 二:事件流

                        1. 概述:事件發生時會在元素節點與根節點之間按照特定的順序傳播,路徑所經過的所有節點都會收到該事件,這個傳播過程即DOM事件流

                                 事件流圖

 

                        2. 捕獲階段

                                捕獲階段處於事件流的第一階段,開始於Document,結束於目標階段,主要作用是捕獲截取事件。

<!DOCTYPE html>
<html>
  <head>
    <title>事件流.html</title>
    <meta charset="UTF-8">
  </head>
  
  <body>
      <div id="div1">
          <div id="div2">
              <div id="div3">點我試試</div>
          </div>
      </div>
      <style>
          #div1{
              width: 500px;
              height: 500px;
              background-color: orange;
          }
          #div2{
              width: 300px;
              height: 300px;
              background-color: gray;
              position: absolute;
              top: 100px;
              left: 100px;
          }
          #div3{
              width: 100px;
              height: 100px;
              background-color: blue;
              position: absolute;
              top: 100px;
              left: 100px;;
              text-align: center;
          }
      </style>
      <script>
          /**
           *  1. 捕獲階段:從根元素一直執行到目標元素
           */
          var div3 = document.getElementById("div3");
          div3.addEventListener("click", function () {
              alert("藍色盒子在捕獲階段被觸發");
          }, true); // true為捕獲階段執行,false為冒泡階段執行
          
          var div2 = document.getElementById("div2");
          div2.addEventListener("click", function () {
              alert("灰色盒子在捕獲階段被觸發");
          }, true);
          
          var div1= document.getElementById("div1");
          div1.addEventListener("click", function () {
              alert("橙色盒子在捕獲階段被觸發");
          }, true);
      </script>
  </body>
</html>
   
捕獲階段代碼實現

 

                        3. 目標階段

                                目標階段處於事件流的第二階段,具有雙重范圍,即捕獲階段的結束,冒泡階段的開始,主要作用是執行綁定事件。

 

                        4. 冒泡階段

                                冒泡階段處於事件流的第三階段,開始於目標元素,結束於Document,主要作用是將目標元素綁定事件執行的結果返回給瀏覽器,

                                處理不同瀏覽器之間的差異。

<!DOCTYPE html>
<html>
  <head>
    <title>事件流.html</title>
    <meta charset="UTF-8">
  </head>
  
  <body>
      <div id="div1">
          <div id="div2">
              <div id="div3">點我試試</div>
          </div>
      </div>
      <style>
          #div1{
              width: 500px;
              height: 500px;
              background-color: orange;
          }
          #div2{
              width: 300px;
              height: 300px;
              background-color: gray;
              position: absolute;
              top: 100px;
              left: 100px;
          }
          #div3{
              width: 100px;
              height: 100px;
              background-color: blue;
              position: absolute;
              top: 100px;
              left: 100px;;
              text-align: center;
          }
      </style>
      <script>
          /**
           *  2.冒泡階段:從目標元素一直執行到根元素
           */
           var div3 = document.getElementById("div3");
           div3.onclick= function () {
               alert("我是藍色盒子");
           };
           
           var div2 = document.getElementById("div2");
           div2.onclick=function(){
               alert("我是灰色盒子");
           }
           
           var div1= document.getElementById("div1");
           div1.onclick= function () {
               alert("我是橙色盒子");
           }
         </script>
  </body>
</html>
冒泡階段代碼實現

 

                 三:事件處理程序

                        1. HTML事件處理程序

                              1. 優點:事件處理程序中的代碼,能夠訪問全局作用域中的任何變量

                              2. 缺點:時差問題、擴展的作用域鏈在不同瀏覽器中會導致不同結果、html代碼與js代碼高度耦合

 

                        2. DOM0級事件處理程序

                              1. 優點:簡單和瀏覽器兼容性好,解決了html代碼和js代碼的高度耦合

                              2. 缺點:一個元素只能綁定一個事件處理函數,只會在事件冒泡中運行

 

                        3. DOM2級事件處理程序   

                              1. 優點:同時支持事件處理的捕獲和冒泡階段,並且一個元素可以綁定多個處理函數

                              2. 缺點:IE不支持

 

                        4. 跨瀏覽器處理程序

                              1. 優點:繼承了DOM2級事件處理程序的優點,並且可以解決其缺點

<!DOCTYPE html>
<html>
  <head>
     <title>鼠標鍵盤事件</title>
     <meta charset="UTF-8">
  </head>

<body>
    <!-- 
          1. HTML事件處理程序
       -->
    <button onclick="test1()">測試1</button>
    <script>
        function test1() {
            alert("HTML事件處理程序");
        }
    </script>

    <!-- 
           2. DOM0級事件處理程序
       -->
    <button id="btn1">測試2</button>
    <script>
        var btn1 = document.getElementById("btn1");
        btn1.onclick = function test1() {
            alert("DOM0級事件處理程序");
        }
    </script>

    <!-- 
           3. DOM2級事件處理程序
       -->
    <button id="btn2">測試3</button>
    <script>
        var btn2 = document.getElementById("btn2");
    
        // 1. 添加事件:第一個參數是事件類型,第三個參數為true表示在捕獲階段執行,false表示在冒泡階段執行
        btn2.addEventListener("click", function() {
            alert("DOM2級事件處理程序,我在捕獲階段執行");
        }, true);
    
        btn2.addEventListener("click", function() {
            alert("DOM2級事件處理程序,我在冒泡階段執行");
        }, false);
    
        // 2. 移除事件:function必須是同一個
        var fun = function() {
            alert("我要被移除了");
        }
        btn2.addEventListener("click", fun, false);
        btn2.removeEventListener("click", fun, false);
    </script>


    <!-- 
        4. 跨瀏覽器事件處理程序
     -->
    <button id="btn3">測試4</button>
    <script>
        // 封裝
        var EventUtil = {
            // 1. 添加事件
            addEvent : function(element, type, fn) { // DOM2級事件處理程序
                if (element.addEventListener) {
                    element.addEventListener(type, fn, false);
                } else if (element.attachEvent) { // IE事件處理程序
                    element.attachEvent("on" + type, fn);
                } else {
                    element["on" + type] = fn;
                }
            },
    
            // 2. 移除事件
            removeEvent : function(element, type, fn) { // DOM2級事件處理程序
                if (element.removeEventListener) {
                    element.removeEventListener(type, fn, false);
                } else if (element.detachEvent) { // IE事件處理程序
                    element.detachEvent("on" + type, fn);
                } else {
                    element["on" + type] = null;
                }
            }
        };
    
        // 2. 測試
        var btn3 = document.getElementById("btn3");
        var func = function() {
            alert("我馬上被移除了");
            EventUtil.removeEvent(btn3, "click", func);
        };
        EventUtil.addEvent(btn3, "click", func);
    </script>
</body>
</html>
事件處理程序代碼實現

 

                 四:事件處理函數

                        1. 鼠標鍵盤事件

                                 鼠標鍵盤事件        

 

<!DOCTYPE html>
<html>
<head>
   <title>鼠標鍵盤事件</title>
   <meta charset="UTF-8">
</head>
<body>
     <!-- 
          1. 鼠標事件
      -->
    <button id="btn1">測試1</button>
    <button id="btn2">測試2</button>
    <button id="btn3">測試3</button>
    <button id="btn4">測試4</button>
    <button id="btn5">測試5</button>
    <button id="btn6">測試6</button>
    <button id="btn7">測試7</button>
    <script>
        // 1. 鼠標單擊事件
        var btn1 = document.getElementById("btn1");
        btn1.onclick = function() {
            alert("我是鼠標單擊事件--IE支持我哦");
        }
        btn1.addEventListener("click", function() {
            alert("我也是鼠標單擊事件--IE不支持我")
        }, false);
        
        // 2. 鼠標雙擊事件
        var btn2 = document.getElementById("btn2");
        btn2.ondblclick = function() {
            alert("我是鼠標雙擊事件--IE支持我哦");
        }
        btn2.addEventListener("dblclick", function() {
            alert("我也是鼠標雙擊事件--IE不支持我")
        }, false);
        
        // 3. 鼠標按下事件
        var btn3 = document.getElementById("btn3");
        btn3.onmousedown = function() {
            alert("我是鼠標按下事件--IE支持我哦");
        }
        btn3.addEventListener("mousedown", function() {
            alert("我也是鼠標按下事件--IE不支持我")
        }, false);
        
        // 4. 鼠標松開事件
        var btn4 = document.getElementById("btn4");
        btn4.onmouseup = function() {
            alert("我是鼠標松開事件--IE支持我哦");
        }
        btn4.addEventListener("mouseup", function() {
            alert("我也是鼠標松開事件--IE不支持我")
        }, false);
        
        // 5. 鼠標移動事件
        var btn5 = document.getElementById("btn5");
        btn5.onmousemove = function() {
            alert("我是鼠標移動事件--IE支持我哦");
        }
        btn5.addEventListener("mousemove", function() {
            alert("我也是鼠標移動事件--IE不支持我")
        }, false);
        
        // 6. 鼠標移動到元素上事件
        var btn6 = document.getElementById("btn6");
        btn6.onmouseover = function() {
            alert("我是鼠標移動到元素上事件--IE支持我哦");
        }
        btn6.addEventListener("mouseover", function() {
            alert("我也是鼠標移動到元素上事件--IE不支持我")
        }, false);
        
        // 7. 鼠標離開某元素事件
        var btn7 = document.getElementById("btn7");
        btn7.onmouseout = function() {
            alert("我是鼠標離開某元素事件--IE支持我哦");
        }
        btn7.addEventListener("mouseout", function() {
            alert("我也是鼠標離開某元素事件--IE不支持我")
        }, false);
    </script>

    <!-- 
          2. 鍵盤事件
     -->
    <button id="btn8">測試8</button>
    <button id="btn9">測試9</button>
    <button id="btn10">測試10</button>
    <script> 
        // 1. 按下鍵盤按鍵事件
        var btn8 = document.getElementById("btn8");
        btn8.onkeydown = function() {
            alert("我是按下鍵盤按鍵事件--IE支持我哦");
        }
        btn8.addEventListener("keydowm", function() {
            alert("我也是按下鍵盤按鍵事件--IE不支持我")
        }, false); 
        
        // 2. 釋放鍵盤按鍵事件
        var btn9 = document.getElementById("btn9");
        btn9.onkeyup = function() {
            alert("我是釋放鍵盤按鍵事件--IE支持我哦");
        }
        btn9.addEventListener("keyup", function() {
            alert("我也是釋放鍵盤按鍵事件--IE不支持我")
        }, false); 
        
        // 3. 按下字母鍵事件
        var btn10 = document.getElementById("btn10");
        btn10.onkeypress = function() {
            alert("我是按下字母鍵事件--IE支持我哦");
        }
        btn10.addEventListener("keypress", function() {
            alert("我也是按下字母鍵事件--IE不支持我")
        }, false); 
    </script>
</body>
</html>
鼠標鍵盤事件代碼實現

 

                        2. 頁面窗口事件

                                 頁面窗口事件

<!DOCTYPE html>
<html>
<head>
    <title>頁面窗口事件</title>
    <meta charset="UTF-8">
</head>
<body>
    <script>
        // 1. 頁面加載完成時觸發此事件
        window.onload = function() {
            alert("頁面加載完成時觸發的事件");
        };
    
        // 2. 頁面完全卸載時觸發此事件
        window.onunload = function() {
            alert("頁面完全卸載時觸發的事件");
        };
    
        // 3. 瀏覽器窗口大小被改變時觸發此事件
        window.onresize = function() {
            alert("瀏覽器窗口大小被改變時觸發的事件");
        };
    
        // 4. 瀏覽器的滾動條位置發生變化時觸發此事件
        window.onscroll = function() {
            alert("瀏覽器的滾動條位置發生變化時觸發此事件");
        };
    </script>
</body>
</html>
頁面窗口事件代碼實現

 

                        3. 表單事件

                                      表單事件

<!DOCTYPE html>
<html>
<head>
     <title>表單事件</title>
     <meta charset="UTF-8">
</head>
<body>
    用戶名:
    <input type="text" name="uname" id="btn1" />
    <br />
    密碼:
    <input type="password" name="pwd" id="btn2" />
    <br />
    <input type="submit" value="確認" />
    <script>
        // 1. 獲得焦點
        var btn1 = document.getElementById("btn1");
        btn1.onfocus = function() {
            alert("獲得焦點");
        };
        
        // 2. 失去焦點
        btn1.onblur = function() {
            alert("失去焦點");
        };
    
        // 3. 元素內容發生改變時
        var btn2 = document.getElementById("btn2");
        btn2.onchange = function() {
            alert("內容被改變");
        }
    
        // 4. 內容被重置時
        var form = document.getElementsByTagName('form');
        form.onreset = function() {
            alert("內容本重置了");
        };
        
        // 5. 表單被提交
        form.onsubmit = function() {
            alert("表單被提交");
        };
    </script>
</body>
</html>
表單事件代碼實現

 

四、JavaScript BOM

        一:簡介

               一:概念:瀏覽器對象模型(Browser Object Model,簡稱BOM)描述與瀏覽器進行交互的方法口,和網頁內容無關

                 二:作用:管理窗口和窗口之間的通訊

                 三:結構圖

                       BOM結構圖

 

        二:window對象

                一:概述

                           BOM的核心對象就是windowwindow對象也是BOM的頂級對象,所有瀏覽器都支持window對象,它代表的是瀏覽器的窗口。JavaScript的所有全局對象、

                           全局方法和全局變量全都自動被歸為window對象的方法和屬性,在調用這些方法和屬性的時候可以省略window

 

                 二:屬性和方法

                            window對象的屬性和方法

<!DOCTYPE html>
<html>
<head>
<title>window對象的屬性和方法</title>
<meta charset="UTF-8">
</head>
<body>
    <script>
    /**
     *  1. 屬性
     */
    
        // 1. 頁面視圖區域
        console.log("高:" + window.innerHeight + ";寬:" + window.innerWidth); // 高:720;寬:1536
    
        // 2. 窗口大小
        console.log("高:" + window.outerHeight + ";寬:" + window.outerWidth); // 高:824;寬:1536
    
        // 3. 窗口位置
        console.log("距左邊:" + window.screenLeft + ";距上邊:" + window.screenTop); // 距左邊:0;距上邊:0
    
        /**
         *  2. 方法
         */
    
        // 1. 打開一個新窗口
        var wor = window.open("http://www.cnblogs.com/mh20131118", "_blank");
    
        // 2. 超時調用
        var s1 = setTimeout(function() {
            alert("我是超時調用");
        }, 10000);
        clearTimeout(s1);
    
        // 3. 間歇調用
        var num = 0;
        var max = 10;
        var intervalId = null;
        function incrementNumber() {
            num++;
            //如果執行次數達到了max設定的值,則取消后續尚未執行的調用
            if (num == max) {
                clearInterval(intervalId);
                alert("Done");
            }
        }
        intervalId = setInterval(incrementNumber, 500);
    </script>
</body>
</html>
window對象的屬性和方法代碼實現

 

   

     三:其他對象

            一:frames                    

                          如果頁面包含框架,則每個框架都有自己的window對象,並且保存frames集合中,可以通過數值索引或框架名稱來訪問相應的window對象

 

            二:history

                      history對象保存着用戶上網的歷史記錄,從窗口被打開的一刻算起

                          back( ):加載 history 對象列表中的前一個URL

                          forward( ):加載 history 對象列表中的下一個URL

            三:location

                      location對象提供了與當前窗口加載的文檔有關的信息,還提供了一些導航功能

                          replace()方法:用戶不能回到前一個頁面

                          reload()方法:重新加載當前顯示的頁面

            四:screen

                     screen對象基本上只用來表明客戶端的能力,其中包括瀏覽器窗口外部的顯示器的信息,如像素寬度和高度等

 

            五:navigator

                     navigator屬性通常用於檢測顯示網頁的瀏覽器類型。可以使用plugins數組檢測瀏覽器是否安裝了特定的插件

                            plugins數組的屬性:

                               name:插件名字              

                               description:插件的描述

                               filename:插件的文件名    

                               length:插件所處理的MIME類型數量

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM