jQuery原理-入口函数

jQuery基本结构

(function( window, undefined ) {
    var jQuery = function( ) {
        return new jQuery.prototype.init( );
    }
    jQuery.prototype = {
        constructor: jQuery
    }
    jQuery.prototype.init.prototype = jQuery.prototype;
    window.jQuery = window.$ = jQuery;
})( window );
  1. jQuery本质是一个闭包:防止与其他框架产生冲突

  2. jQuery让外界访问内部局部变量方法

    window.jQuery = window.$ = jQuery;
    //将jQuery方法放在window上
    
  3. jQuery window参数的含义和作用

    • 为了以后方便压缩代码
    • 提高查找效率:在内部就可以查找到window
  4. jQuery undefined参数的含义和作用

    • 为了以后方便压缩代码
    • 旧版本的浏览器(IE9一下)undefined可以被赋值,为了保证内部的undefined不被污染,所以需要正确接收一个undefined

入口函数测试

  • 传入 ‘’ null undefined NaN 0 false :返回一个空的jQuery对象
console.log($());
console.log($(''));
console.log($(null));
console.log($(undefined));
console.log($(NaN));
console.log($(0));
console.log($(false));

  • 传入HTML代码片段 :会将DOM元素创建好并存储到jQuery对象中返回
console.log($('<p>1</p><p>2</p><p>3</p>'));
//创建三个p元素

  • 传入选择器 : 将找到的所有元素存储到jQuery对象中返回
console.log($('p'));

  • 传入数组 : 将数组中存储的元素依次存储到jQuery对象中返回
let arr = [1, 2, 3, 4, 5, 6];
console.log($(arr));

  • 传入伪数组 :将数组中存储的元素依次存储到jQuery对象中返回
let likeArr = {0:"lnj", 1:"33", 2:"male", length: 3};
console.log($(likeArr));

  • 传入对象 : 将传入的对象存储到jQuery对象中返回
function Person() {}
console.log($(new Person()));

  • 传入DOM元素:将传入的DOM元素存储到jQuery对象中返回
console.log($(document.createElement('div')));

  • 传入基本数据类型:将传入的基本数据类型存储到jQuery对象中返回
console.log($(123));

入口函数代码实现

(function (window, undefined) {
	let jQuery = function(selector){
		return new jQuery.prototype.init(selector)
	}
	
	jQuery.prototype = {
		constructor : jQuery,
		init : function (selector) {

		   // trim -> 去除字符串两端的空格
			selector = jQuery.trim(selector)

			//
			 if(!selector){
				 return this
			 }
			 // 方法处理
			 else if(jQuery.isFunction(selector)){
				 jQuery.ready(selector)
			 }			 
			 // 字符串处理
			 else if(jQuery.isString(selector)){
				 // 判断是否为代码片段
				 if(jQuery.isHTML(selector)){
					 let temp = document.createElement("div");
					 temp.innerHTML =  selector
					 // this指向的不是数组 是 jQuery对象
					 [].push.apply(this,temp.children);
				 }
				 // 判断传入是个为选择器
				 else{
					 // 利用querySelectorAll方法找到对应元素
					 let res = document.querySelectorAll(selector);
					 // 将找到的元素添加到jQuery上
					 [].push(this,res)
				 }
			 }
			 // 判断是否为数组
			 else if(jQuery.isArray(selector)){
				 //真数组
				 // if(({}).toString.apply(selector) === "[object Array]"){
					//  [].push.apply(this, selector)
					//  return this;
				 // } 
				 // 伪数组
				 // else{
					//  // 将自定义的伪数组转换为真数组
					//  let arr = [].slice.call(selector);
					//  // 将真数组转换为伪数组
					//  [].push.apply(this, arr);
					//  return this;
				 // }
				 
				 // 统一方法
				 let arr = [].slice.call(selector);
				 [].push.apply(this, arr);
			 }
			 // 其他类型
			 else{
				 this[0] = selector;
				 this.lenght = 1;
				 
			 }
			 // 统一返回
			 return this;
			 
		}
	}
	
	jQuery.extend = jQuery.prototype.extend = function (obj) {
		for(let key in obj){
			this[key] = obj[key]
			// this[key] -> 将键名传入给jQuery对象
			// obj[key] -> 获取对应键的值
		}
	}
	jQuery.extend({
		// 判断传入是否为字符串
		isString : function(str){
			return typeof str === "string"
		},
		// 判断传入是否为代码片段
		isHTML : function (str) {
			return str.charAt(0) == "<" &&
			str.charAt(str.length - 1) == ">" &&
			str.length >= 3
		},
		trim : function (str) {
			// 如果不是字符串 直接返回
			if(!jQuery.isString(str)){
				return str
			}
			// 判断是否支持trim方法
			if(str.trim){
				return str.trim()
			}else{
				// 兼容IE方法
				return str.replace(/^\s+|\s+$/g, "")
			}
		},
		// 判断传入是否为对象
		isObject : function (obj) {
			return typeof obj === "object"
		},
		// 判断传入是否为window
		isWindow : function (w) {
			return typeof w === window
		},
		// 数组判断
		isArray : function (sele) {
			// 是对象 不能是window 必须带有 length属性
			if(jQuery.isObject(sele) &&
			!jQuery.isWindow(sele) &&
			"length" in sele) {
				return true;
			}
			return false
		},
		// 判断是否为函数
		isFunction : function (sele) {
			return typeof sele === "function";
		},
		ready : function (fn) {
			// 判断DOM是否加载完毕
			if(document.readyState === "complete"){
				fn()
			}else if(document.addEventListener){
				// 判断是否支持 addEventListener方法
				document.addEventListener("DOMContentLoaded", function () {
				    fn();
				});
			}else{
				document.attachEvent("onreadystatechange", function () {
				    if(document.readyState == "complete"){
				       fn();
				    }
				});
			}
		}
	});
	jQuery.prototype.init.prototype = jQuery.prototype;
	window.jQuery = window.$ = jQuery;
})(window)


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值