簡化版本身實現jQuery、this、arguments、閉包、原型鏈

簡化版本身實現jQuery

1. == 與===

儘可能不要用 == 規則太複雜
ChUuAf.pnghtml

用===只須要注意兩點,1.NaN===NaN,false,2.全部對象===也都是false,由於地址不同.
ChUM4S.pngnode

2.本身寫jQuery與用jQuery

Ch7FXj.png

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jQuery-Study</title>
    <script src="01_myjQuery1.js"></script>
    <script src="jQuery3.3.1min.js"></script>
    <style>
        .red{
            color: red;
        }
        .blue{
            color: blue;
        }
        .big{
            font-size: larger;
        }
        .green{
            color: green;
        }
        .pink{
            color: pink;
        }
    </style>
</head>
<body>
<!--ul>li[id=item$]{這是li$}*8-->
<ul>
    <li id="item1">這是li1</li>
    <li id="item2">這是li2</li>
    <li id="item3">這是li3</li>
    <li id="item4" class="xxx">這是li4</li>
    <li id="item5">這是li5</li>
    <li id="item6">這是li6</li>
    <li id="item7">這是li7</li>
    <li id="item8">這是li8</li>
</ul>

<button id="x">x</button>
<ol id="ol2">
    <li id="i1">1</li>
    <li id="i2">2</li>
    <li id="i3">3</li>
    <li id="i4">4</li>
    <li id="i5">5</li>
</ol>
</body>
<script>
    console.log('直接使用');
    console.log(getSiblings(item1));

    console.log('直接使用');
    addClass(item2,{a:true,xxx:false,c:true});
    console.log(item2);
</script>
<script src="UseJquery.js"></script>
</html>

01_myjQuery1.jsjquery

// 獲得兄妹結點
//傳入的參數是一個節點,返回兄妹結點的數組
function getSiblings(node) {
    var allSilings = node.parentNode.children;
    var siblingsArray = {length:0};
    for (let i = 0; i < allSilings.length; i++) {
        if (allSilings[i]!==node){
            siblingsArray[siblingsArray.length] = allSilings[i];
            siblingsArray.length++;
        }
    }
    return siblingsArray;
}
//添加或刪除class
//傳入的第一個參數是結點,第二個參數是對象, 這個對象裏是key:value,key就是要操做的class,value判斷操做類型,true添加,false刪除
function addClass(node,object){
    for (let key in object){
        //對象調用方法的兩種方式:
        // obj.f()
        // obj['f']()

        var methodName;

        methodName = object[key] ? 'add':'remove';
        node.classList[methodName](key);

        /*上面兩句代碼至關於
        if (object[key]) {
            node.classList.add(key);
        }else {
            node.classList.remove(key);
        }*/
    }
}
window.mydom = {};
mydom.getSiblings = getSiblings;
mydom.addClass = addClass;//命名空間,經常使用的設計或者組合就叫作設計模式.哈希,數組,都是一種設計模式
//因此jQuery就是這樣來的,jQuery就是一個命名空間,裏面有不少函數.

// 命名空間做用:1.方便識別庫,2.若是都放在window裏,可能會覆蓋別的庫,因此命名空間是爲了防止覆蓋別的函數

