前端面试小知识

120 阅读43分钟

1、css3有哪些新增属性???

css 新特性

我知道的 C3 的新特性有很多,常见的如下:

  • border-radius:圆角边框
  • box-shadow:盒子阴影
  • background-size:背景图片大小
  • transition:过渡
  • transform:转换(位移 旋转 缩放)
  • animation:动画
  • linear-gradient:线性渐变
  • box-sizing:css3 盒子模型 2、git的核心概念有哪些???

git的三个核心概念(版本库,工作区,暂存区)

本文适合有一定的git基础的人阅读

Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念,下面我以在windows系统中进行相关的讲解。

一、工作区(Working Directory)——其实就是一个文件夹

就是你在电脑里能看到的目录,比如我在F盘下面建了一个GitRepository文件夹,使用命令为:mkdir f:\GitRepository .那么这个GitRepository文件夹其实就是一个工作区。

二、版本库(Repository)——其实就是.git隐藏文件夹 在我们创建一个GitRpository文件夹之后,进入到该文件夹之后,使用命令 git init命令,则会创建版本库,即产生一个 .git隐藏文件夹 工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,暂存区有时候也称之为索引区。还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。

那我们怎么去查看这个.git隐藏文件夹?因为我的事win10系统,可以在文件夹中通过“查看”勾选“隐藏的项目”既可以查看到隐藏文件夹了。

前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:比如我们添加一个tt.txt文本文件在GitRepository目录之下。这个文本文件只有一两个数字111.

f:\GitRepository>git add tt.txt f:\GitRepository>git commit -m "create successfully" [master (root-commit) 98e1592] create successfully 1 file changed, 1 insertion(+) create mode 100644 tt.txt 第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;

第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。

你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。

然后执行命令 git commit -a -m "insert successfully"

接下来,我们自己在GitRrpository这个目录下创建一个 ss.txt文本文件,并且添加一行文本 aaa,但是我们不去将这个 ss.txt文本文件add进去,这时候我们通过状态查看GitRepository下面两个文本文件的的状态:

f:\GitRepository>git status On branch master Untracked files: (use "git add ..." to include in what will be committed) //说明ss.txt没有添加进master里面去 ss.txt nothing added to commit but untracked files present (use "git add" to track)

总结: git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行 git commit就可以一次性把暂存区的所有修改提交到分支(branch)。

三、版本库的深入理解 下面一幅图片,从更深入的角度讲解了在底层到底是怎么工作的:

图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage, index),标记为 "master" 的是 master 分支所代表的目录树。 图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。

图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。

当对工作区修改(或新增)的文件执行 "git add" 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。

当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。

当执行 "git rm --cached " 命令时,会直接从暂存区删除文件,工作区则不做出改变。

当执行 "git checkout ." 或者 "git checkout -- " 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。

当执行 "git checkout HEAD ." 或者 "git checkout HEAD " 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

———————————————— 版权声明:本文为CSDN博主「LoveMIss-Y」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/qq_27825451…

3、git中的分支相关概念有哪些??? # 说说 Git 常用的命令有哪些?

#简版

  • git add 提交文件到缓存区
  • git commit 提交代码到本地仓库
  • git pull 拉取远程仓库的分支与本地当前分支合并
  • git fetch 拉取远程仓库的分支
  • git push 上传本地指定分支到远程仓库
  • git status 查看当前分支状态
  • git diff 显示工作区中未添加至暂存区的内容与上一次 commit 的差异
  • git checkout 新建一个分支或切换分支或撤销工作区文件更改
  • git merge 合并指定分支到当前分支

(@徐济豪)

#一、前言

git的操作可以通过命令的形式如执行,日常使用就如下图 6 个命令即可

实际上,如果想要熟练使用,超过 60 多个命令需要了解,下面则介绍下常见的的git命令

#二、有哪些

#配置

Git自带一个 git config 的工具来帮助设置控制 Git外观和行为的配置变量,在我们安装完git之后,第一件事就是设置你的用户名和邮件地址

后续每一个提交都会使用这些信息,它们会写入到你的每一次提交中,不可更改

设置提交代码时的用户信息命令如下:

  • git config [--global] user.name "[name]"
  • git config [--global] user.email "[email address]"

#启动

一个git项目的初始有两个途径,分别是:

  • git init [project-name]:创建或在当前目录初始化一个 git 代码库
  • git clone url:下载一个项目和它的整个代码历史

#日常基本操作

在日常工作中,代码常用的基本操作如下:

  • git init 初始化仓库,默认为 master 分支
  • git add . 提交全部文件修改到缓存区
  • git add <具体某个文件路径+全名> 提交某些文件到缓存区
  • git diff 查看当前代码 add 后,会 add 哪些内容
  • git diff --staged 查看现在 commit 提交后,会提交哪些内容
  • git status 查看当前分支状态
  • git pull <远程仓库名> <远程分支名> 拉取远程仓库的分支与本地当前分支合并
  • git pull <远程仓库名> <远程分支名>:<本地分支名> 拉取远程仓库的分支与本地某个分支合并
  • git commit -m "<注释>" 提交代码到本地仓库,并写提交注释
  • git commit -v 提交时显示所有 diff 信息
  • git commit --amend [file1] [file2] 重做上一次 commit,并包括指定文件的新变化

关于提交信息的格式,可以遵循以下的规则:

  • feat: 新特性,添加功能
  • fix: 修改 bug
  • refactor: 代码重构
  • docs: 文档修改
  • style: 代码格式修改, 注意不是 css 修改
  • test: 测试用例修改
  • chore: 其他修改, 比如构建流程, 依赖管理

#分支操作

  • git branch 查看本地所有分支
  • git branch -r 查看远程所有分支
  • git branch -a 查看本地和远程所有分支
  • git merge <分支名> 合并分支
  • git merge --abort 合并分支出现冲突时,取消合并,一切回到合并前的状态
  • git branch <新分支名> 基于当前分支,新建一个分支
  • git checkout --orphan <新分支名> 新建一个空分支(会保留之前分支的所有文件)
  • git branch -D <分支名> 删除本地某个分支
  • git push <远程库名> :<分支名> 删除远程某个分支
  • git branch <新分支名称> <提交 ID> 从提交历史恢复某个删掉的某个分支
  • git branch -m <原分支名> <新分支名> 分支更名
  • git checkout <分支名> 切换到本地某个分支
  • git checkout <远程库名>/<分支名> 切换到线上某个分支
  • git checkout -b <新分支名> 把基于当前分支新建分支,并切换为这个分支

#远程同步

