0

0

你值得了解的JavaScript“继承之jquery”使用方法(代码详解)

奋力向前

奋力向前

发布时间:2021-08-19 11:49:36

|

2473人浏览过

|

来源于禅境花园

转载

之前的文章《深入解析JS中数组reduce方法(附代码)》中,给大家了解一下JS中数组reduce方法。下面本篇文章给大家了解一下JS-继承之jquery使用方法,小伙伴们可以参考一下。

你值得了解的JavaScript“继承之jquery”使用方法(代码详解)

jquery截止到当前已经 3.3.1 版本了,如今随着各种浏览器的盛行,前端的框架层出不穷,jquery独步天下,老夫写代码只用jquery,拿起代码就是干的辉煌时代已经过去了。

2006 年,jQuery的第一个版本的面世,凭借着简洁、灵活的编程风格受到了开发者的喜爱。而它本身是一个JavaScript框架,它的设计的宗旨是“write LessDo More”,即倡导写更少的代码,做更多的事情。它封装了JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。

从之前的风靡到如今的被抛弃,究其原因,不少前端工程师表示,对于jQuery来说,大量的操作DOM虽然方便,但是会牺牲很多页面的性能。另一方面,现阶段ReactVueAngularjs等主流前端框架并不依赖jQuery,都可以独立使用。况且浏览器的兼容问题越来越少,当浏览器兼容不再是问题时,jQuery的价值就大打折扣了

就在微软收购github的 52 天,github改变也已经放弃了jquery,奇替代方案使用了原生的 js

立即学习Java免费学习笔记(深入)”;

  • 使用querySelectorAll来查询DOM节点;

  • 使用fetch来代替ajax

  • 事件处理使用了事件代理;

  • 使用DOM标准化写了polyfill

  • 使用了自定义元素。

微信截图_20210819112650.jpg

假如不用,学习下还是可以的

本文粗燥的实现jqueryready、each、bind、``$.fn.extend、$.extend

初始化$

(function (win) {
  var _$ = function (selector, context) {
    /**
     * 通常咱们定义一个 函数 var Fun = function(){}
     * 然后定义一个 Fun.prototype.init = function(){}
     * 那么咱们调用init 的时候 得先要实例化对象 var f = new Fun()
     * 然后f.init()
     * 这里就省去了 var $ = new $()
     */
    return new _$.prototype.Init(selector, context);
  };
  _$.prototype = {
    //初始化$
    Init: function (selector, context) {
      this.elements = [];
      /**
       * 传入的类型是function 就执行ready事件,如果是document 就将document对象插入到this.elements
       * 主要就是判断$(document).ready  和 $(function(){}) 这两种的ready事件的写法
       */
      if (typeof selector === "function") {
        this.elements.push(document);
        this.ready(selector);
      } else {
        var context = context || document;
        var isDocument = (ele) =>
          Object.prototype.toString.call(ele) == "[object HTMLDocument]" ||
          "[object Document]";
        if (isDocument(selector)) {
          this.elements.push(selector);
        } else {
          /**
           * 如果是字符串的话就查询该节点 $('.class') | $('#id')
           */
          if (context.querySelectorAll) {
            var arr = context.querySelectorAll(selector);
            for (var i = 0; i < arr.length; i++) {
              this.elements.push(arr[i]);
            }
          }
        }
      }
    },
    //实现each
    each: function (callback) {},
    //实现ready
    ready: function (callback) {},
    //实现bind
    bind: function (type, callback) {},
  };
  /**
   * 让两个作用域不一样的对象共享一个方法,让他们的原型指向一致,即Init.prototype = _$.prototype
   * 那么原型一致之后 就可以共享this.elements 属性了。
   */
  _$.prototype.Init.prototype = _$.prototype;
  window.$ = _$;
})(window || global);

ready

//实现ready
ready: function (callback) {
  var isDocument = (ele) => Object.prototype.toString.call(ele) == '[object HTMLDocument]' || '[object Document]'
  //如果已经取得了节点
  if (isDocument(this.elements[0])) {
    if (document.addEventListener) { //判断火狐、谷歌
      /**
       * DOM树构建完成的时候就会执行DOMContentLoaded
       * 页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,才会触发window.onload
       * 这也就是$(document).ready() 比 window.onload 执行早的原因
       *
       * arguments.callee 博客里面有一篇文章 [js-递归] 里面专门讲到了,这里不再解释了
       */
      document.addEventListener('DOMContentLoaded', function () {
        document.removeEventListener('DOMContentLoaded', arguments.callee, false)
        callback()
      }, false)
    } else if (document.attachEvent) { //判断IE
      document.attachEvent('onreadystatechange', function () {
        if (document.readyState == 'complete') {
          document.detachEvent('onreadystatechange', arguments.callee);
          callback()
        }
      })
    } else if (document.lastChild == document.body) { //body已经加载完了,就直接回调了
      callback()
    }
  }
},