window.onload = function () {
// 測試


    // 如何直接使用item3.addclass()?,item3.getSiblings()?
    // 方法一:給原型鏈加公有屬性公有方法,可是有缺點,容易覆蓋
    Node.prototype.getSiblings = function () {
        var allSilings = this.parentNode.children;//誰調用這個函數,this就是誰
        var siblingsArray = {length:0};
        for (let i = 0; i < allSilings.length; i++) {
            if (allSilings[i]!==this){
                siblingsArray[siblingsArray.length] = allSilings[i];
                siblingsArray.length++;
            }
        }
        return siblingsArray;
    }
    let item3 = document.getElementById('item3');
    // console.log(item3.getSiblings.call(item3));若是用cal.第一個參數就是函數裏的this,若是不用call(),那麼this就自動變成了item3
    console.log(' 方法一:');
    console.log(item3.getSiblings());//測試成功

    Node.prototype.addClass = function (object) {
        for (let key in object){
            var methodName;
            methodName = object[key] ? 'add':'remove';
            this.classList[methodName](key);
        }
    }
    // item3.addClass.call(item3,{a:true,xxx:false,c:true});;若是用call.第一個參數就是函數裏的this,若是不用call(),那麼this就自動變成了item3
    console.log(' 方法一:');
    item3.addClass.call(item3,{a:true,xxx:false,c:true});
    // item3.addClass({a:true,xxx:false,c:true});
    console.log(item3);//測試成功


    // 如何直接使用item3.addclass()?,item3.getSiblings()?
    // 方法二:由於方法一在原型中添加函數容易覆蓋,因此本身作一個相似的Node出來
    var Node2 = function (node) {// 將要操做的結點傳進去,而後返回一個對象,這個對象裏給添加了有操做這個節點方法,因此對象.方法就能夠實現操做了,而不須要mydom.addclass(item3,...)這樣了
        return{
            getSiblings: function () {
                var allSilings = node.parentNode.children;
                var siblingsArray = {length:0};
                for (let i = 0; i < allSilings.length; i++) {
                    if (allSilings[i]!==node){
                        siblingsArray[siblingsArray.length] = allSilings[i];
                        siblingsArray.length++;
                    }
                }
                return siblingsArray;
            },
            addClass:function (object) {
                for (let key in object){

                    var methodName;

                    methodName = object[key] ? 'add':'remove';
                    node.classList[methodName](key);

                }
            }
        }
    }
    let item4 = document.getElementById('item4');

    var item4obj = Node2(item4);

    console.log(' 方法二:');
    console.log(item4obj.getSiblings());//測試成功

    console.log(' 方法二:');
    item4obj.addClass({a:true,xxx:false,c:true});
    console.log(item4);//測試成功

    // 改成jQuery
    var jQuery = function (nodeOrSelector) {//將Node2改成jQuery,jQuery能夠根據選擇器去找到對應的元素
        var node;
        if(typeof nodeOrSelector==="string"){
            node = document.querySelector(nodeOrSelector);
        }else {
            node = nodeOrSelector;
        }
        return{
            getSiblings: function () {
                var allSilings = node.parentNode.children;
                var siblingsArray = {length:0};
                for (let i = 0; i < allSilings.length; i++) {
                    if (allSilings[i]!==node){
                        siblingsArray[siblingsArray.length] = allSilings[i];
                        siblingsArray.length++;
                    }
                }
                return siblingsArray;
            },
            addClass:function (object) {
                for (let key in object){

                    var methodName;

                    methodName = object[key] ? 'add':'remove';
                    node.classList[methodName](key);

                }
            }
        }
    }
    let item5 = document.getElementById('item5');

    var $item5 = jQuery(item5);
    console.log(' 改成jQuery方法:');
    console.log($item5.getSiblings());

    console.log(' 改成jQuery方法:');
    $item5.addClass({red:true,xxx:false,c:true});
    console.log(item5);//測試成功
     var child3 = jQuery('ul>li:nth-child(3)');
     child3.addClass({blue:true});


     // jQuery操做多個節點
    var jQueryS = function (nodeOrSelector) {
        var node = {};
        if (typeof nodeOrSelector ==='string'){
            var temp = document.querySelectorAll(nodeOrSelector);//先用querySelectorAll獲取這個僞數組
            for (let i = 0; i < temp.length; i++) {
                node[i] = temp[i];
            }
            node.length = temp.length;//將僞數組淨化,淨化成只有0123值和length的僞數組

        } else if(nodeOrSelector instanceof Node){// 若是是node,也將其轉化成僞數組
            node[0] =nodeOrSelector;
            node.length = 1;
        }
        node.getSiblings = function () {

        };
        node.addClass = function (classesArray) {//傳入class數組,給選擇的多個節點都加上數組中class
            classesArray.forEach(value=>{
                for (let i = 0; i < node.length; i++) {
                    node[i].classList.add(value);
                }
            })
        }
        node.getTexts = function () {
            var texts=[];
            for (let i = 0; i < node.length; i++) {
                texts.push(node[i].textContent);
            }
            return texts;
        }
        node.setTexts = function (text) {
            for (let i = 0; i < node.length; i++) {
                node[i].textContent = text;
            }
        }

        //set和get合併
        node.text = function (text) {
            if (text===undefined){
                var texts=[];
                for (let i = 0; i < node.length; i++) {
                    texts.push(node[i].textContent);
                }
                return texts;
            }else{
                for (let i = 0; i < node.length; i++) {
                    node[i].textContent = text;
                }
            }
        }
        return node;
    }

    var allNodes = jQueryS('ul>li:nth-child(even)');//偶數孩子
    allNodes.addClass(['big','green']);
    console.log(allNodes.getTexts());
    console.log(allNodes.text());
    // console.log(allNodes.text(1));//測試成功

    //總結:jQuery的做用就是將選擇其選擇的元素放到一個對象裏,這個對象裏有01234標序,表明每個選擇的元素,有length表明全部元素加起來總共的長度,有各類方法,addclass,gettext等等.就是反悔了這樣一個hash
};