远程操作常见的命令:

  • git fetch [remote] 下载远程仓库的所有变动
  • git remote -v 显示所有远程仓库
  • git pull [remote] [branch] 拉取远程仓库的分支与本地当前分支合并
  • git fetch 获取线上最新版信息记录,不合并
  • git push [remote] [branch] 上传本地指定分支到远程仓库
  • git push [remote] --force 强行推送当前分支到远程仓库,即使有冲突
  • git push [remote] --all 推送所有分支到远程仓库

#撤销

  • git checkout [file] 恢复暂存区的指定文件到工作区
  • git checkout [commit] [file] 恢复某个 commit 的指定文件到暂存区和工作区
  • git checkout . 恢复暂存区的所有文件到工作区
  • git reset [commit] 重置当前分支的指针为指定 commit,同时重置暂存区,但工作区不变
  • git reset --hard 重置暂存区与工作区,与上一次 commit 保持一致
  • git reset [file] 重置暂存区的指定文件,与上一次 commit 保持一致,但工作区不变
  • git revert [commit] 后者的所有变化都将被前者抵消,并且应用到当前分支

reset:真实硬性回滚,目标版本后面的提交记录全部丢失了

revert:同样回滚,这个回滚操作相当于一个提价,目标版本后面的提交记录也全部都有

#存储操作

你正在进行项目中某一部分的工作,里面的东西处于一个比较杂乱的状态,而你想转到其他分支上进行一些工作,但又不想提交这些杂乱的代码,这时候可以将代码进行存储

  • git stash 暂时将未提交的变化移除
  • git stash pop 取出储藏中最后存入的工作状态进行恢复,会删除储藏
  • git stash list 查看所有储藏中的工作
  • git stash apply <储藏的名称> 取出储藏中对应的工作状态进行恢复,不会删除储藏
  • git stash clear 清空所有储藏中的工作
  • git stash drop <储藏的名称> 删除对应的某个储藏

#三、总结

git常用命令速查表如下所示:

#参考文献

#简版

  • 盒子模型组成有 4 部分,分别为:内容 内边距 外边距(一般不计入盒子实际宽度) 边框
  • 盒子模型有 2 种:标准盒子模型与怪异盒子模型
  • 标准盒子模型=content(内容)+border(边框)+padding(内边距)
  • 怪异盒子模型=content(内容)(已经包含了 padding 和 border)
  • css3 种可以通过设置 box-sizing 属性来完成标准或许怪异盒子模型之间的切换,怪异盒子模型:box-sizing: border-box;标准盒子模型:box-sizing:content-box

(@李金波)

#一、是什么

当对一个文档进行布局(layout)的时候,浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型(CSS basic box model),将所有元素表示为一个个矩形的盒子(box)

一个盒子由四个部分组成:contentpaddingbordermargin

content,即实际内容,显示文本和图像

boreder,即边框,围绕元素内容的内边距的一条或多条线,由粗细、样式、颜色三部分组成

padding,即内边距,清除内容周围的区域,内边距是透明的,取值不能为负,受盒子的background属性影响

margin,即外边距,在元素外创建额外的空白,空白通常指不能放其他元素的区域

上述是一个从二维的角度观察盒子,下面再看看看三维图:

下面来段代码:

<style>
  .box {
    width: 200px;
    height: 100px;
    padding: 20px;
  }
</style>
<div class="box">盒子模型</div>
当我们在浏览器查看元素时,却发现元素的大小变成了`240px`

这是因为,在`CSS`中,盒子模型可以分成:

-   W3C 标准盒子模型
-   IE 怪异盒子模型

默认情况下,盒子模型为`W3C` 标准盒子模型

## [#](http://fanyouf.gitee.io/interview/css/03.html#%E4%BA%8C%E3%80%81%E6%A0%87%E5%87%86%E7%9B%92%E5%AD%90%E6%A8%A1%E5%9E%8B)二、标准盒子模型

标准盒子模型,是浏览器默认的盒子模型

下面看看标准盒子模型的模型图:

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d95514db834842b78e01bf0365cc9d8b~tplv-k3u1fbpfcp-zoom-1.image)

从上图可以看到:

-   盒子总宽度 = width + padding + border + margin;
-   盒子总高度 = height + padding + border + margin

也就是,`width/height` 只是内容高度,不包含 `padding` 和 `border`值

所以上面问题中,设置`width`为 200px,但由于存在`padding`,但实际上盒子的宽度有 240px

## [#](http://fanyouf.gitee.io/interview/css/03.html#%E4%B8%89%E3%80%81ie-%E6%80%AA%E5%BC%82%E7%9B%92%E5%AD%90%E6%A8%A1%E5%9E%8B)三、IE 怪异盒子模型

同样看看 IE 怪异盒子模型的模型图:

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d743f2d2ba8e47e5a0f87fd6af9ef97d~tplv-k3u1fbpfcp-zoom-1.image)

从上图可以看到:

-   盒子总宽度 = width + margin;
-   盒子总高度 = height + margin;

也就是,`width/height` 包含了 `padding`和 `border`值

## [#](http://fanyouf.gitee.io/interview/css/03.html#box-sizing)Box-sizing

CSS 中的 box-sizing 属性定义了引擎应该如何计算一个元素的总宽度和总高度

语法:

box-sizing: content-box|border-box|inherit:


1  


-   content-box 默认值,元素的 width/height 不包含 paddingborder,与标准盒子模型表现一致
-   border-box 元素的 width/height 包含 paddingborder,与怪异盒子模型表现一致
-   inherit 指定 box-sizing 属性的值,应该从父元素继承

回到上面的例子里,设置盒子为 border-box 模型

.box { width: 200px; height: 100px; padding: 20px; box-sizing: border-box; }
盒子模型
这时候,就可以发现盒子的所占据的宽度为 200px

#参考文献

最新修改: 10/25/2022, 10:08:51 PM

5、event loop事件循环如何理解??? ## 为什么JavaScript是单线程?

        JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

        所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。

        为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

同步任务和异步任务:

        单线程,就是指一次只能完成一件任务,如果在同个时间有多个任务的话,这些任务就需要进行排队,前一个任务执行完,才会执行下一个任务。但如果有一个任务的执行时间很长,比如文件的读取或者数据的请求等等,那么后面的任务就要一直等待,这就会影响用户的使用体验。
为了解决这种情况,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。

        同步模式:  就是前一个任务执行完成后,再执行下一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的;
异步模式: 则完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行队列上的后一个任务,而是执行回调函数;后一个任务则是不等前一个任务的回调函数的执行而执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

事件循环(Event Loop):

        同步任务和异步任务分别进入不同的执行"场所"; 同步任务进入主线程,异步任务进入Event Table并注册回调函数。
当指定的事情完成时,Event Table会将这个函数移入任务队列(task quene),等待主线程的任务执行完毕;
当栈中的代码执行完毕,执行栈(call stack)中的任务为空时,就会读取任务队列(task quene)中的任务,去执行对应的回调;
如此循环,就形成js的事件循环机制(Event Loop)。

