jQuery原理
jQuery的基本結構
-
jQuery的本質是一個閉包
-
jQuery爲什麼要使用閉包來實現?
爲了避免多個框架的衝突
- jQuery如何讓外界訪問內部定義的局部變量
window.xxx = xxx
- jQuery爲什麼要給在自己傳遞一個window參數?
爲了方便後期壓縮代碼
爲了提升查找的效率
- jQuery爲什麼要給自己接收一個undefined參數?
爲了方便後期壓縮代碼
IE9以下的瀏覽器undefined可以被修改,爲了保證內部使用的undefined不被修改,所以需要接收一個正確的undefined
jQuery的基本結構如下:
(function (window, undefined) {
var jQuery = function () {
return new jQuery.prototype.init();
};
jQuery.prototype = {
constructor: jQuery,
init: function () {}
};
jQuery.prototype.init.prototype = jQuery.prototype;
window.jQuery = window.$ = jQuery;
})(window);
jQuery入口函數測試
- 傳入 ‘’ null undefined NaN 0 false
會返回一個空的jQuery對象給我們
- 傳入html片段
會將創建好的DOM元素存儲到jQuery對象中返回
- 傳入選擇器
會將找到的所有元素存儲到jQuery對象中返回
- 傳入數組
會將數組中存儲的元素依次存儲到jQuery對象中立返回
- 傳入僞數組
會將數組中存儲的元素依次存儲到jQuery對象中立返回
- 傳入對象
會將傳入的對象存儲到jQuery對象中返回
- 傳入DOM元素
會將傳入的DOM元素存儲到jQuery對象中返回
- 傳入基本數據類型
會將傳入的基本數據類型存儲到jQuery對象中返回
apply和call方法
function test() {
console.log(this);
}
var obj = { name: "lnj2" };
/*
1. 通過window.test找到test方法
2. 通過apply(obj)將找到的test方法內部的this修改爲自定義的對象
*/
// window.test.apply(obj);
// window.test.call(obj);
function sum(a, b) {
console.log(this);
console.log(a + b);
}
// window.sum.call(obj, 1, 2);
/*
1. 通過window.sum找到sum方法
2. 通過apply(obj)將找到的sum方法內部的this修改爲自定義對象
3. 將傳入數組中的元素依次取出,傳遞給形參
*/
// window.sum.apply(obj, [3, 5]);
// 真數組轉換僞數組的一個過程
var arr = [1, 3, 5, 7, 9];
var obj = {};
/*
1. 通過[].push找到數組中的push方法
2. 通過apply(obj)將找到的push方法內部的this修改爲自定義的對象
3. 將傳入數組中的元素一次取出,傳遞給形參
*/
// [].push.apply(obj, arr);
// console.log(obj);
window.onload = function (ev) {
// 系統自帶的僞數組
var res = document.querySelectorAll("div");
// 自定義的僞數組
var obj = { 0: "lnj", 1: "33", length: 2 };
var arr = []; // 真數組
// [].push.apply(arr, res);
// [].push.apply(arr, obj);
// console.log(arr);
// 如果想將僞數組轉化爲真數組那麼可以使用如下方法
var arr = [].slice.call(obj);
console.log(arr);
};
記錄一下今天所寫的代碼:
/*
* @Author: 碼小余
* @Date: 2020-06-23 09:26:25
* @LastEditTime: 2020-06-23 12:42:16
* @FilePath: \代碼\jQuery原理\js\njQuery-1.0.0.js
*/
(function (window, undefined) {
function njQuery(selector) {
return new njQuery.prototype.init(selector);
}
njQuery.prototype = {
constructor: njQuery,
init: function (selector) {
/*
1.傳入 '' null undefined NaN 0 false, 返回空的jQuery對象
2.字符串:
代碼片段:會將創建好的DOM元素存儲到jQuery對象中返回
選擇器: 會將找到的所有元素存儲到jQuery對象中返回
3.數組:
會將數組中存儲的元素依次存儲到jQuery對象中立返回
4.除上述類型以外的:
會將傳入的數據存儲到jQuery對象中返回
*/
// 0. 去除字符串兩端的空格
selector = njQuery.trim(selector);
// 1.傳入 '' null undefined NaN 0 false, 返回空的jQuery對象
if (!selector) {
return this;
}
// 2. 字符串
else if (njQuery.isString(selector)) {
// 2.1. 判斷是否是代碼片段
if (njQuery.isHTML(selector)) {
// 1. 根據代碼片段創建所有的元素
var temp = document.createElement("div");
temp.innerHTML = selector;
// // 2. 將創建好定得一級元素添加到jQuery當中
// for (var i = 0; i < temp.children.length; i++) {
// this[i] = temp.children[i];
// }
// // 3. 給jQuery對象添加length屬性
// this.length = temp.children.length;
[].push.apply(this, temp.children);
// 4. 返回加工好的this(jQuery)
return this;
}
// 2.2 判斷是否是選擇器
else {
// 1. 根據傳入的選擇器找到對應的元素
var res = document.querySelectorAll(selector);
// // 2. 將找到的元素添加到njQuey上
// for (var i = 0; i < res.length; i++) {
// this[i] = res[i];
// }
// this.length = res.length;
[].push.apply(this, res);
// 3. 返回加工好的this
return this;
}
}
},
};
njQuery.isString = function (str) {
return typeof str === "string";
};
njQuery.isHTML = function (str) {
return (
str.charAt(0) == "<" &&
str.charAt(str.length - 1) == ">" &&
str.length >= 3
);
};
njQuery.trim = function (str) {
// 判斷是否支持trim方法
if (str.trim) {
return str.trim();
} else {
return str.replace(/^\s+|\s+$/g, "");
}
};
njQuery.prototype.init.prototype = njQuery.prototype;
window.njQuery = window.$ = njQuery;
})(window);