UseJquery.jsajax

var $nodes  = $('ul>li:nth-child(even)');//注意$nodesjQuery聲明的變量前面要加一個$,防止混淆,由於jQuery聲明的變量只能用jQuery的api,不能用dom的api.
console.log($nodes);
x.onclick = function () {
    $nodes.toggleClass('pink');//toggle,開關,切換
    // console.log(1);
}

var colorArray = ['blue','yellow','red','pink','big']
var $nodes2 = $('#ol2>li');
$nodes2.addClass(function (index,currentClass) {
    return colorArray[index];//ol裏面的每個li加了'blue','yellow','red','pink','big'這幾個屬性
})
//https://www.jquery123.com/addClass/

3.thisarguments

f.call(asThis, input1,input2)

其中 asThis 會被當作 this,[input1,input2] 會被當作 arguments
禁止使用 f(input1, input2),由於學會 .call 才能理解 this設計模式

thisargumentsapi

function f(){
    'use strict'
    console.log(this)
    console.log(arguments)
    return undefined
}
f.call(1,2,3) // this 爲 1,arguments 爲 [2,3]

this 的值究竟是什麼?一次說清楚---方應杭
this定義:this是call的第一個參數.
this定義:this是call的第一個參數.
this定義:this是call的第一個參數.
「每日一題」JS中的閉包是什麼?---方應杭數組

關於原型鏈:
「每日一題」什麼是 JS原型鏈?---方應杭閉包

JavaScript 世界萬物誕生記dom

ChN7kT.png
dom就是一個命名的空間,命名的所屬對象
函數庫:特定種類的API
jQueryMobil已通過時,不要學函數

jQuery的原型

測試代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js"></script>
    <script>
        console.log($.prototype)
        console.log($.prototype.__proto__)
        console.log($.prototype.__proto__ === Object.prototype)//繼承自Object
    </script>
</head>
<body>
    
</body>
</html>

結果以下:
CXIos1.png

CXo8W4.png
就像Boolea,Array同樣,
他的原型就是jQuery.prototype

總結:本身實現jquery例子

var myjQueryS = function(node){
    var Node = {}
    Node.length = 0
    if((typeof node)==='string'){
        var nodearr  = document.querySelectorAll(node)
        for (let index = 0; index < nodearr.length; index++) {
            let element = nodearr[index];
            Node[index] = element
            Node.length++
        }
    }else{
        Node['0'] = node
        Node.length++
    }
    Node.addClass = function(addclass){
        for (let index = 0; index < Node.length; index++) {
            let element = Node[index]
            element.classList.add(addclass)
        }
    }
    Node.text = function(text){
        
        if(text===undefined){
            let textArr = []
            for (let index = 0; index < Node.length; index++) {
                let element = Node[index]
                textArr.push(element.textContent)
            }
            return textArr
        }else{
            for (let index = 0; index < Node.length; index++) {
                let element = Node[index]
                element.textContent = text
            }
        }
    }
    return Node
}
var $div = myjQueryS('div')
console.log($div)
$div.addClass('xxx')
console.log($div.text())
// $div.text('xxx')
相關文章
相關標籤/搜索