执行过程:

  1. 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
  2. 遇到异步任务, 进入Event Table并注册回调函数; 等到指定的事件完成(如ajax请求响应返回, setTimeout延迟到指定时间)时,Event Table会将这个回调函数移入Event Queue。
  3. 当栈中的代码执行完毕,执行栈(call stack)中的任务为空时,主线程会先检查micro-task(微任务)队列中是否有任务,如果有,就将micro-task(微任务)队列中的所有任务依次执行,直到micro-task(微任务)队列为空; 之后再检查macro-task(宏任务)队列中是否有任务,如果有,则取出第一个macro-task(宏任务)加入到执行栈中,之后再清空执行栈,检查micro-task(微任务),以此循环,直到全部的任务都执行完成。

在这里插入图片描述

 

在这里插入图片描述 

 

任务队列(task queue) 或 事件队列(event queue):

        SetTimeout和promise都是异步任务,那么它们两个先执行谁呢?
其实在js中也是有一个机制,就是会分为宏任务和微任务。宏任务和微任务分别存放在不同的event queue,这两个队列分别为macrotack queue和microtack queue.

        任务队列分为: macro-task(宏任务)队列, micro-task(微任务)队列;

        在最新标准中,它们被分别称为task与jobs。

macro-task(宏任务):

  • script(整体代码)
  • setTimeout
  • setInterval
  • setImmediate
  • I/O (比如Ajax操作从网络读取数据)
  • UI render

micro-task(微任务):

  • process.nextTick
  • Promise
  • Async/Await(实际就是promise)
  • MutationObserver(html5新特性)

事件表格(Event Table):

        Event Table 可以理解成一张事件->回调函数 对应表。

        用来存储 JS 中的异步事件 (request, setTimeout, IO等) 及其对应的回调函数的列表。

        当指定的事件完成(如ajax请求响应返回, setTimeout延迟到指定时间)时,Event Table会将这个回调函数移入Event Queue, 即macro-task(宏任务)队列 或 micro-task(微任务)队列。

6、js数组方法有哪些??? js数组方法大全

小爱同学-Allen

已于 2022-01-23 19:05:38 修改

1265 收藏 14 文章标签: javascript 前端 js数组方法 版权 在日常开发中,我们会接触到js中数组的一些方法,这些方法对我们来说,可以很遍历的达到我们想要的结果,但是因为方法比较多,有些方法也不常用,可能会过一段时间就会忘记,那么在这里我整理了31个数组的方法,供大家查阅。

1:concat(); 功能:合并数组,可以合并一个或多个数组,会返回合并数组之后的数据,不会改变原来的数组;

var str1 = [12,2,"hello"];var str2 = ["world"]; console.log(str1.concat(str2));        //[12, 2, "hello", "world"] console.log(str1);                //[12,2,"hello"]; 也可以使用es6的扩展运算符,不会改变原数组

let str3 = [...str1,...str2] ** 2:join();** 功能:将数组转为字符串并返回转化的字符串数据,不会改变原来的数组; 注意:()中用双引号包括自己想用的分隔符,默认为逗号,这里方便观察,我用了-

var str1 = [12,2,"hello"]; var str2 = ["world"]; console.log(str1.join("-"));        //12-2-hello console.log(str1);              //[12, 2, "hello"] 3:pop(); 功能:删除数组的最后一位,并且返回删除的数据,会改变原来的数组

