JS
文章平均质量分 87
JavaScript学习心得记录
程序员阿甘
这个作者很懒,什么都没留下…
展开
-
JS-原型和原型链以及继承和instaceof实现
通过构造函数创建对象ES6之前没有提出class,所有无法通过类来创建对象,但是却可以通过构造函数创建对象。function Person(name, age) { this.name = name, this.age = age, this.say = function(){ console.log(this.name + ' say I am ' + this.age + ' years old') }}var p = new Person('Tom', 18)p.say(原创 2021-09-02 14:26:37 · 341 阅读 · 0 评论 -
JS-闭包
如何产生闭包内层函数访问外层函数的成员(变量或函数),就产生了闭包原创 2021-09-03 15:14:34 · 544 阅读 · 0 评论 -
Promise - (一)初识
JS异步原理主线程(main-thread)和执行栈(call-stack)JS是单线程的,即所有JS代码都由一个线程执行,这个线程就是JS的主线程。JS的主线程在执行JS代码时,需要保存执行过程中的数据,而这些数据就保存在执行栈中,更准确的说,JS的主线程在执行代码中的函数时,就会在执行栈中生成一个栈帧,栈帧中保存着函数中的使用的数据。同步任务和异步任务由于JS是单线程执行的,所以在遇到耗时且不依赖于JS线程的操作时,会发生无意义的阻塞。为什么叫无意义的阻塞呢?举个例子:原创 2021-09-15 23:29:03 · 726 阅读 · 0 评论 -
Promise - (二)Promise核心实现
一步步还原Promise构造函数,和then方法的实现,将实现过程中可能遇到的难点全部嚼碎分析原创 2021-12-02 23:24:04 · 910 阅读 · 0 评论 -
Promise - (三)异步宏任务和异步微任务
浏览器五大核心线程:1、GUI渲染线程2、JS引擎线程3、事件触发线程4、定时触发器线程5、异步http请求线程其中JS代码的解释执行是由JS引擎线程负责的,我们通常将该线程叫做JS主线程,同时它也是单线程运行的。即所有的JS代码都有JS主线程这一个线程负责解释执行。单线程运行过程中,如果遇到费时操作,会造成阻塞现象,单线程必须处理完费时操作后,才可以继续往下执行。为了提升单线程执行效率,JS引擎线程在解释执行JS代码时会将JS代码分为两种类型:1、同步任务2、异原创 2021-12-03 19:00:04 · 1782 阅读 · 1 评论 -
Promise - (四)Promise其他方法实现
(5条消息) 随笔-对Promise的深入理解_qfc_128220的博客-CSDN博客前面完成了Promise构造函数和Promise.prototype.then方法的重写但是还有如下方法没有重写Promise.prototype.catchPromise.prototype.finallyPromise.resolvePromise.rejectPromise.allPromise.race这里我们先用es6 class语法将之前重写Promise构造函数和Pr原创 2021-12-05 12:52:15 · 791 阅读 · 0 评论 -
Promise - (五)then方法参数回调函数加入异步微任务队列的时机
先看一个例子Promise.resolve().then(()=>{ setTimeout(()=>{ console.log(1) })}).then(()=>{ console.log(2)})思考一个问题1在JS事件循环机制触发前,即JS同步代码执行阶段,上面两个then都会执行吗?还是只执行第一个then?答:两个then都会执行,因为then方法调用是同步的再思考一个问题2在JS事件循环机制触发前,即原创 2021-12-04 18:21:28 · 1438 阅读 · 0 评论 -
Promise - (六)关于then参数回调函数的缓存位置理解
题目来源于:【JS】因两道Promise执行题让我产生自我怀疑,从零手写Promise加深原理理解 - 听风是风 - 博客园 (cnblogs.com)const fn = (s) => { new Promise((resolve, reject)=>{ if(typeof s === 'number') { resolve() } else { reject() } }) .then(res => { conso原创 2022-05-10 01:16:14 · 407 阅读 · 0 评论 -
Promise - (七)初识async&await
举个例子吧我要在1s后打印1,打印1时刻2s后打印2,打印2时刻3s后打印3传统异步编程实现console.log(new Date)setTimeout(()=>{ console.log(new Date,1) setTimeout(()=>{ console.log(new Date,2) setTimeout(()=>{ console.log(new Date,3) },3000) },2000)},1000)Pro.原创 2021-09-24 16:44:00 · 622 阅读 · 0 评论 -
Promise - (八)Iterator、Generator、co
ES6不仅推出了Promise,还推出了Iterator、Generator。简单理解:Iterator是迭代器,Generator是生成器。Iterator迭代器从名字来看,我们就应该知道Iterator的功能应该类似于for循环。但是它和for循环有着本质区别。Iterator迭代器主要解决了两个问题:1、for循环是不可控迭代,而Iterator可以实现可控迭代什么叫不可控迭代,什么叫可控迭代?我们平时使用for循环,只要定义好for,for循环就会从数列头部一直迭代到原创 2021-12-06 13:13:46 · 752 阅读 · 0 评论 -
Promise - (九)重识async&await
第一代异步编程方案是:基于回调函数的异步编程,缺点是当实现异步串行时,会产生回调地狱第二代异步编程方案是:基于Promise的异步编程,它使用then链式调用解决了异步任务串行时产生回调地狱的问题那么Promise异步编程真的完美吗?const fs = require('fs')function read(path) { return new Promise((resolve, reject) => { fs.readFile(path, 'utf-8',原创 2021-12-06 18:59:55 · 944 阅读 · 0 评论 -
Promise - (十)await暂停async函数执行的实现
async function f1(){ console.log('f1 start') await f2() console.log('f1 end')}async function f2(){ console.log('f2')}console.log('script start')f1()console.log('script end')我们知道await可以暂停async函数继续向下执行,那么JS主线程也会被await阻塞吗?即:awa..原创 2021-12-07 11:13:16 · 1765 阅读 · 0 评论 -
Promise - (十一)co思想,以及co4.0.0源码分析
co/index.js at master · tj/co · GitHub附上tj大神co函数源码地址,源码下载npm i co基础知识储备先看下readme.md关于co介绍Generator based control flow goodness for nodejs and the browser, using promises, letting you write non-blocking code in a nice-ish way.基于控制流的生成器,在node环境原创 2021-12-07 13:39:41 · 924 阅读 · 0 评论 -
Promise - (十二)Promisify
有了async和await之后,Promise编程在代码变得更加简洁,逻辑更加清晰。其中async通常只是修饰函数,表示该函数是一个异步函数,async中通常使用await来触发异步任务间的串行执行(同步执行)。await等待Promise对象的成功值,Promise对象的成功值等待异步任务的执行完成。所以一个简洁明了地封装异步任务到Promise对象的方法Promisify是必要的。没有Promisify的异步编程,又想起了被Promise公式化代码的恐怖支配的日子....a.原创 2021-09-24 18:24:42 · 607 阅读 · 0 评论 -
Promise - async await的基本用法以及使用陷阱,高效使用技巧
基本用法async关键字用于修饰一个函数,被修饰的函数会变为异步函数这里的异步函数,并不是指async函数执行是异步的,而是指async函数会返回一个promise对象async函数返回的promise对象的状态和结果取决于async函数的return值或抛出的异常若return值为非promise对象,则async函数返回一个成功态的promise对象,其结果为return值若return值为promise对象,则async函数返回一个新的promise对象,其状态和..原创 2021-12-07 01:17:55 · 3964 阅读 · 0 评论 -
Promise - then参数回调函数返回值为Promise对象时产生的两次微任务说明
【JS】因两道Promise执行题让我产生自我怀疑,从零手写Promise加深原理理解 - 听风是风 - 博客园 (cnblogs.com)Promise.resolve().then(() => { console.log(0); return Promise.resolve(4);}).then((res) => { console.log(res)})Promise.resolve().then(() => { console.log(1原创 2022-05-11 18:19:40 · 2437 阅读 · 0 评论 -
随笔-深入学习ES6的Map和Set(底层数据结构层面)
在学习ES6的Map和Set之前,我总是有意无意地将它们和我之前学习的Java集合类中的Map和Set进行对比参照,有兴趣的同学可以去看下我之前总结的Java的Map和Set(9条消息) Map集合之HashMap(一)_qfc_128220的博客-CSDN博客我在网上找到的大部分关于ES6的Map和Set的资料是关于它们的用法,少料资料提及了性能,(9条消息) 前端集合删除对象_如何使用JavaScript Set集合更快地编写代码_weixin_39616674的博客-CSDN博客原创 2021-12-08 13:24:35 · 1979 阅读 · 2 评论 -
随笔-Set和WeakSet的使用
上一篇阐述了ES6的Map和Object的比较,以及Set和Array的比较Map和Set唯一性判断由于Map键名 和 Set元素,在底层都是采用哈希表保证的唯一性,而哈希表保证唯一性的关键就是:如何判断两个元素或两个属性是相同的?这里Map和Set使用的一套判断是否相同的算法:下面MDN对于Set和Map对于唯一性元素判定的描述:可以发现Map和Set唯一性保证时都特别关注了两个东西:1、+0,-02、NaN和NaN这里结论是:Map和Set认为 +0和-0相.原创 2021-12-09 23:12:33 · 875 阅读 · 0 评论 -
随笔-Map和WeakMap的使用
Map类Map是一个构造函数或类,它可以用来创建一个Map实例对象,在new Map时支持传入一个可迭代对象,Map内部会对传入对象进行迭代,将可迭代对象中每一个元素存入Map中const map = new Map([1,2,3])但是需要注意,new Map传入的可迭代对象的组成元素必须是一个键值对形式的对象,否则会报错如[1,2,3]数组,它是一个可迭代对象,但是数组元素不是键值对形式的对象,所以无法被Map加入。所以:Map中存储的元素必须是键值对形式的对象。但是我..原创 2021-12-10 15:55:55 · 761 阅读 · 0 评论 -
随笔-ES6 class语法糖 及继承性实现
ES5构造函数的缺点在ES5时,JS还没有“类”的概念,创建对象使用的都是构造函数,而构造函数和普通函数没有什么本质区别,只是在书写上要求构造函数的函数名首字母大写,方便和普通函数区分。即ES5构造函数不仅可以new调用,还可以当成普通函数调用。如果我们要限制ES5构造函数不能当成普通函数调用,则需要做额外处理function Person(name){ if(this instanceof Person) { this.name = name } else {原创 2021-12-10 17:26:31 · 727 阅读 · 0 评论 -
随笔-ES6 class 封装性实现(私有属性)
面向对象三大特征:封装,继承,多态上一章,我们介绍了使用class extends实现JS类的继承,但是其本质上还是ES5构造函数的寄生组合式继承。面向对象另一大特征就是封装,即类的属性不对外直接暴露,外部也无法直接操作类的属性,外部只能通过类对外提供getter和setter方法来操作类的属性。可以发现,上面的类定义不符合封装性要求,age已经被设置为100000了。闭包+Symbol+getter setter实现私有属性封装性实现:对象属性不能被外部直接访问,即不能对象..原创 2021-12-10 18:34:21 · 1078 阅读 · 0 评论 -
随笔-ES6 class 多态性真的有必要实现吗
面向对象三大特征:封装、继承、多态而多态只发生在父子类之间,即子类继承父类的方法,但是又可以重写父类的方法,使得相同的方法在父类实例和子类实例中表现不同的行为,这一现象称为多态。而ES6的class是可以实现多态吗?class Sup{ test(){ console.log('Sup test') }}class Sub extends Sup { test(){ console.log('Sub test') }}原创 2021-12-11 22:25:12 · 675 阅读 · 0 评论 -
随笔-ES6 Symbol
Symbol简介Symbol是ES6推出的JS第六大简单数据类型,其余五个分别是:undefined null number string boolean由于它是简单数据类型,所以不支持newSymbol本身是一个函数,通过Symbol()函数调用可以返回一个独一无二的值,Symbol()返回值仅用来表示唯一值,而不能用来和其他数据类型的值进行运算。Symbol()常用来解决对象属性命令冲突问题在JS开发中,我们经常需要给对象添加属性,但是当对象原本的属...原创 2021-12-11 22:02:46 · 666 阅读 · 1 评论 -
随笔-JS早期模块化的实现与缺点分析
早期人们对于JS的预期只是一个具备,在浏览器上实现校验用户输入,的能力的脚本化语言,但是随着WEB的发展,越来越多的工作交给了浏览器端,浏览器不得不将JS独立出来,为JS单独设立了JS引擎,让JS可以接收更加繁重地任务,而这也加剧了JS文件的复杂度。终于有一天,人们发现单纯地依靠一个JS文件包办一个网站所有行为,已经变得很困难了,比如:1、所有HTML文件的行为都放到了一个JS文件中,导致JS文件体量异常巨大2、JS文件体量过于庞大,导致每个HTML在加载JS文件时,会造成很长的延迟,用户体验.原创 2021-12-13 11:55:05 · 596 阅读 · 2 评论 -
随笔-深入理解ES6模块化(一)
首先我们来了解下CommonJS模块化规范,CommonJS规范将每一个JS文件都视为一个模块,在JS文件中通过module.exports对外暴露模块输出,通过require引入其他模块的module.exports。那么为什么CommonJS规范下的JS文件中可以使用module.exports和require呢?这两个变量是谁提供的呢?答:首先CommonJS规定每个JS都是一个模块,我们知道模块必须具有模块作用域原创 2021-12-15 12:49:46 · 2017 阅读 · 0 评论 -
随笔-深入理解ES6模块化(二)
上一章,介绍了ES6模块化的export和import的命令的一些令人奇怪的特性,并做了解释。但还是有点乱,这一节我们再来理一下。模块,输出变量,输出接口三者的关系一个JS文件就是一个模块模块内需要被暴露出去的变量就是 输出变量模块 export命令会产生一个输出接口,输出接口和输出变量之间一一对应。模块,输入变量,输入接口三者的关系输入接口和输出接口之间的关系输入接口要求和输出接口同名输入接口其实就是通过输出接口和静态定义的输出变量符号建立单向连接(只.原创 2021-12-15 13:34:46 · 555 阅读 · 0 评论 -
随笔-深入理解ES6模块化(三)
ES6模块加载 和 CommonJS模块加载区别:1、模块加载时机不同ES6模块是在编译期间完成的加载ES6模块加载的概念就是:编译期间完成模块间关联;即确定A模块输入接口,和B模块输出接口之间的联系。而输入变量和输出变量之间的传递是需要等到运行期间完成的。CommonJS模块是在运行期间完成的加载CommonJS模块加载的概念是:运行期间完成模块间的关联:即通过A模块的require函数调用,触发B模块代码执行,并完成B模块的module.exports输出对象的输出数据挂载,当B原创 2021-12-16 14:43:44 · 2135 阅读 · 0 评论 -
随笔-使用d8将JS源码编译为字节码,及字节码指令解读
什么是 D8d8 是一个非常有用的调试工具,你可以把它看成是 debug for V8 的缩写。我们可以使用 d8 来查看 V8 在执行 JavaScript 过程中的各种中间数据,比如作用域、AST、字节码、优化的二进制代码、垃圾回收的状态,还可以使用 d8 提供的私有 API 查看一些内部信息。下载D8win64 平台:https://storage.googleapis.com/chromium-v8/official/canary/v8-win64-dbg-8.4.109.zip原创 2021-12-15 11:04:02 · 1731 阅读 · 0 评论 -
有趣-如何解决递归过多导致的栈溢出
我们知道函数递归,就是函数自己调用自己,而每次函数调用就会产生一个函数执行上下文(栈帧)入执行栈,所以递归函数都依赖于下一个递归函数调用结束来实现自己实现结束调用而出栈,如果递归函数没有结束方向的话,就会发生执行栈内存不够分配,导致执行栈中栈帧溢出。但是这里问题是递归过多,而不是递归没有结束方向。递归过多是指,递归有结束方向,但是在结束之前就发生了栈溢出。function sum(total, i) { if(i === 0) { // 递归结束条件 return原创 2021-12-17 11:44:37 · 6879 阅读 · 0 评论 -
随笔-前端文件操作 File, Blob, ArrayBuffer 以及FileReader
前端文件操作浏览器由于安全性要求,不允许JS直接获取主机的文件系统上的文件,只能通过HTML标签input[type=file]来由用户选择可以被浏览器操作的文件。那么input[type=file]标签选择的文件,会被如何保存呢?<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible"原创 2021-12-30 18:43:03 · 3498 阅读 · 0 评论