热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[路飞]每日一答:如何利用闭包和立即执行函数实现类库的封装?

[路飞]每日一答:如何利用闭包和立即执行函数实现类库的封装?-highlight:ascetictheme:channing-cyan如何利用闭包和立即执行函数实现类库的封装

highlight: ascetic
theme: channing-cyan

如何利用闭包和立即执行函数实现类库的封装

封装类库的特点

类库是我们在开发中经常用到的,但是在使用的时候我们很少会考虑他是如何设计的,如何实现封装的。

首先我们要了解类库的特点是什么。类库最基础的要求就是高复用性和低耦合性。这就引申出类库实际上不仅要求脱离业务更要求他有自己的作用域和命名空间。那么利用闭包和立即执行函数就可以做到这一点。

比较一下

第一种写法:

var name = 'defaultName' // 变量 name
function Person () {
  this.name = name // 属性 name 默认为变量 name
}

const p = new Person()
console.log(p) // Person {name: "detaultName"}

这么写功能上固然是没有问题的,我们可以看到返回了一个默认值为 defaultNameperson对象
。但是,如果你尝试去打印 this.name 或者 window.name :

console.log(this.name) // defaultName
console.log(window.name) // defaultName

不难发现,我们全局作用域下的 name属性也受到了影响。

第二种写法

const Person = (function () {
  var name = 'defaultName' // 变量 name
  const Person = function () {
    this.name = name // 属性 name 默认为变量 name
  }
  return Person
})()

const p = new Person()
console.log(p) // Person {name: "detaultName"}
console.log(this.name) // ''
console.log(window.name) // ''

采用了闭包和立即执行函数的形式,为类库的实现创建了单独的作用空间,最终返回一个对象或一个方法的形式。这样一来,类库下的作用域以及变量就不会对全局造成影响,也不会受到命名的限制。

典型案例

大名鼎鼎 jQuery 架构:

;(function(global, factory) { 
    factory(global); 
}(typeof window !== "undefined" ? window : this, function(window, noGlobal) { 
    var jQuery = function( selector, context ) { 
        return new jQuery.fn.init( selector, context ); 
    }; 
    jQuery.fn = jQuery.prototype = {}; 
    // 核心方法 
    // 回调系统 
    // 异步队列 
    // 数据缓存 
    // 队列操作 
    // 选择器引 
    // 属性操作 
    // 节点遍历 
    // 文档处理 
    // 样式操作 
    // 属性操作 
    // 事件体系 
    // AJAX交互 
    // 动画引擎 
    return jQuery; 
})); 

尝试去分解一下。首先是一个自执行函数:

function(global, factory) { factory(global); }

它包含了两个入参,第一个是挂载对象(默认全局),第二个是工厂方法。那么这个自执行对象的传参分别是

typeof window !== "undefined" ? window : this

以及下面的整段方法了

function(window, noGlobal) { 
    var jQuery = function( selector, context ) { 
        return new jQuery.fn.init( selector, context ); 
    }; 
    jQuery.fn = jQuery.prototype = {}; 
    // 核心方法 
    // 回调系统 
    // 异步队列 
    // 数据缓存 
    // 队列操作 
    // 选择器引 
    // 属性操作 
    // 节点遍历 
    // 文档处理 
    // 样式操作 
    // 属性操作 
    // 事件体系 
    // AJAX交互 
    // 动画引擎 
    return jQuery; 
}

如果我们不使用立即执行函数去实现就应该会变成这样:

var window = typeof window !== "undefined" ? window : this
function(window) { 
    var jQuery = function( selector, context ) { 
        return new jQuery.fn.init( selector, context ); 
    }; 
    jQuery.fn = jQuery.prototype = {}; 
    // 核心方法 
    // 回调系统 
    // 异步队列 
    // 数据缓存 
    // 队列操作 
    // 选择器引 
    // 属性操作 
    // 节点遍历 
    // 文档处理 
    // 样式操作 
    // 属性操作 
    // 事件体系 
    // AJAX交互 
    // 动画引擎 
    return jQuery; 
}

由于自身的入参本身就是全局对象window,这种写法可能也不会对全局造成什么影响,但是也太不优雅了。