each

//实现each
 each: function (callback) {
    if (this.elements.length > 0) {
        for (var i = 0; i < this.elements.length; i++) {
        callback.call(this, this.elements[i], i);
        }
    }
 },

bind

百度AI搜
百度AI搜

百度全新AI搜索引擎

下载
//实现bind
bind: function (type, callback) {
  if (document.addEventListener) { //判断火狐、谷歌
    this.each(function (item, i) {
        item.addEventListener(type, callback, false)
    })
    } else if (document.attachEvent) { //判断IE
    this.each(function (item, i) {
        item.attachEvent('on' + type, callback)
    })
    } else {
    this.each(function (item, i) { //其他浏览器 egg: item.onclick = function(){}
        item['on' + type] = callback
    })
  }
}

$.fn.extend/$.extend

$.fn.extend是为查询的节点对象扩展方法,是基于$的原型扩展的方法

$.extend是扩展常规方法,是$的静态方法

官方给出解释:

jQuery.extend(): Merge the contents of two or more objects together into the first object.(把两个或者更多的对象合并到第一个当中)

jQuery.fn.extend():Merge the contents of an object onto the jQuery prototype to provide new jQuery instance methods.(把对象挂载到jQueryprototype属性,来扩展一个新的jQuery实例方法)

$.fn.extend方法的初衷是我们扩展之后可以用$("").newMetod()这样访问,实际上就是给$原型加一个extend方法。这中间的fn其实类似于命名空间的作用,没什么实际的意义。为的是和$.extend作区分

$.fn.extend

