实训题目记录 --- 1

70 阅读45分钟

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分支上提交更改。

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

俗话说,实践出真知。现在,我们再练习一遍,先对 tt.txt做个修改,比如加上两行内容:

111

222

333

然后执行命令 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、标准盒模型与怪异(IE)盒模型的区别???

# 说说你对盒子模型的理解?

#简版

  • 盒子模型组成有 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>

1

2

3

4

5

6

7

8

当我们在浏览器查看元素时,却发现元素的大小变成了240px

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

  • W3C 标准盒子模型

  • IE 怪异盒子模型

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

#二、标准盒子模型

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

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

从上图可以看到:

  • 盒子总宽度 = width + padding + border + margin;

  • 盒子总高度 = height + padding + border + margin

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

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

#三、IE 怪异盒子模型

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

从上图可以看到:

  • 盒子总宽度 = width + margin;

  • 盒子总高度 = height + margin;

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

#Box-sizing

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

语法:


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

1

  • content-box 默认值,元素的 width/height 不包含 padding,border,与标准盒子模型表现一致

  • border-box 元素的 width/height 包含 padding,border,与怪异盒子模型表现一致

  • inherit 指定 box-sizing 属性的值,应该从父元素继承

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


<style>

  .box {

    width: 200px;

    height: 100px;

    padding: 20px;

    box-sizing: border-box;

  }

</style>

<div class="box">盒子模型</div>

1

2

3

4

5

6

7

8

9

这时候,就可以发现盒子的所占据的宽度为 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"];

1

2

3

也可以使用es6的扩展运算符,不会改变原数组

let str3 = [...str1,...str2]

1

** 2:join();**

功能:将数组转为字符串并返回转化的字符串数据,不会改变原来的数组;

注意:()中用双引号包括自己想用的分隔符,默认为逗号,这里方便观察,我用了-

var str1 = [12,2,"hello"];

var str2 = ["world"];

console.log(str1.join("-"));        //12-2-hello

console.log(str1);              //[12, 2, "hello"]

1

2

3

4

3:pop();

功能:删除数组的最后一位,并且返回删除的数据,会改变原来的数组

var str1 = [12,2,"hello"];

console.log(str1.pop()        //hello

console.log(str1);          //[12, 2]

1

2

3

4:shift();

功能:删除数组的第一位数据,并且返回新数组的长度,会改变原来的数组

var str1 = [12,2,"hello"];

console.log(str1.shift());      //12

console.log(str1);           //[2,"hello"]

1

2

3

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); 

1

2

3

4

5

6

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"]

1

2

3

4

5

6

7:reverse();

功能:将数组的数据进行反转,并且返回反转后的数组,会改变原数组

var str1 = [12,2,"hello"];

console.log(str1.reverse());      //["hello", 2, 12]

console.log(str1);            //["hello", 2, 12]

1

2

3

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"]

1

2

3

4

5

6

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;

}

1

2

3

4

5

6

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"]

1

2

3

4

5

6

7

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]

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

如果第一个参数为负数就从后面往前数,入上图

splice会改变原数组

11:toString();

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

var str = [1,2,3];

console.log(str.toString()); //1,2,3

console.log(str); //[1,2,3]

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

1

2

3

4

5

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

1

2

3

4

5

6

14:lastIndexOf();

功能:根据指定的数据,从左向右,lastIndexOf() 方法可返回一个指定的元素在数组中最后出现的位置,从该字符串的后面向前查找。如果不存在指定的数据,返回-1,找到了指定的数据返回该数据的索引

参数:indexOf(value, start);value为要查询的数据;start为可选,表示开始查询的位置,当start为负数时,从数组的尾部向前数;如果查询不到value的存在,则方法返回-1

var str = ["h","e","l","l","o"];

console.log(str.lastIndexOf("l")); //3

1

2

根据我的发现,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没有返回值

//该方法为遍历方法,不会修改原数组

1

2

3

4

5

6

7

8

9

10

11

12

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"]---原数组未改变

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

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"]---原数组未改变

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

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功能

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

功能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

1

2

3

4

5

6

7

8

9

10

11

12

13

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

1

2

3

4

5

6

7

8

9

10

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

1

2

3

4

5

6

7

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 }

1

2

3

4

5

6

7

8

9

10

(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]

1

2

3

4

5

6

7

8

9

(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]

1

2

3

4

5

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)) // []

1

2

3

4

5

6

原来的不会发生改变

23 Array.of()

将一组值转换成数组,类似于声明数组 —es6

let str = '11'

console.log(Array.of(str)) // ['11']

// 等价于

console.log(new Array('11')) // ['11]

1

2

3

4

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

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

console.log(Array.of(2)) // [2]

1

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]

1

2

3

4

5

6

7

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

1

2

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

1

2

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)

1

2

3

4

5

6

7

8

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

1

2

3

4

5

6

7

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

}

1

2

3

4

5

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

}

1

2

3

4

5

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]

}

1

2

3

4

5

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

1

2

3

4

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

1

2

3

4

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

// ES6 扩展运算符 写法

var array = [1,2,3,4,3];

var max2 = Math.max(...array);

console.log(max2);//4

1

2

3

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]

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]

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' ]

1

2

3

4

5

6

7

8

9

10

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: {…}}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

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

2.4 将伪数组转化为数组

//伪数组转换为数组

var nodeList = document.querySelectorAll('div');

console.log([...nodeList]); // [div, div, div ... ]

1

2

3

上面代码中,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

1

2

3

4

5

6

7

8

使用rest参数:

function sumRest (...m) {

var total = 0; 

for(var i of m){

    total += i;

}

return total;

}

console.log(sumRest(1,2,3));//6

1

2

3

4

5

6

7

8

上面代码利用 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();

1

2

3

4

5

6

7

上面的两种写法,比较后可以发现,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]

1

2

3

4

5

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

var array = [1,2,3,4,5,6];

var [a,b,...c,d,e] = array;

// Uncaught SyntaxError: Rest element must be last element

1

2

3

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

1

2

3

4

5

6

7

8

Set 对象作用

1.去重

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

[...mySet]; // [1, 2, 3, 4]

1

2

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}

1

2

3

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}

1

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}

1

2

3

二、什么是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 对象中每个元素的值。 */

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

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)

1

2

3

4

5

6

7

8

Map 对象的操作

Map 与 Array的转换

var kvArray = [["key1", "value1"], ["key2", "value2"]];

// Map 构造函数可以将一个 二维 键值对数组转换成一个 Map 对象

var myMap = new Map(kvArray);

// 使用 Array.from 函数可以将一个 Map 对象转换成一个二维键值对数组

var outArray = Array.from(myMap);

1

2

3

4

5

6

7

Map 的克隆

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

var myMap2 = new Map(myMap1);

console.log(original === clone);

// 打印 false。 Map 对象构造函数生成实例,迭代出新的对象。

1

2

3

4

5

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]);

1

2

3

4

5

三、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({

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…