我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么掌握JS高阶编程技巧

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么掌握JS高阶编程技巧

这篇文章主要讲解了“怎么掌握JS高阶编程技巧”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么掌握JS高阶编程技巧”吧!

单例设计模式

用单独的实例来管理当前事物的相关特征,泛指属性和方法,类似于实现分组的特点,把一个实例的所有特征描述绑定在一个分组里。

来看一下简单的单例设计模式:

let module1 = (function () {   function tools() {}   function share() {}    return {     name: 'house',     tools   }; })(); module1.tools();

这里我们可以把module1模块定义的方法暴露出来,给外部模块用。

还有一种基于闭包实现的单例模式称为:高级单例设计模式,在vue/react出来之前,是团队协作最常用的模块化思想,常用来以此模块划分。

闭包形式的单例模式如下:

let A = (function () {   function fn() {     B.getXxx();   }   function query() {}    return {     query   } })();  let B = (function () {   function fn() {}   function getXxx() {}      A.query();    return {     getXxx   } })();

在上面这个例子中,我们可以分别定义A、B两个模块,先在自己模块内声明函数,再暴露出去,给对方的模块使用,这便是最早的模块化思想,也是高级单例设计模式。

惰性函数

我们先来看这样一个例子,封装一个获取元素样式的函数。

获取样式,我们通常想到window.getComputedStyle和element.currentStyle这两个API,但他们的执行也是有条件的。

比如:前者只有Google浏览器兼容,后者IE浏览器兼容。

function getCss(element, attr) {   if ('getComputedStyle' in window) {     return window.getComputedStyle(element)[attr];   }   return element.currentStyle[attr]; }   getCss(document.body, 'margin'); getCss(document.body, 'padding'); getCss(document.body, 'width');

从这个例子中,我们可以看出来,如果需要3次获取元素的样式,明显每一次进入函数都需要判断该方法兼容与否,这就造成了不必要的浪费。最好的解决方案——惰性函数思想。

通俗的来说,惰性函数初始化第一次渲染的时候执行,如果第二遍执行还是一样的效果,我们需要用闭包的思想解决这一问题。

