程序员依扬

Results 84 issues of 程序员依扬

## 引言 上一节介绍了高阶函数的定义,并结合实例说明了使用高阶函数和不使用高阶函数的情况。后面几部分将结合实际应用场景介绍高阶函数的应用,本节先来聊聊函数柯里化,通过介绍其定义、比较常见的三种柯里化应用、并在最后实现一个通用的 currying 函数,带你认识完整的函数柯里化。 有什么想法或者意见都可以在评论区留言,下图是本文的思维导图,高清思维导图和更多文章请看我的 [Github](https://github.com/yygmind/blog)。 ![【进阶 6-2 期】深入高阶函数应用之柯里化](https://ws4.sinaimg.cn/large/006tNc79gy1g37t2jmjvhj32r00gcn2x.jpg) ## 柯里化 ### 定义 函数柯里化又叫部分求值,维基百科中对柯里化 (Currying) 的定义为: > 在数学和计算机科学中,柯里化是一种将使用多个参数的函数转换成一系列使用一个参数的函数,并且返回接受余下的参数而且返回结果的新函数的技术。 用大白话来说就是只传递给函数一部分参数来调用它,让它返回一个新函数去处理剩下的参数。使用一个简单的例子来介绍下,最常用的就是 add 函数了。 ```js // 木易杨 const add = (...args) =>...

进阶系列
高阶函数

本期的主题是**调用堆栈**,本计划一共28期,**每期重点攻克一个面试重难点**,如果你还不了解本进阶计划,文末点击查看全部文章。 如果觉得本系列不错,欢迎点赞、评论、转发,您的支持就是我坚持的最大动力。 --- JS内存空间分为**栈(stack)**、**堆(heap)**、**池(一般也会归类为栈中)**。 其中**栈**存放变量,**堆**存放复杂对象,**池**存放常量,所以也叫常量池。 昨天文章介绍了堆和栈,小结一下: - 基本类型:--> `栈`内存(不包含闭包中的变量) - 引用类型:--> `堆`内存 **今日补充**一个知识点,就是闭包中的变量并不保存中栈内存中,而是保存在`堆内存`中,这也就解释了函数之后之后为什么闭包还能引用到函数内的变量。 ```js function A() { let a = 1 function B() { console.log(a) } return B } ```...

进阶系列
调用堆栈

本期的主题是**作用域闭包**,本计划一共28期,**每期重点攻克一个面试重难点**,如果你还不了解本进阶计划,文末点击查看全部文章。 如果觉得本系列不错,欢迎点赞、评论、转发,您的支持就是我坚持的最大动力。 --- 作用域指的是一个变量和函数的作用范围,JS中**函数内声明的所有变量在函数体内始终是可见的**,在ES6前有全局作用域和局部作用域,但是没有块级作用域(catch只在其内部生效),局部变量的优先级高于全局变量。 #### 作用域 ##### 变量提升 ```js var scope="global"; function scopeTest(){ console.log(scope); var scope="local" } scopeTest(); //undefined ``` 上面的代码输出是`undefined`,这是因为局部变量`scope`变量提升了,等效于下面 ```js var scope="global"; function scopeTest(){ var scope; console.log(scope); scope="local"...

进阶系列
作用域闭包

## 引言 上一节我们详细聊了聊高阶函数之柯里化,通过介绍其定义和三种柯里化应用,并在最后实现了一个通用的 currying 函数。这一小节会继续之前的篇幅聊聊函数节流 throttle,给出这种高阶函数的定义、实现原理以及在 underscore 中的实现,欢迎大家拍砖。 有什么想法或者意见都可以在评论区留言,下图是本文的思维导图,高清思维导图和更多文章请看我的 [Github](https://github.com/yygmind/blog)。 ![66666333](https://ws3.sinaimg.cn/large/006tNc79ly1g3hetnzs7zj33o20jgqcu.jpg) ## 定义及解读 函数节流指的是某个函数在一定时间间隔内(例如 3 秒)只执行一次,在这 3 秒内 **无视后来产生的函数调用请求**,也不会延长时间间隔。3 秒间隔结束后第一次遇到新的函数调用会触发执行,然后在这新的 3 秒内依旧无视后来产生的函数调用请求,以此类推。 ![img](https://static.xmt.cn/d3e6c89fb74b492fabc14f6185af77ce.png) 举一个小例子,不知道大家小时候有没有养过小金鱼啥的,养金鱼肯定少不了接水,刚开始接水时管道中水流很大,水到半满时开始拧紧水龙头,减少水流的速度变成 3 秒一滴,通过滴水给小金鱼增加氧气。 此时「管道中的水」就是我们频繁操作事件而不断涌入的回调任务,它需要接受「水龙头」安排;「水龙头」就是节流阀,控制水的流速,过滤无效的回调任务;「滴水」就是每隔一段时间执行一次函数,「3 秒」就是间隔时间,它是「水龙头」决定「滴水」的依据。 如果你还无法理解,看下面这张图就清晰多了,另外点击 [这个页面](http://demo.nimius.net/debounce_throttle/)...

进阶系列
防抖节流

