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)
一个盒子由四个部分组成:content、padding、border、margin
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)。
执行过程:
-
所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
-
遇到异步任务, 进入Event Table并注册回调函数; 等到指定的事件完成(如ajax请求响应返回, setTimeout延迟到指定时间)时,Event Table会将这个回调函数移入Event Queue。
-
当栈中的代码执行完毕,执行栈(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关键字给变量起别名
-
. 代表当前文件所在文件夹 ./ 访问当前文件夹下的东西 如果不写 ./ 默认找同级目录下的这个文件
3.按需导入导出可以和默认导入导出同时在一个文件夹里使用,但是按需导入导出可以使用多次,默认导入导出只能使用一次
2.3 无变量直接导入一个模块
无导出.js
for(let i = 0, i < 10; i++) {
console.log(i)
}
// 无导出,就是一个普通要执行的模块
导入.js
import "./无导出.js"
// 目的:为了让模块文件执行一次
————————————————
版权声明:本文为CSDN博主「蓝爱人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。