function getCss(element, attr) {   if ('getComputedStyle' in window) {     getCss = function (element, attr) {       return window.getComputedStyle(element)[attr];     };   } else {     getCss = function (element, attr) {       return element.currentStyle[attr];     };   }   // 为了第一次也能拿到值   return getCss(element, attr); } getCss(document.body, 'margin'); getCss(document.body, 'padding'); getCss(document.body, 'width');

在这个函数中,当我们第一次执行getCss函数的时候,就已经可以确定getComputedStyle兼容与否了,所以在第二次就没必要再判断了,根据第一次判断完返回的结果,直接确定第二次,第三次的函数执行到底用哪个API,这样以来每次函数执行,都将少了一层判断,一定程度上提高了js的运行速度。

那么我们来看,这个惰性体现在哪里呢?

过程:其实,是第一次getCss函数执行完创建了全局作用域下的私有执行上下文,而在其里面重新生成了getCss函数,将其引用地址重新赋值给全局函数getCss,导致全局下的getCss不能被释放,形成了一个闭包。在以后每次执行时,都执行里面的小函数getCss。

柯理化函数

柯理化函数含义是给函数分步传递参数,每次传递部分参数,并返回一个更具体的函数接收剩下的参数,这中间可嵌套多层这样的接收部分参数的函数,直至返回最后结果。

最基本的柯里化拆分

// 原函数 function add(a, b, c) {   return a + b + c; }  // 柯里化函数 function addCurrying(a) {   return function (b) {     return function (c) {       return a + b + c;     }   } }  // 调用原函数 add(1, 2, 3); // 6  // 调用柯里化函数 addCurrying(1)(2)(3) // 6

被柯里化的函数 addCurrying  每次的返回值都为一个函数,并使用下一个参数作为形参,直到三个参数都被传入后,返回的最后一个函数内部执行求和操作,其实是充分的利用了闭包的特性来实现的。

封装柯理化通用式

上面的柯里化函数没涉及到高阶函数,也不具备通用性,无法转换形参个数任意或未知的函数。

我们来封装一个通用的柯里化转换函数,可以将任意函数转换成柯里化。

// add的参数不固定,看有几个数字累计相加 function add (a,b,c,d) {   return a+b+c+d }  function currying (fn, ...args) {   // fn.length 回调函数的参数的总和   // args.length currying函数 后面的参数总和    // 如:add (a,b,c,d)  currying(add,1,2,3,4)   if (fn.length === args.length) {       return fn(...args)   } else {     // 继续分步传递参数 newArgs 新一次传递的参数     return function anonymous(...newArgs) {       // 将先传递的参数和后传递的参数 结合在一起       let allArgs = [...args, ...newArgs]       return currying(fn, ...allArgs)     }   } }  let fn1 = currying(add, 1, 2) // 3 let fn2 = fn1(3)  // 6 let fn3 = fn2(4)  // 10

柯理化函数思想

利用闭包保存机制,把一些信息预先存储下来(预处理的思想)

我们用一道求和的题来描述:

function currying(...outerArgs) {   return function anonymous (...innerArgs) {     let args = outerArgs.concat(innerArgs)     return args.reduce((previousValue, currentValue) => previousValue + currentValue)   } }  let fn1 = currying(1, 2) let fn2 = fn1(3) let fn3 = fn2(4)

补充 什么是预处理的思想:

在第一次fn1函数执行的时候,会创建一个函数执行上下文,将 1, 2 存储在该上下文中的局部变量里,在以后执行 fn2 fn3的时候,需要先取得 fn1  的返回结果,使用存储的 1, 2 参数,这种机制便形成了闭包

不理解reduce的小伙伴看过来:

情况1:reduce没有第二个参数时

let Array = [10, 20, 30, 40, 50]; Array.reduce(previousValue, currentValue, currentIndex, arr){   return previousValue + currentValue; }
  • 第一次触发函数时,previousValue为第一项(10),currentValue为第二项(20)

  • 第二次触发函数时,previousValue为回调函数的返回值(30),currentValue为第三项(30)

  • 第X次触发函数时,previousValue为回调函数的返回值,currentValue为第X+1项

  • currentIndex:对应的就是currentValue的索引值

  • arr:是个常量 数组本身

情况2:reduce有第二个参数时

let Array = [10, 20, 30, 40, 50]; Array.reduce((previousValue, currentValue, currentIndex, arr){   return previousValue + currentValue; }, 0)
  • 第一次触发函数时,previousValue为第二个参数(0),currentValue为第一项(10)

  • 第二次触发函数时,previousValue为回调函数的返回值(10),currentValue为第二项(20)

  • 第X次触发函数时,previousValue为回调函数的返回值,currentValue为第X项

  • currentIndex:对应的就是currentValue的索引值

  • arr:是个常量 数组本身

compose函数

compose组合函数:把多层函数嵌套调用扁平化

compose函数常基于reduce 柯理化函数思想解决 函数调用扁平化的问题:

在项目中,我们经常遇到这样一个问题:

const fn1 = x => x + 10; const fn2 = x => x - 10; const fn3 = x => x * 10; const fn4 = x => x / 10;  console.log(fn3(fn1(fn2(fn1(4)))))

上面这个例子中,明显看出层级嵌套较深,这时候就需要调用函数扁平化的思想

函数调用扁平化: 如果是多层级嵌套调用的函数,把一个函数调用完,当作另一个函数的实参传递到下一个函数中

解决方案:从左到右依次执行

 function compose(...funcs) {   return function anonymous(...args) {     if(funcs.length === 0) return args;     if(funcs.length === 1) return funcs[0](...args);     // funcs 里有 多个函数时     return funcs.reduce((n, func) => {       // 第一次执行:       // n:第一个函数执行的实参 func:第一个函数       // 第二次执行:       // n的值:上一次func执行后的返回值,作为实参传递给下一个函数执行 func:第二个函数       return Array.isArray(n) ? func(...n) : func(n);     }, args)   } }  let res = compose(fn1, fn3, fn2, fn4)(5)  // 执行过程: console.log(compose()(5)); //=>5 console.log(compose(fn1)(5)); //=>5+10 = 15 console.log(compose(fn1, fn3)(5)); //=>fn1(5)=15  fn3(15)=150 console.log(compose(fn1, fn3, fn2)(5)); //=>fn1(5)=15  fn3(15)=150 fn2(150)=140 console.log(compose(fn1, fn3, fn2, fn4)(5)); //=>fn1(5)=15  fn3(15)=150 fn2(150)=140 fn4(140)=14

compose函数扁平化的执行过程:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. compose()(5),如compose()函数中无函数参数传递进来,则直接返回后面的参数 5

  3. compose(fn1, fn3, fn2, fn4)(5),先执行fn1(5),再将fn1(5)的结果传递到fn3中,如fn3(fn1(5))  => fn3(15),以此类推fn2(fn3(fn1(5))) =>  fn4(150),后来每一次函数调用的参数都是前一个函数返回的结果,自然我们就想到了Array.prototype.reduce方法

  4. 设置reduce的第二个参数,是为了统一n为每一次函数的返回结果(第一次n为5,func为fn1),刚好又需要让fn1(5)函数执行,可见第二个参数的必要性,是为了统一每次的回调函数返回结果都是number

函数式编程与命令式编程

回调函数:把一个函数作为值传递给另外一个函数,在另外一个函数中把这个函数执行(这是实现函数式编程重要的知识)

函数式编程:注重结果,不在乎过程,过程交给别人处理,体现函数封装性思想(提倡)

命令式编程:注重过程,需要自己去实现过程

函数式编程:把逻辑如何实现封装成为API方法,我们以后只要调取API方法,即可获取想要的结果即可

let arr = [10, 20, 30, 40, 50];  let res = arr.reduce((n, item) => {   return n + item; });

命令式编程:用代码实现主要的逻辑,注重过程

let res = 0; for (let i = 0; i < arr.length; i++) {   res += arr[i]; }

感谢各位的阅读,以上就是“怎么掌握JS高阶编程技巧”的内容了,经过本文的学习后,相信大家对怎么掌握JS高阶编程技巧这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么掌握JS高阶编程技巧

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Vue Jest进阶攻略:掌握高阶测试技巧

本文将介绍Vue Jest进阶攻略,掌握高阶测试技巧,使您能够编写更强大、更可靠的测试代码,提高代码覆盖率,增强测试信心。
Vue Jest进阶攻略:掌握高阶测试技巧
2024-02-04

web前端:JS高阶编程技巧--惰性函数

编程学习网:框架(framework)是一个框子--指其约束性,也是一个架子--指其支撑性。是一个基本概念上的结构,用于去解决或者处理复杂的问题。
web前端:JS高阶编程技巧--惰性函数
2024-04-23

Golang进阶指南:掌握高级概念和技巧

本文探讨了 go 编程语言的高级概念和技巧,包括:并发与 goroutine:实现多任务执行。通道:实现 goroutine 之间安全的数据传递。接口:提供代码灵活性、松耦合和可扩展性。反射:允许在运行时检查、修改和创建变量。测试:确保代码
Golang进阶指南:掌握高级概念和技巧
2024-05-12

掌握C++模板编程的百变技巧

掌握 c++++ 模板编程通过使用参数化的代码块(模板)在编译时生成代码,提高代码可重用性、类型化和效率。高级技巧包括类模板特化、类型别名和函数指针。实战案例中,动态数组问题使用 dynamicarray 模板类提供了可调整大小的容器解决方
掌握C++模板编程的百变技巧
2024-05-21

掌握golang中Select Channels Go并发式编程的高级技巧

掌握golang中Select Channels的高级技巧可以帮助我们更好地进行并发式编程。下面是一些可以帮助你提升技能的技巧:1. 在select语句中使用default分支:默认分支可以用来处理非阻塞的channel操作。当没有任何一个
2023-10-20

提升Go语言技能:掌握高级编程技巧和实践经验

Go语言作为一门新兴的编程语言,因其简洁、高效、并发性能优越等特点,受到越来越多程序员的关注和青睐。如果想要在Go语言领域走得更远,不仅需要熟练掌握基础语法和常见用法,还需要积累一定的高级编程技巧和实践经验。本文将带领读者深入探讨提升Go语
提升Go语言技能:掌握高级编程技巧和实践经验
2024-02-27

问题回答:学习vue需要掌握高级js技巧吗

随着Vue.js的日益流行,越来越多的前端开发人员发现自己需要学习和了解这个强大而灵活的JavaScript框架,以便能够更好地构建可扩展和动态的Web应用程序。然而,有些人可能会问:“学习Vue.js是否需要掌握高级JavaScript呢?”事实上,学习Vue.js的确需要对JavaScript有一定的了解,特别是对高级JavaScript概念的掌握对于Vue.js的学习和开
2023-05-14

HTML 无序列表进阶教程:掌握高级技巧,提升网页表现力

HTML 无序列表是网页中常用的元素,可以帮助您轻松地将内容组织成易读的格式。除了基本的用法之外,HTML 无序列表还提供了许多高级技巧,可以帮助您提升网页的表现力,让您的网站更具吸引力。
HTML 无序列表进阶教程:掌握高级技巧,提升网页表现力
2024-02-27

Java程序员须掌握的8项编程技巧是什么

这篇文章给大家介绍Java程序员须掌握的8项编程技巧是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Java是目前最好的编程语言之一,它可以用来编写Windows程序或者是Web应用,移动应用,网络程序,消费电子产
2023-06-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录