欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > 15-JS封装:入口函数

15-JS封装:入口函数

2024/10/24 1:54:11 来源:https://blog.csdn.net/m0_68467925/article/details/139843029  浏览:    关键词:15-JS封装:入口函数

目录

1 模块化的基本结构

2 编写封装里的jQuery函数

2.1 对象本身上添加css方法

 2.2 对象原型上添加css方法

2.3 自定义构造函数 

2.4 优化1-伪数组

2.5 优化2-原型链

 2.6 简化代码


需求:给页面中所有的div设置字体颜色为红色

jQuery封装:$("div").css("color","red")

如果没有引入jQuery,该如何编写?

1 模块化的基本结构

要封装的这个库应该是一个独立的单元:模块化

独立:

  1. 不依赖任何其他第三方库
  2. 里面的东西大部分也是与世隔绝的,只有:$、jQuery

模块化的基本结构

    (function (global) {function jQuery() {}//global.$ = global.jQuery = jQuery;//相当于:global.jQuery = jQuery;global.$ = jQuery;})(window)

1) 传入window,global接收window,即global保存了window对象的引用

2)在global(相当于window)里添加一个方法jQuery,并将模块化里的jQuery函数将其赋值

3)在global(相当于window)里添加一个方法$,并将模块化里的jQuery函数将其赋值

2 编写封装里的jQuery函数

2.1 对象本身上添加css方法

步骤:

1、获取页面中所有的元素
2、把这个元素放在一个特定的对象中

观察$("div").css("color","red")所得:

直接在jQuery函数里elementsc添上css方法

(function(global){function jQuery(selector){const elements = document.getElementsByTagName(selector);elements.css=()=>{}return elements;}window.$ = window.jQuery = jQuery;})(window)$("div").css()$("p")$("span")$("img")$("input")

 问题:随着$()操作频次的增加,会产生无数个相同的css方法,造成内存浪费

 2.2 对象原型上添加css方法

放在对象本身上会造成浪费,则我们优化成:放在对象的原型上 

(function(global){function jQuery(selector){const elements = document.getElementsByTagName(selector);return elements;}HTMLCollection.prototype.css=()=>{console.log('css方法');}window.$ = window.jQuery = jQuery;})(window)$("div").css()

这种解决方案,把DOM操作的方法都放在了原型中,这样看似可以正常访问,但是依然存在问题:破坏了原生的对象结构

2.3 自定义构造函数 

自定义构造函数 F,在F的原型上添加css方法

<body><div>aaa</div><div>bbb</div><div>ccc</div><span class="header">123</span><input type="text" id="inputId">
</body>
<script>//给页面中所有的div设置字体颜色为红色//$("div").css("color","red")(function(global){function jQuery(selector){return new F(selector);}//jquery对象的构造函数function F(selector){//jquery内部封装了一个Sizzle引擎来获取DOM元素const elements = document.querySelectorAll(selector) //把DOM元素放到这个对象中this.elements = elements; //为了让这些元素可以在css方法中进行访问,所以需要把这些元素放在对象上面进行传递}F.prototype.css=function(name,value){for(let i = 0;i<this.elements.length;i++){let element = this.elements[i];element.style[name]=value;}}window.$ = window.jQuery = jQuery;})(window)$("div").css("color","red")$(".header").css("backgroundColor","pink")$("#inputId").css("backgroundColor","black")
</script>

2.4 优化1-伪数组

    jquery为了后续的DOM操作的方便,将这些获取到的DOM元素全部放在了对象自己身上,让自己变成了一个就像数组一样,可以使用for循环进行遍历,我们把这种对象特性称之为【伪数组】

(function(global){function jQuery(selector){return new F(selector);}function F(selector){//把DOM元素放到这个对象中const elements = document.querySelectorAll(selector)//实现把这些所有DOM元素都添加到对象自己身上for(let i = 0;i<elements.length;i++){//ele:DOM元素this[i] = elements[i];}this.length=elements.length;}F.prototype = {constructor:F,//此时的css方法还是雏形,后续完善css(name,value){for(let i = 0;i<this.length;i++){let element = this[i];element.style[name]=value;}}}window.$ = window.jQuery = jQuery;})(window)$("div").css("color","red")$(".header").css("backgroundColor","pink")$("#inputId").css("backgroundColor","black")//实现的结果:没次需要new一个对象,但是对象的方法是共用的var $1=$("div");var $2=$("div");console.log($1 == $2); //2个对象,falseconsole.log($1.css == $2.css); //同一个方法,true

优化前

 

优化后

jquery对象不可能相同,后续,内存优化介绍如何适当地解决这种jquery对象消耗的内存

2.5 优化2-原型链

1、jQuery函数里返回的是构造函数(jQuery原型里的init函数)

2、jQuery原型里有的css函数

3、jQuery.prototype.init(selector)只能访问本身及其原型里的内容(原型:构造函数.prototype)

4、所以 jQuery.prototype.init.prototype = jQuery.prototype;

<script>(function(global){function jQuery(selector){var _init=jQuery.prototype.init;return new _init(selector);//等价于://return new jQuery.prototype.init(selector);}jQuery.prototype = {constructor:jQuery,init:function(selector){const elements = document.querySelectorAll(selector)for(let i = 0;i<elements.length;i++){this[i] = elements[i];}this.length=elements.length;},css(name,value){for(let i = 0;i<this.length;i++){let element = this[i];element.style[name]=value;}}}//此时创建的jquery是init构造函数的实例//css方法在jquery.prototype对象中//-->为了让jquery对象可以访问到css方法//  -->让init的原型继承自jQuery.prototypejQuery.prototype.init.prototype = jQuery.prototype;//-->1、创建了一个init的对象//-->2、执行css方法//  -->找对象本身有没有css方法,并没有//  -->找对象的原型:init.prototype -->jquery.prototype//  -->发现jquery.prototype中有一个css方法window.$ = window.jQuery = jQuery;})(window)$("div").css("color","red")$(".header").css("backgroundColor","pink")$("#inputId").css("backgroundColor","black")var $1=$("div");var $2=$("div");console.log($1 == $2); //2个对象,falseconsole.log($1.css == $2.css); //同一个方法,true</script>
 2.6 简化代码

1、考虑到需要经常访问jQuery.prototype

2、给jQuery添加了一个fn属性,fn属性等价于prototype属性

3、访问jQuery.fn相当于访问jQuery.prototype

(function(global){function jQuery(selector){return new jQuery.fn.init(selector);}//给jquery添加了一个fn属性,fn属性等价于prototype属性jQuery.fn = jQuery.prototype = {constructor:jQuery,init:function(selector){const elements = document.querySelectorAll(selector)for(let i = 0;i<elements.length;i++){this[i] = elements[i];}this.length=elements.length;},css(name,value){for(let i = 0;i<this.length;i++){let element = this[i];element.style[name]=value;}}}jQuery.fn.init.prototype = jQuery.fn;window.$ = window.jQuery = jQuery;})(window)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com