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);