推荐阅读
  • 在深入研究 React 项目的过程中,特别是在探索 react-router 源码时,我发现了其中蕴含的中间件概念。这激发了我对中间件的进一步思考与整理。本文将详细探讨 Redux 中间件的原理及其在实际项目中的应用,帮助读者更好地理解和使用这一强大工具。通过具体示例和代码解析,我们将揭示中间件如何提升应用的状态管理和异步操作处理能力。 ... [详细]
  • Vue 实战基础教程第9讲:深入理解计算属性与侦听器的高效使用
    Vue 实战基础教程第9讲:深入理解计算属性与侦听器的高效使用 ... [详细]
  • 深入解析 Vue3 中的响应式 API:shallowReactive、shallowRef、triggerRef 和 customRef 的使用与原理
    深入解析 Vue3 中的响应式 API:shallowReactive、shallowRef、triggerRef 和 customRef 的使用与原理 ... [详细]
  • 本文详细探讨了Zebra路由软件中的线程机制及其实际应用。通过对Zebra线程模型的深入分析,揭示了其在高效处理网络路由任务中的关键作用。文章还介绍了线程同步与通信机制,以及如何通过优化线程管理提升系统性能。此外,结合具体应用场景,展示了Zebra线程机制在复杂网络环境下的优势和灵活性。 ... [详细]
  • 本文详细介绍了 jQuery 的入门知识与实战应用,首先讲解了如何引入 jQuery 库及入口函数的使用方法,为初学者提供了清晰的操作指南。此外,还深入探讨了 jQuery 在实际项目中的多种应用场景,包括 DOM 操作、事件处理和 AJAX 请求等,帮助读者全面掌握 jQuery 的核心功能与技巧。 ... [详细]
  • 在关系型数据库中,数据约束是指在向数据表中插入数据时必须遵循的限制条件。在MySQL和MariaDB中,常见的数据约束包括主键约束、唯一键约束、外键约束以及非空约束等。这些约束确保了数据的完整性和一致性,是数据库管理中的重要组成部分。通过合理设置和使用这些约束,可以有效防止数据冗余和错误,提升数据库的可靠性和性能。 ... [详细]
  • 本文详细探讨了使用纯JavaScript开发经典贪吃蛇游戏的技术细节和实现方法。通过具体的代码示例,深入解析了游戏逻辑、动画效果及用户交互的实现过程,为开发者提供了宝贵的参考和实践经验。 ... [详细]
  • 在 Linux 环境下,多线程编程是实现高效并发处理的重要技术。本文通过具体的实战案例,详细分析了多线程编程的关键技术和常见问题。文章首先介绍了多线程的基本概念和创建方法,然后通过实例代码展示了如何使用 pthreads 库进行线程同步和通信。此外,还探讨了多线程程序中的性能优化技巧和调试方法,为开发者提供了宝贵的实践经验。 ... [详细]
  • 在深入研究 UniApp 封装请求时,发现其请求 API 方法中使用了 `then` 和 `catch` 函数。通过详细分析,了解到这些函数是 Promise 对象的核心组成部分。Promise 是一种用于处理异步操作的结果的标准化方式,它提供了一种更清晰、更可控的方法来管理复杂的异步流程。本文将详细介绍 Promise 的基本概念、结构和常见应用场景,帮助开发者更好地理解和使用这一强大的工具。 ... [详细]
  • 本文深入探讨了JavaScript中`this`关键字的多种使用方法和技巧。首先,分析了`this`作为全局变量时的行为;接着,讨论了其在对象方法调用中的表现;然后,介绍了`this`在构造函数中的作用;最后,详细解释了通过`apply`等方法改变`this`指向的机制。文章旨在帮助开发者更好地理解和应用`this`关键字,提高代码的灵活性和可维护性。 ... [详细]
  • 微信小程序实现类似微博的无限回复功能,内置云开发数据库支持
    本文详细介绍了如何利用微信小程序实现类似于微博的无限回复功能,并充分利用了微信云开发的数据库支持。文中不仅提供了关键代码片段,还包含了完整的页面代码,方便开发者按需使用。此外,HTML页面中包含了一些示例图片,开发者可以根据个人喜好进行替换。文章还将展示详细的数据库结构设计,帮助读者更好地理解和实现这一功能。 ... [详细]
  • 在Kohana 3框架中,实现最优的即时消息显示方法是许多开发者关注的问题。本文将探讨如何高效、优雅地展示flash消息,包括最佳实践和技术细节,以提升用户体验和代码可维护性。 ... [详细]
  • 在Node.js中调用MySQL存储过程`updateUser(p1, p2, @p3)`时,其中`@p3`为输出参数。若更新操作失败,则返回0;成功则返回1。本文将详细介绍如何正确获取存储过程的返回结果,并确保在实际应用中能够顺利执行。 ... [详细]
  • React项目基础教程第五课:深入解析组件间通信机制 ... [详细]
  • 本文深入探讨了 Vue 框架中的混入(mixins)机制及其实际应用场景。首先,文章从官方文档出发,详细解读了混入的基本概念和核心原理。接着,通过具体的代码示例,展示了如何创建和使用混入,帮助开发者更好地理解和掌握这一功能。此外,文章还对比了混入与 Vuex、公共组件之间的区别,明确了各自适用的场景和优缺点,为开发者在项目中选择合适的技术方案提供了参考。 ... [详细]
author-avatar
阡蓝fliona
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有