var str1 = [12,2,"hello"]; console.log(str1.pop()        //hello console.log(str1);          //[12, 2] 4:shift(); 功能:删除数组的第一位数据,并且返回新数组的长度,会改变原来的数组

var str1 = [12,2,"hello"]; console.log(str1.shift());      //12 console.log(str1);           //[2,"hello"] 5:unshift(); 功能:在数组的首位新增一个或多数据,并且返回新数组的长度,会改变原来的数组 注意:unshift()方法返回的数据是新数组的长度,它增加的数据可以是一个也可以是多个,可以理解为增加一连串的数据,

var str1 = [12,2,"hello"]; var str2 = [43,2,"test"]; console.log(str1.unshift("你好"));              //4 console.log(str2.unshift("hello","world"));        //5 console.log(str1);                       //["你好", 12, 2, "hello"] console.log(str2);  6:push(); 功能:在数组的最后一位新增一个或多个数据,并且返回新数组的长度,会改变原来的数组 注意:push()方法返回的是数据是新数组的长度,它增加的数据可以是一个也可以是多个,可以理解为增加一连串的数据

var str1 = [12,2,"hello"]; var str2 = [43,2,"test"]; console.log(str1.push("你好"));          //4 console.log(str2.push("hello","world"));    //5 console.log(str1);                 //[12, 2, "hello","你好"] console.log(str2);                 //[43, 2, "test","hello", "world"] 7:reverse(); 功能:将数组的数据进行反转,并且返回反转后的数组,会改变原数组

var str1 = [12,2,"hello"]; console.log(str1.reverse());      //["hello", 2, 12] console.log(str1);            //["hello", 2, 12] 8:sort(); 功能:对数组内的数据进行排序(默认为升序),并且返回排过序的新数组,会改变原来的数组 注意: 8.1:这里的排序是针对字符的排序,先使用数组的toString()方法转为字符串,再逐位比较,3是大于12的,因为首位3>1,不要与Number型的数据排序混淆 8.2:str2数组中增加了三个字符,可以看到,比较的时候,zoom是最大的,因为首位的英文字母通过ASCII码可以转为相应的数值,再根据数值比较

var str1 = [12,2,43,5,2,5]; var str2 = [92,2,43,"hello",5,2,5,"abc","zoom"]; console.log(str1.sort());        //[12, 2, 2, 43, 5, 5] console.log(str1);            //[12, 2, 2, 43, 5, 5] console.log(str2.sort());        //[2, 2, 43, 5, 5, 92, "abc", "hello", "zoom"] console.log(str2);            //[2, 2, 43, 5, 5, 92, "abc", "hello", "zoom"] 8.3:排序问题 参数:sort(callback) 如果需要按照数值排序,需要传参。sort(callback),callback为回调函数,该函数应该具有两个参数,比较这两个参数,然后返回一个用于说明这两个值的相对顺序的数字(a-b)。其返回值如下: 若 a 小于 b,返回一个小于 0 的值。 若 a 等于 b,则返回 0。 若 a 大于 b,则返回一个大于 0 的值。

var str3 = [92,2,43,5,2,5];
console.log(str3.sort(fn));                 //[2, 2, 5, 5, 43, 92] console.log(str3);                      //[2, 2, 5, 5, 43, 92] function fn (a,b){     return a-b; } 9:slice(); 功能:截取指定位置的数组,并且返回截取的数组,不会改变原数组 参数:slice(startIndex, endIndex) 注意:可从已有的数组中返回选定的元素。该方法接收两个参数slice(start,end),strat为必选,表示从第几位开始;end为可选,表示到第几位结束(不包含end位),省略表示到最后一位;start和end都可以为负数,负数时表示从最后一位开始算起,如-1表示最后一位。

var arr = ["T1","J1","L1","L2","M1"]; console.log(arr.slice(1,3)); //["J1","L1"] console.log(arr.slice(1)); //["J1","L1","L2","M1"] console.log(arr.slice(-4,-1)); //["J1","L1","L2"] console.log(arr.slice(-2)); //["Lily","M1"] console.log(arr.slice(1,-2)); //["J1","L1"] console.log(arr); //["T1","J1","L1","L2","M1"] 10:splice() 功能:向数组中添加,或从数组删除,或替换数组中的元素,然后返回被删除/替换的元素。 参数:splice(start,num,data1,data2,…); 所有参数全部可选。第一个参数是小标,第二个是删除的长度,第一个参数可以为负数

var list = [1, 2, 3] console.log(list); // [1, 2, 3]

// 删除 list.splice(0,1); // 删除 -> 从下标为0开始,长度为1 console.log(list); // [2,3] list.splice(0,2); // 删除 -> 从下标为0开始,长度为2 console.log(list); // []

//替换 list.splice(0,1,4); // 替换 -> 从下标为0开始,长度为1的数组元素替换成4 console.log(list); // [4,2,3] list.splice(0,2,4); // 替换 -> 从下标为0开始,长度为2的数组元素替换成4(即4,2整体替换成4) console.log(list); // [4,3]

//添加 list.splice(1,0,5); // 表示在下标为1处添加一项5 console.log(list); // [1,5,2,3]

如果第一个参数为负数就从后面往前数,入上图 splice会改变原数组

11:toString(); 功能:将数组转换成字符串,类似于没有参数的join()。该方法会在数据发生隐式类型转换时被自动调用,如果手动调用,就是直接转为字符串。不会改变原数组

var str = [1,2,3]; console.log(str.toString()); //1,2,3 console.log(str); //[1,2,3] 12:valueOf(); 功能:返回数组的原始值(一般情况下其实就是数组自身),一般由js在后台调用,并不显式的出现在代码中

var str = [1,2,3]; console.log(str.valueOf()); //[1,2,3] console.log(str); //[1,2,3] //为了证明返回的是数组自身 console.log(str.valueOf() == str); //true 13:IndexOf(); 功能:根据指定的数据,从左向右,查询在数组中出现的位置,如果不存在指定的数据,返回-1,找到了指定的数据返回该数据的索引 参数:indexOf(value, start);value为要查询的数据;start为可选,表示开始查询的位置,当start为负数时,从数组的尾部向前数;如果查询不到value的存在,则方法返回-1 注意:如果找到该数据,立即返回该数据的索引,不再往后继续查找

var str = ["h","e","l","l","o"]; console.log(str.indexOf("l")); //2 console.log(str.indexOf("l",3)); //3 console.log(str.indexOf("l",4)); //-1 console.log(str.indexOf("l",-1)); //-1 console.log(str.indexOf("l",-3)); //2 14:lastIndexOf(); 功能:根据指定的数据,从左向右,lastIndexOf() 方法可返回一个指定的元素在数组中最后出现的位置,从该字符串的后面向前查找。如果不存在指定的数据,返回-1,找到了指定的数据返回该数据的索引 参数:indexOf(value, start);value为要查询的数据;start为可选,表示开始查询的位置,当start为负数时,从数组的尾部向前数;如果查询不到value的存在,则方法返回-1

var str = ["h","e","l","l","o"]; console.log(str.lastIndexOf("l")); // 根据我的发现,indexOf的第二个参数传进去有用,lastIndexOf第二个参数跟没传一样

15:forEach(); 功能:ES5新增的方法,用来遍历数组,没有返回值, 参数:forEach(callback);callback默认有三个参数,分别为value(遍历到的数组的数据),index(对应的索引),self(数组自身)。

var arr = ["Tom","Jack","Lucy","Lily","May"]; var a = arr.forEach(function(value,index,self){ console.log(value + "--" + index + "--" + (arr === self)); }) // 打印结果为: // Tom--0--true // Jack--1--true // Lucy--2--true // Lily--3--true // May--4--true console.log(a); //undefined---forEach没有返回值 //该方法为遍历方法,不会修改原数组 16:map(); 功能: 1.同forEach功能; 2.map的回调函数会将执行结果返回,最后map将所有回调函数的返回值组成新数组返回。 参数:map(callback);callback默认有三个参数,分别为value,index,self。跟上面的forEach()的参数一样

//功能1:同forEach var arr = ["Tom","Jack","Lucy","Lily","May"]; var a = arr.map(function(value,index,self){ console.log(value + "--" + index + "--" + (arr === self)) }) // 打印结果为: // Tom--0--true // Jack--1--true // Lucy--2--true // Lily--3--true // May--4--true

//功能2:每次回调函数的返回值被map组成新数组返回 var arr = ["Tom","Jack","Lucy","Lily","May"]; var a = arr.map(function(value,index,self){ return "hi:"+value; }) console.log(a); //["hi:Tom", "hi:Jack", "hi:Lucy", "hi:Lily", "hi:May"] console.log(arr); //["Tom", "Jack", "Lucy", "Lily", "May"]---原数组未改变

17:filter(); 功能:1.同forEach功能;2.filter的回调函数需要返回布尔值,当为true时,将本次数组的数据返回给filter,最后filter将所有回调函数的返回值组成新数组返回(此功能可理解为“过滤”)。 参数:filter(callback);callback默认有三个参数,分别为value,index,self。

//功能1:同forEach var arr = ["Tom","Jack","Lucy","Lily","May"]; var a = arr.filter(function(value,index,self){ console.log(value + "--" + index + "--" + (arr === self)) }) // 打印结果为: // Tom--0--true // Jack--1--true // Lucy--2--true // Lily--3--true // May--4--true

//功能2:当回调函数的返回值为true时,本次的数组值返回给filter,被filter组成新数组返回 var arr = ["Tom","Jack","Lucy","Lily","May"]; var a = arr.filter(function(value,index,self){ return value.length > 3; }) console.log(a); //["Jack", "Lucy", "Lily"] console.log(arr); //["Tom", "Jack", "Lucy", "Lily", "May"]---原数组未改变

18:every(); 功能:判断数组中每一项是否都满足条件,只有所有项都满足条件,才会返回true。 参数:every()接收一个回调函数作为参数,这个回调函数需要有返回值,every(callback);callback默认有三个参数,分别为value,index,self。 功能1:当回调函数的返回值为true时,类似于forEach的功能,遍历所有;如果为false,那么停止执行,后面的数据不再遍历,停在第一个返回false的位置。

//demo1: var arr = ["Tom","abc","Jack","Lucy","Lily","May"]; var a = arr.every(function(value,index,self){ console.log(value + "--" + index + "--" + (arr == self)) }) // 打印结果为: // Tom--0--true //因为回调函数中没有return true,默认返回undefined,等同于返回false

//demo2: var arr = ["Tom","abc","Jack","Lucy","Lily","May"]; var a = arr.every(function(value,index,self){ console.log(value + "--" + index + "--" + (arr == self)) return value.length < 4; }) // 打印结果为: // Tom--0--true // abc--1--true // Jack--2--true //因为当遍历到Jack时,回调函数到return返回false,此时Jack已经遍历,但是后面数据就不再被遍历了

//demo3: var arr = ["Tom","abc","Jack","Lucy","Lily","May"]; var a = arr.every(function(value,index,self){ console.log(value + "--" + index + "--" + (arr == self)) return true; }) // 打印结果为: // Tom--0--true // abc--1--true // Jack--2--true // Lucy--3--true // Lily--4--true // May--5--true //因为每个回调函数的返回值都是true,那么会遍历数组所有数据,等同于forEach功能

功能2:当每个回调函数的返回值都为true时,every的返回值为true,只要有一个回调函数的返回值为false,every的返回值都为false

//demo1: var arr = ["Tom","abc","Jack","Lucy","Lily","May"]; var a = arr.every(function(value,index,self){ return value.length > 3; }) console.log(a); //false

//demo2: var arr = ["Tom","abc","Jack","Lucy","Lily","May"]; var a = arr.every(function(value,index,self){ return value.length > 2; }) console.log(a); //true

19:some(); 功能:判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。 参数:some()接收一个回调函数作为参数,这个回调函数需要有返回值,some(callback);callback默认有三个参数,分别为value,index,self。 功能1:因为要判断数组中的每一项,只要有一个回调函数返回true,some都会返回true,所以与every正好相反,当遇到一个回调函数的返回值为true时,可以确定结果,那么停止执行,后面都数据不再遍历,停在第一个返回true的位置;当回调函数的返回值为false时,需要继续向后执行,到最后才能确定结果,所以会遍历所有数据,实现类似于forEach的功能,遍历所有。

//demo1: var arr = ["Tom","abc","Jack","Lucy","Lily","May"]; var a = arr.some(function(value,index,self){ console.log(value + "--" + index + "--" + (arr == self)) return value.length > 3; }) // 打印结果为: // Tom--0--true // abc--1--true // Jack--2--true

20.reduce(); 迭代数组的所有项,累加器,数组中的每个值(从左到右)合并,最终计算为一个值 参数: callback: previousValue 必选 --上一次调用回调返回的值,或者是提供的初始值(initialValue) currentValue 必选 --数组中当前被处理的数组项 index 可选 --当前数组项在数组中的索引值 array 可选 --原数组 initialValue: 可选 --初始值 实行方法:回调函数第一次执行时,preValue 和 curValue 可以是一个值,如果 initialValue 在调用 reduce() 时被提供,那么第一个 preValue 等于 initialValue ,并且curValue 等于数组中的第一个值;如果initialValue 未被提供,那么preValue 等于数组中的第一个值.

let arr = [0,1,2,3,4] let arr1 = arr.reduce((preValue, curValue) => preValue + curValue ) console.log(arr1) // 10 let arr2 = arr.reduce((preValue,curValue)=>preValue + curValue,5) console.log(arr2) // 15

arr.reduce()拓展(高级用法) (1)计算数组中每个元素出现的次数

let names = ['peter', 'tom', 'mary', 'bob', 'tom','peter']; let nameNum = names.reduce((pre,cur)=>{ if(cur in pre){ pre[cur]++ }else{ pre[cur] = 1 } return pre },{}) console.log(nameNum); //{ peter: 2, tom: 2, mary: 1, bob: 1 }

(2)数组去重

let arr = [1,2,3,4,4,1] let newArr = arr.reduce((pre,cur)=>{ if(!pre.includes(cur)){ return pre.concat(cur) }else{ return pre } },[]) console.log(newArr);// [1, 2, 3, 4]

(3)将多维数组转化为一维

let arr = [[0, 1], [2, 3], [4,[5,6,7]]] const newArr = function(arr){ return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[]) } console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]