; (function (win) {
  ...
  _$.prototype.Init.prototype = _$.prototype;

   _$.fn = _$.prototype; //把对象挂载到jQuery的prototype属性

  var isObj = (o) => Object.prototype.toString().call(o) === '[object Object]';
  $.fn.extend = function (obj) {
    if (isObj(obj)) {
      for (var i in obj) {
        this[i] = obj  //注意这里的this指向是 $.prototype
      }
    }
  }

$.extend

var isObj = (o) => Object.prototype.toString().call(o) === '[object Object]';
...
_$.extend = function (obj) {
    if (isObj(obj)) {
        for (var i in obj) {
            this[i] = obj[i]; //注意这里的this指向是 $
        }
    }
}

这俩看上去一模一样啊,没啥区别,注释里面已经说了,this指向不同。咱们来看个例子:

<!DOCTYPE html>
<html>
  <head>
    <title>jQuery.extend()与jQuery.fn.extend()区别</title>
    <meta charset="utf-8" />
    <script type="text/javascript" src="jquery.js"></script>
    <!-- 开始扩展 -->
    <script type="text/javascript">
      (function ($) {
        $.extend({
          sayHello: function () {
            console.log("Hello");
          },
        });
        $.fn.extend({
          sayHello: function () {
            console.log("Hello");
          },
        });
      })(jQuery);
    </script>
    <!-- 调用 -->
    <script type="text/javascript">
      $(document).ready(function () {
        //$.extend扩展调用
        $.sayHello();

        //$.fn.extend扩展调用
        $("#test").sayHello();
      });
    </script>
  </head>
  <body>
    <div id="test"></div>
  </body>
</html>

这样以来就看的很明白了。jQuery.extend(object); 为扩展jQuery类本身,为自身添加新的方法。$.xxx()

jQuery.fn.extend(object);jQuery对象添加方法$('#test').xxx()

$.extend常见用法

//在jquery全局对象中扩展一个net命名空间。
$.extend({ net: {} });

//方法扩展到之前扩展的Jquery的net命名空间中去。
$.extend($.net, {
  sayHello: function () {
    console.log("Hello");
  },
});

//extend方法还有一个重载原型
//extend(boolean,dest,src1,src2,src3...),第一个参数boolean代表是否进行深度拷贝
var a = { protocol: "http", hash: { a: 1, b: 2 } };
var b = { host: "chuchur.com", hash: { b: 1, c: 2 } };

var result = $.extend(true, {}, a, b);
console.log(result); //{ protocol: 'http',host: 'chuchur.com', hash: { a: 1, b: 1,c:2 } }

var result = $.extend(false, {}, a, b);
console.log(result); //{ protocol: 'http',host: 'chuchur.com', hash: { b: 1, c:2 } }

完整代码

(function (win) {
  var _$ = function (selector, context) {
    /**
     * 通常咱们定义一个 函数 var Fun = function(){}
     * 然后定义一个 Fun.prototype.init = function(){}
     * 那么咱们调用init 的时候 得先要实例化对象 var f = new Fun()
     * 然后f.init()
     * 这里就省去了 var $ = new $()
     */
    return new _$.prototype.Init(selector, context);
  };
  _$.prototype = {
    //初始化$
    Init: function (selector, context) {
      this.elements = [];
      /**
       * 传入的类型是function 就执行ready事件,如果是document 就将document对象插入到this.elements
       * 主要就是判断$(document).ready  和 $(function(){}) 这两种的ready事件的写法
       */
      if (typeof selector === "function") {
        this.elements.push(document);
        this.ready(selector);
      } else {
        var context = context || document;
        var isDocument = (ele) =>
          Object.prototype.toString.call(ele) == "[object HTMLDocument]" ||
          "[object Document]";
        if (isDocument(selector)) {
          this.elements.push(selector);
        } else {
          /**
           * 如果是字符串的话就查询该节点 $('.class') | $('#id')
           */
          if (context.querySelectorAll) {
            var arr = context.querySelectorAll(selector);
            for (var i = 0; i < arr.length; i++) {
              this.elements.push(arr[i]);
            }
          }
        }
      }
    },
    //实现each
    each: function (callback) {
      if (this.elements.length > 0) {
        for (var i = 0; i < this.elements.length; i++) {
          callback.call(this, this.elements[i], i);
        }
      }
    },
    //实现ready
    ready: function (callback) {
      var isDocument = (ele) =>
        Object.prototype.toString.call(ele) == "[object HTMLDocument]" ||
        "[object Document]";
      //如果已经取得了节点
      if (isDocument(this.elements[0])) {
        if (document.addEventListener) {
          //判断火狐、谷歌
          /**
           * DOM树构建完成的时候就会执行DOMContentLoaded
           * 页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,才会触发window.onload
           * 这也就是$(document).ready() 比 window.onload 执行早的原因
           *
           * arguments.callee 博客里面有一篇文章 js-递归里面专门讲到了,这里不再解释了
           */
          document.addEventListener(
            "DOMContentLoaded",
            function () {
              document.removeEventListener(
                "DOMContentLoaded",
                arguments.callee,
                false
              );
              callback();
            },
            false
          );
        } else if (document.attachEvent) {
          //判断IE
          document.attachEvent("onreadystatechange", function () {
            if (document.readyState == "complete") {
              document.detachEvent("onreadystatechange", arguments.callee);
              callback();
            }
          });
        } else if (document.lastChild == document.body) {
          //body已经加载完了,就直接回调了
          callback();
        }
      }
    },
    //实现bind
    bind: function (type, callback) {
      if (document.addEventListener) {
        //判断火狐、谷歌
        this.each(function (item, i) {
          item.addEventListener(type, callback, false);
        });
      } else if (document.attachEvent) {
        //判断IE
        this.each(function (item, i) {
          item.attachEvent("on" + type, callback);
        });
      } else {
        this.each(function (item, i) {
          //其他浏览器 egg: item.onclick = function(){}
          item["on" + type] = callback;
        });
      }
    },
  };
  /**
   * 让两个作用于不一样的对象共享一个方法,让他们的原型指向一直,即Init.prototype = _$.prototype
   * 那么指向之后 就可以共享this.elements 属性了。
   */
  _$.prototype.Init.prototype = _$.prototype;

  var isObj = (o) => Object.prototype.toString().call(o) === "[object Object]";
  $.fn.extend = function (obj) {
    if (isObj(obj)) {
      for (var i in obj) {
        this[i] = obj; //注意这里的this指向是 $.prototype
      }
    }
    //....这里是简写
  };

  _$.extend = function (obj) {
    if (isObj(obj)) {
      for (var i in obj) {
        this[i] = obj[i]; //注意这里的this指向是 $
      }
    }
    //....这里是简写
  };

  window.$ = _$;
})(window || global);

【完】

推荐学习:jQuery视频教程

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

89

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

276

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

59

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

99

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

105

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

230

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

619

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

173

2026.03.04

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 10.3万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号