本期的主题是**调用堆栈**,本计划一共28期,**每期重点攻克一个面试重难点**,如果你还不了解本进阶计划,文末点击查看全部文章。 如果觉得本系列不错,欢迎点赞、评论、转发,您的支持就是我坚持的最大动力。 --- 堆栈的内容和执行顺序我就不说了,前面两篇已经介绍过了。 但是**今天补充一个知识点**:某些情况下,调用堆栈中函数调用的数量超出了调用堆栈的实际大小,浏览器会抛出一个错误终止运行。 对于下面的递归就会无限制的执行下去,直到超出调用堆栈的实际大小,这个是浏览器定义的。 ```js function foo() { foo(); } foo(); ``` ![](https://static.oschina.net/uploads/space/2017/1213/104225_sJsM_2896879.png) 现在正式开始今天的主题,**内存空间详解** #### 栈数据结构 栈的结构就是后进先出**(LIFO)**,如果读过前面两篇文章应该是相当熟悉了。文中使用乒乓球盒子的结构来解释。 处于盒子中最顶层的乒乓球5,它一定是最后被放进去,但可以最先被使用。而我们想要使用底层的乒乓球1,就必须将上面的4个乒乓球取出来,让乒乓球1处于盒子顶层。 ![](https://upload-images.jianshu.io/upload_images/599584-b12fef30803a0c53.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700/format/webp) #### 堆数据结构 堆数据结构是一种树状结构。它的存取数据的方式与书架和书非常相似。我们只需要知道书的名字就可以直接取出书了,并不需要把上面的书取出来。JSON格式的数据中,我们存储的`key-value`可以是无序的,因为顺序的不同并不影响我们的使用,我们只需要关心书的名字。 #### 队列 队列是一种先进先出(**FIFO**)的数据结构,这是事件循环(Event Loop)的基础结构,事件循环我们会在第8期详解介绍。 ![](https://upload-images.jianshu.io/upload_images/599584-7ca4b641daf48c57.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp) ####...

进阶系列
调用堆栈

#### 数组方法概述 ##### 1、不改变原数组,返回新数组 * `concat() ` 连接两个或多个数组,两边的原始数组都不会变化,返回被连接数组的一个副本。 * `join()` 把数组中所有元素放入一个字符串中,返回字符串。 * `slice() ` 从开始到结束(不包括结束)选择数组的一部分浅拷贝到一个新数组。 * `map()` 创建一个新数组并返回,其中新数组的每个元素由调用原始数组中的每一个元素执行提供的函数得来,原始数组不会改变。 * `every()` 对数组中的每个元素都执行一次指定的回调函数,直到回调函数返回`false`,此时`every()`返回`false`并不再继续执行。如果回调函数对每个元素都返回`true`,那么`every()`将返回`true`。 * `some()` 对数组中的每个元素都执行一次指定的回调函数,直到回调函数返回`true`,此时`some()`返回`true`并不再继续执行。如果回调函数对每个元素都返回`false`,那么`some()`将返回`false`。 - `filter()` 创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。 ##### 2、改变原数组...

Array

## 引言 上篇文章用图解的方式向大家介绍了原型链及其继承方案,在介绍原型链继承的过程中讲解原型链运作机制以及属性遮蔽等知识,今天这篇文章就来深入探究下 `Function.__proto__ === Function.prototype` 引起的鸡生蛋蛋生鸡问题,并在这个过程中深入了解 Object.prototype、Function.prototype、function Object 、function Function 之间的关系。 ## Object.prototype 我们先来看看 ECMAScript 上的定义([15.2.4](http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.4))。 > The value of the [[Prototype]] internal property of the Object prototype object...

进阶系列
原型 Prototype

## 定义 > **new 运算符**创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。 ——(来自于MDN) 举个栗子 ```js function Car(color) { this.color = color; } Car.prototype.start = function() { console.log(this.color + " car start"); } var car = new Car("black");...

进阶系列
this全面解析

## 引言 上一节我们学习了 Lodash 中防抖和节流函数是如何实现的,并对源码浅析一二,今天这篇文章会通过七个小例子为切入点,换种方式继续解读源码。其中源码解析上篇文章已经非常详细介绍了,这里就不再重复,建议本文配合上文一起服用,[猛戳这里学习](https://github.com/yygmind/blog/issues/41) 有什么想法或者意见都可以在评论区留言,欢迎大家拍砖。 ## 节流函数 Throttle 我们先来看一张图,这张图充分说明了 Throttle(节流)和 Debounce(防抖)的区别,以及在不同配置下产生的不同效果,其中 `mousemove` 事件每 50 ms 触发一次,即下图中的每一小隔是 50 ms。今天这篇文章就从下面这张图开始介绍。 ![4196897931-5a14d309d661c_articlex](http://resource.muyiy.cn/image/20200125143922.png) ### 角度 1 `lodash.throttle(fn, 200, {leading: true, trailing: true})` ####...

进阶系列
防抖节流

本期的主题是**作用域闭包**,本计划一共28期,**每期重点攻克一个面试重难点**,如果你还不了解本进阶计划,文末点击查看全部文章。 如果觉得本系列不错,欢迎点赞、评论、转发,您的支持就是我坚持的最大动力。 --- 红宝书(p178)上对于闭包的定义:**闭包是指有权访问另外一个函数作用域中的变量的函数**, MDN 对闭包的定义为:**闭包是指那些能够访问自由变量的函数**。 其中**自由变量**,指在函数中使用的,但既不是函数参数`arguments`也不是函数的局部变量的变量,其实就是另外一个函数作用域中的变量。 使用上一篇文章的例子来说明下**自由变量** ```js function getOuter(){ var date = '1127'; function getDate(str){ console.log(str + date); //访问外部的date } return getDate('今天是:'); //"今天是:1127" } getOuter(); ``` 其中`date`既不是参数`arguments`,也不是局部变量,所以`date`是自由变量。 总结起来就是下面两点:...

进阶系列
作用域闭包