21.reduceRight() 功能:(与reduce类似)从数组的最后一项开始,向前逐个遍历到第一位,迭代数组的所有项,然后构建一个最终返回的值。 参数:同reduce。 demo:同reduce

22 Array.from() 将伪数组变成数组,就是只要有length的就可以转成数组。 —es6

let str = '12345' console.log(Array.from(str)) // ["1", "2", "3", "4", "5"] let obj = {0:'a',1:'b',length:2} console.log(Array.from(obj)) // ["a", "b"] let aa= {0:'a',1:'b'} console.log(Array.from(aa)) // []

原来的不会发生改变

23 Array.of() 将一组值转换成数组,类似于声明数组 —es6

let str = '11' console.log(Array.of(str)) // ['11'] // 等价于 console.log(new Array('11')) // ['11]

ps:但是new Array()有缺点,就是参数问题引起的重载

console.log(new Array(2)) //[empty × 2] 是个空数组 console.log(Array.of(2)) // [2]

24 arr.copyWithin() 在当前数组内部,将制定位置的数组复制到其他位置,会覆盖原数组项,返回当前数组 参数: target --必选 索引从该位置开始替换数组项 start --可选 索引从该位置开始读取数组项,默认为0.如果为负值,则从右往左读。 end --可选 索引到该位置停止读取的数组项,默认是Array.length,如果是负值,表示倒数

let arr = [1,2,3,4,5,6,7] let arr1 = arr.copyWithin(1) console.log(arr1) // [1, 1, 2, 3, 4, 5, 6] let arr2 = arr.copyWithin(1,2) console.log(arr2) // [1, 2, 3, 4, 5, 6, 6] let arr3 = arr.copyWithin(1,2,4) console.log(arr3) // [1, 3, 4, 4, 5, 6, 6]

25 arr.find(callback) 找到第一个符合条件的数组成员

let arr = [1,2,3,4,5,2,4] let arr1 = arr.find((value, index, array) =>value > 2) console.log(arr1) // 3

26 arr.findIndex(callback) 找到第一个符合条件的数组成员的索引值

let arr = [1,2,3,4,5] let arr1 = arr.findIndex((value, index, array) => value > 3) console.log(arr1) // 3

27 arr.fill(target, start, end) 使用给定的值,填充一个数组,ps:填充完后会改变原数组 参数: target – 待填充的元素 start – 开始填充的位置-索引 end – 终止填充的位置-索引(不包括该位置)

let arr = [1,2,3,4,5] let arr1 = arr.fill(5) console.log(arr1) // [5, 5, 5, 5, 5] console.log(arr) // [5, 5, 5, 5, 5] let arr2 = arr.fill(5,2) console.log(arr2) let arr3 = arr.fill(5,1,3) console.log(arr3)

28 arr.includes() 判断数中是否包含给定的值

let arr = [1,2,3,4,5] let arr1 = arr.includes(2)
console.log(arr1) // ture let arr2 = arr.includes(9) console.log(arr2) // false let arr3 = [1,2,3,NaN].includes(NaN) console.log(arr3) // true

ps:与indexOf()的区别: indexOf()返回的是数值,而includes()返回的是布尔值 indexOf() 不能判断NaN,返回为-1 ,includes()则可以判断、

29 arr.keys() 遍历数组的键名

let arr = [1,2,3,4] let arr2 = arr.keys() for (let key of arr2) { console.log(key); // 0,1,2,3 }

30 arr.values() 遍历数组键值

let arr = [1,2,3,4] let arr1 = arr.values() for (let val of arr1) { console.log(val); // 1,2,3,4 }

31 arr.entries() 遍历数组的键名和键值

let arr = [1,2,3,4] let arr1 = arr.entries() for (let e of arr1) { console.log(e); // [0,1] [1,2] [2,3] [3,4] }

entries() 方法返回迭代数组。 迭代数组中每个值 前一个是索引值作为 key, 数组后一个值作为 value。

哪些数组方法会改变原数组 unshift(); push(); shift(); pop(); sort(); reverse(); splice(); copyWithin() fill() 这九个数组方法在上面都有过介绍了,可以看出,再用这些方法的时候,原数组是会被改变的。 ———————————————— 版权声明:本文为CSDN博主「小爱同学-Allen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/qq_34595425…

7、拓展运算符与rest剩余参数是什么意思,应用场景??? 1、扩展运算符简介 扩展运算符( spread )是三个点(…),可以将一个数组转为用逗号分隔的参数序列。

总的来说就是把一个大元素给打散成一个个单独的小元素。

基本用法:拆解字符串与数组

var array = [1,2,3,4]; console.log(...array);//1 2 3 4 var str = "String"; console.log(...str);//S t r i n g

2、扩展运算符应用 2.1 某些场景可以替代apply

在使用Math.max()求数组的最大值时,ES5可以通过 apply 做到(用一种不友好且繁琐的方式)

// ES5 apply 写法 var array = [1,2,3,4,3]; var max1 = Math.max.apply(null,array); console.log(max1);//4

幸运的是JavaScript的世界在不断改变,扩展运算符可用于数组的析构,优雅的解决了这个问题。

// ES6 扩展运算符 写法 var array = [1,2,3,4,3]; var max2 = Math.max(...array);
console.log(max2);//4

先把 array 打散成 1 2 3 4 3,再在里面找最大的那一个,就显而易见了。

2.2 代替数组的push、concat 等方法

实现把 arr2 塞到 arr1 中

// ES5 apply 写法 var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; Array.prototype.push.apply(arr1, arr2); //arr1 [0, 1, 2, 3, 4, 5]

扩展运算符又要施展化骨大法了

// ES6 扩展运算符 写法 var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; arr1.push(...arr2); //arr1 [0, 1, 2, 3, 4, 5]

通俗的解释下, 扩展运算符先把 arr2 打散成 3 4 5 , 之后再往arr1里push,就轻松多了。

同理可推,concat 合并数组的时候:

var arr1 = ['a', 'b']; var arr2 = ['c']; var arr3 = ['d', 'e'];

// ES5的合并数组 arr1.concat(arr2, arr3) // [ 'a', 'b', 'c', 'd', 'e' ]

// ES6的合并数组 [...arr1, ...arr2, ...arr3] // [ 'a', 'b', 'c', 'd', 'e' ]

ES5的合并数组写法,像是 arr1 把 arr2,arr3 给吸收了。

而ES6的合并数组写法,则是先把 arr1,arr2, arr3 拆解,之后塞到新的数组中。

2.3 拷贝数组或对象

//拷贝数组 var array0 = [1,2,3]; var array1 = [...array0]; console.log(array1);//[1, 2, 3]

//拷贝数组 var obj = { age:1, name:"lis", arr:{ a1:[1,2] } } var obj2 = {...obj}; console.log(obj2);//{age: 1, name: "lis", arr: {…}}

无论是像克隆数组还是对象,先用化骨绵掌之扩展运算符,将其打散,之后再拼装的到一起就可以了,多么简单易用。

2.4 将伪数组转化为数组

//伪数组转换为数组 var nodeList = document.querySelectorAll('div'); console.log([...nodeList]); // [div, div, div ... ]

上面代码中,querySelectorAll 方法返回的是一个 nodeList 对象。它不是数组,而是一个类似数组的对象。

这时,扩展运算符可以将其转为真正的数组,原因就在于 NodeList 对象实现了 Iterator。

注意:使用扩展运算符将伪数组转换为数组有局限性,这个类数组必须得有默认的迭代器且伪可遍历的。

3、rest 运算符简介 剩余运算符(the rest operator),它的样子看起来和展开操作符一样,但是它是用于解构数组和对象。在某种程

度上,剩余元素和展开元素相反,展开元素会“展开”数组变成多个元素,剩余元素会收集多个元素和“压缩”成一个

单一的元素。

说的通俗点,有点像吸星大法,收集多个元素,压缩成单一的元素 。

rest参数用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变

量将多余的参数放入数组中。

例如实现计算传入所有参数的和

使用arguments参数:

function sumArgu () { var result = 0; for (var i = 0; i < arguments.length; i++) { result += arguments[i]; } return result } console.log(sumArgu(1,2,3));//6

使用rest参数:

function sumRest (...m) { var total = 0; for(var i of m){ total += i; } return total; } console.log(sumRest(1,2,3));//6

上面代码利用 rest 参数,可以向该函数传入任意数目的参数。传递给 sumRest 函数的一组参数值,被整合成了数组 m。

就像是吸星大法,把分散的元素收集到一起。

所以在某些场景中,无需将arguments转为真正的数组,可以直接使用rest参数代替。

4、rest 运算符应用 4.1 rest 参数代替arguments变量

// arguments变量的写法 function sortNumbers() { return Array.prototype.slice.call(arguments).sort(); }

// rest参数的写法 const sortNumbers = (...numbers) => numbers.sort();

上面的两种写法,比较后可以发现,rest 参数的写法更自然也更简洁。

4.2 与解构赋值组合使用

var array = [1,2,3,4,5,6]; var [a,b,...c] = array; console.log(a);//1 console.log(b);//2 console.log(c);//[3, 4, 5, 6]

备注:rest参数可理解为剩余的参数,所以必须在最后一位定义,如果定义在中间会报错。

var array = [1,2,3,4,5,6]; var [a,b,...c,d,e] = array; // Uncaught SyntaxError: Rest element must be last element

5、总结 5.1 扩展运算符和rest运算符是逆运算

扩展运算符:数组=>分割序列

rest运算符:分割序列=>数组

5.2 扩展运算符应用场景

由于其繁琐的语法,apply 方法使用起来并不是很方便。当需要拿一个数组的元素作为函数调用的参数时,

扩展运算符是一个不错的选择。

扩展运算符还改善了数组字面量的操作,你可以更方便的初始化、连接、复制数组了。

使用析构赋值你可以提取数组的一部分。通过与迭代器协议的组合,你可以以一种更灵活的方式使用该表达式。

5.3 rest运算符应用场景

rest运算符主要是处理不定数量参数,rest参数使得收集参数变得非常简单。它是类数组对象arguments一个合理的替代品。

rest参数还可以与解构赋值组合使用。

在实际项目中灵活应用扩展运算符、rest运算符,能写出更精简、易读性高的代码。 ———————————————— 版权声明:本文为CSDN博主「Vicentekw」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/hkw20/artic…

8、ES6新增数据结构set和map是什么???它们中的哪一个可以实现数组去重及相关代码。 一、什么是set Set 是唯一值的集合,类似于数组。 一个 Set 可以容纳任何数据类型的任何值。 每个值在 Set 中只能出现一次,因此常用做数组去重。 另外想要了解其他数组去重的方法可以去看看我之前写的一篇文章,《【超全整理】JS数组去重到底有几种方法?》

Set 对象的几个常用方法和属性 new Set() 创建新的 Set 对象。 add() 向 Set 添加新元素。 clear() 从 Set 中删除所有元素。 delete() 删除由其值指定的元素。 has() 如果值存在则返回 true。 forEach() 为每个元素调用回调。 keys() 返回 Set 对象中值的数组。 size 返回元素个数。

类型转换 // Array 转 Set var mySet = new Set(["value1", "value2", "value3"]); // 用...操作符,将 Set 转 Array var myArray = [...mySet]; String // String 转 Set var mySet = new Set('hello'); // Set(4) {"h", "e", "l", "o"} // 注:Set 中 toString 方法不能将 Set 转换成 String

Set 对象作用 1.去重

var mySet = new Set([1, 2, 3, 4, 4]); [...mySet]; // [1, 2, 3, 4]

2.求并集

var a = new Set([1, 2, 3]); var b = new Set([4, 3, 2]); var union = new Set([...a, ...b]); // {1, 2, 3, 4}

3.求交集

var a = new Set([1, 2, 3]); var b = new Set([4, 3, 2]); var intersect = new Set([...a].filter(x => b.has(x))); // {2, 3}

4.求差集

var a = new Set([1, 2, 3]); var b = new Set([4, 3, 2]); var difference = new Set([...a].filter(x => !b.has(x))); // {1}

二、什么是map Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。 Map 对象记得键的原始插入顺序。 Map 对象具有表示映射大小的属性。

Map 对象的几个常用方法和属性 new Map() 创建新的 Map 对象。 set() 为 Map 对象中的键设置值。 get() 获取 Map 对象中键的值。 entries() 返回 Map 对象中键/值对的数组。 keys() 返回 Map 对象中键的数组。 values() 返回 Map 对象中值的数组。

Map对象的遍历 1.for…of var myMap = new Map(); myMap.set(0, "zero"); myMap.set(1, "one");

// 将会显示两个 log。 一个是 "0 = zero" 另一个是 "1 = one" for (var [key, value] of myMap) { console.log(key + " = " + value); } for (var [key, value] of myMap.entries()) { console.log(key + " = " + value); } /* 这个 entries 方法返回一个新的 Iterator 对象,它按插入顺序包含了 Map 对象中每个元素的 [key, value] 数组。 */

// 将会显示两个log。 一个是 "0" 另一个是 "1" for (var key of myMap.keys()) { console.log(key); } /* 这个 keys 方法返回一个新的 Iterator 对象, 它按插入顺序包含了 Map 对象中每个元素的键。 */

// 将会显示两个log。 一个是 "zero" 另一个是 "one" for (var value of myMap.values()) { console.log(value); } /* 这个 values 方法返回一个新的 Iterator 对象,它按插入顺序包含了 Map 对象中每个元素的值。 */

2.forEach() var myMap = new Map(); myMap.set(0, "zero"); myMap.set(1, "one");

// 将会显示两个 logs。 一个是 "0 = zero" 另一个是 "1 = one" myMap.forEach(function(value, key) { console.log(key + " = " + value); }, myMap)

Map 对象的操作 Map 与 Array的转换 var kvArray = [["key1", "value1"], ["key2", "value2"]];

// Map 构造函数可以将一个 二维 键值对数组转换成一个 Map 对象 var myMap = new Map(kvArray);

// 使用 Array.from 函数可以将一个 Map 对象转换成一个二维键值对数组 var outArray = Array.from(myMap);

Map 的克隆 var myMap1 = new Map([["key1", "value1"], ["key2", "value2"]]); var myMap2 = new Map(myMap1);

console.log(original === clone); // 打印 false。 Map 对象构造函数生成实例,迭代出新的对象。

Map 的合并 ar first = new Map([[1, 'one'], [2, 'two'], [3, 'three'],]); var second = new Map([[1, 'uno'], [2, 'dos']]);

// 合并两个 Map 对象时,如果有重复的键值,则后面的会覆盖前面的,对应值即 uno,dos, three var merged = new Map([...first, ...second]);

三、map和object的区别 二者都是以key-value的形式对数据进行存储;

1.key的数据类型范围不同 obj可以作为key的仅有number、string、symbol。 map均可以。

2.key的顺序不同。 obj通过obj.keys()打印出来的属性顺序是 number–字符串 map的key顺序是声明顺序。

3.创建方式不同。 obj有三种创建方式 字面量{}、new Object() 、构造函数。 map仅支持new Map()

4.key的调用不同。 map只能用原生的get方法调用。

5.设置属性的方式不同 map只能使用set(key,val)方法设置属性。

6.Size属性 map有size属性,对象没有。Map.size 返回 Map 中元素的数量,而 Object 的键值对个数只能手动计算 ———————————————— 版权声明:本文为CSDN博主「new个对象玩游戏」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/weixin_4404…

9、说一下你理解的promise、以及promise封装一个网络请求,核心代码??? 一、Promise 介绍 定义

Promise 是异步编程的一种解决方法,比传统的回调函数和事件更合理;它是由社区提出和实现经由 ES6 将其写进语言标准,并在原生提供了 Promise 对象; Promise 可以理解是一个容器,里面保存着某个将来才会结束的事件(异步操作)的结果;从语法上说,Promise 是一个对象通过它可以获取异步操作的消息;Promise 提供了统一的 API ,各种异步操作都可以用同样的方法进行处理。 特点

Promise 对象代表一个异步操作,对象的状态不受外界影响,有三种状态,pending(进行中)、fulfilled(已成功)、rejected(已失败);只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态; 一旦状态改变就不会再变,Promise 对象的状态改变,只有两种可能:从 pending 变为 fulfilled,从 pending 变为 rejected;如果改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果;这与事件(event)完全不同,事件的特点是:如果你错过了它,再去监听是得不到结果的; 构造函数 Promise 必须接收一个函数(handle)作为参数,函数又包含 resolve 和 reject ; then 、catch 支持链式调用; 缺点

Promise 无法取消:一旦新建就会执行,无法中途取消; 如果不设置回调函数,Promise 内部抛出的错误不会反应到外部; 当处于 pendding 状态时,无法知道目前进展到哪一个阶段; 场景

有效的解决 js 异步回调地狱问题; 将业务逻辑与数据处理分隔开使代码更优雅,方便阅读,更有利于代码维护; 基本用法

let p = new Promise(function(resolve,reject){ setTimeout(function(){ resolve('成功!'); },10) }).then(res=>{ console.log('成功!') }) ———————————————— 版权声明:本文为CSDN博主「三个木马人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/weixin_4329…

使用promise封装ajax请求

尚硅谷铁粉

于 2022-02-11 14:36:18 发布

3525 收藏 19 分类专栏: java 文章标签: ajax javascript 前端 版权

java 专栏收录该内容 108 篇文章4 订阅 订阅专栏

首先作为前端开发人员,大家都应该使用过Ajax发送请求,目前市面上流行的发送Ajax请求的方式为以下三种:

Jquery的$.ajax() 尤雨溪推荐的axios es6新出的fetch方法 这三种方法的区别详见文章ajax三种方式的区别,这里不再详细解释。

本篇文章主要讲工作中是如何使用ajax请求,也就是让ajax结合promise使用。

1.为什么要包装ajax? 小明同学说:“直接发送ajax请求不就得了,干嘛那么麻烦。”于是小明很顺畅的写下以下代码:

//以.ajax发送方式为例.ajax发送方式为例 .ajax({ type:"POST", url:"http://localhost:5000/login", data:{ username:"admin", password:"admin" }, dataType:"json", success:function (data) { console.log(data); }, error:function (err) { console.log(err); } }) 要知道,我们一个完整的项目势必会涉及到大量Ajax请求,如果我们每个请求都直接写Ajax请求,那么即使是请求同一个地址,只要发送的data参数产生了变化,就要重新写一遍ajax请求。很明显,这种写法会有以下几个缺点:

代码重复率很高,过于臃肿 代码可读性很差,不利于后期的维护 所以这种最"直接"的写法真所谓的费力不讨好,代码量变大,最后的效果反而不好,所以在工作中一定要避免重复劳动。前端培训

2.为什么要选择promise封装ajax? 看到上面的缺点,另外一位同学小刚说:“OK,我封装Ajax,但我直接用函数封装,不用Promise封装,那不是也可以避免重复劳动嘛。”于是小刚写下以下代码:

function ajax(url,data={},type="GET",callback){ $.ajax({ type:type, url:url, data:data, dataType:"json", success:function (data) { callback(data); } }) } let url="http://localhost:5000/login"; let data={ username:"admin", password:"admin" } function callback(data){ console.log(data) } ajax(url,data,"GET",callback); ajax(url,data,"POST",callback); 确实,直接用函数封装的写法可以克服重复书写Ajax的缺点,但是还是无法解决“回调地狱”的问题,也就是当如果有多个回调处理函数时,如:f1(f2(f3)),但是采用Promise封装ajax请求就可以完美解决这个问题,最后写出以下代码:

function ajax(url,data={},type="GET"){ return new Promise((resolve, reject) => { $.ajax({ type:type, url:url, data:data, dataType:"json", success:function (data) { resolve(data); }, error:function (err) { reject(err); } }) }) } let url="http://localhost:5000/login"; let data={ username:"admin", password:"admin" } let promise=ajax(url,data,"GET");//注意这里返回的是promise对象 promise.then(data=>{ //f1为第一个回调处理函数 f1(data); }).then(data2=>{ //f2为第二个回调处理函数 f2(data2); }).catch(err=>{ console.log(err); }) 一下这一行代码很重要,一定要记住:

return new Promise((resolve, reject) => {

})

———————————————— 版权声明:本文为CSDN博主「尚硅谷铁粉」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/zjjcchina/a…

10、说一下es6的导入导出如何使用??

ES6 的三种导入导出 2.1 默认导出和导入 默认导出的语法: export default {默认导出的成员}

    默认导入的语法: import 变量名称 from '模块路径'

导出文件.js

const a = 10 const b = 20 const fn = () => { console.log("模块内 - 箭头函数") }

// 导出 export default { // 导出对象,里面装集体的key和上面值 a, b:b, myFn:fn } 导入文件.js

// 注意: .js后缀名必须得写 -babel不会自动去添加后缀名 import Obj from "./导出文件.js" console.log(Obj) 补充:

如果在html文件使用 导入文件.js 的时候,需要注意:

1.使用模块的那个文件引入进来

2.浏览器对import支持性还不高,需要babel.js预处理(import翻译成浏览器认识的代码)后,再被浏览器执行

3.引入babel.js,给import代码的标签添加type='text/babel',告诉浏览器这个script代码要被babel处理后你再来执行

2.2 按需导出和导入 按需导出的语法: export const s1 = 10 export const 变量名 = 值(普通值/函数)

按需导入的语法: import {按需导入的名称} from '模块路径'

// 按需导出的方式 export const a = 10 export const b = 20 export const fn = () => { console.log("模块内 - 箭头函数") }

// 按需导入 // 补充: 可以用as关键字给变量起别名 import {fn as theFn,a} from './text6.js' console.log(theFn,a) 补充:

1.可以用as关键字给变量起别名

  1.  . 代表当前文件所在文件夹
    
     ./ 访问当前文件夹下的东西
    
     如果不写  ./  默认找同级目录下的这个文件
    

3.按需导入导出可以和默认导入导出同时在一个文件夹里使用,但是按需导入导出可以使用多次,默认导入导出只能使用一次

2.3 无变量直接导入一个模块 无导出.js

for(let i = 0, i < 10; i++) { console.log(i) }

// 无导出,就是一个普通要执行的模块 导入.js

import "./无导出.js"

// 目的:为了让模块文件执行一次 ———————————————— 版权声明:本文为CSDN博主「蓝爱人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/weixin_4641…