1.CSS的盒子模型
包含元素内容content
、内边距padding
、边框border
、外边距margin
box-sizing
:border-box
;content-box
;inherit
;
1) content-box
:总宽度=margin+border+padding+width
,即为标准模型;
2) border-box
:总宽度=margin+width
,即为IE模型;
3) inherit
:继承父元素的border-sizing
属性。
2.常见的post提交数据方式对应的content-type取值
4
种
1)application/x-www-form-urlencoded
:数据被编码为名称/值对,这是标准的编码格式。
2)multipart/form-data
:数据被编码为一条消息,页上的每个控件对应消息中的一个部分。
3)application/json
:告诉服务端消息主体是序列化后的 JSON
字符串.
4)text/xml
3.清除浮动的几种方法
1)父级div
定义伪类:after
和zoom
`.clearfloat::after {display:block; clear:both; content:" "; visibility:hidden; height:0;}
.clearfloat {zoom:1}`
2)在结尾处添加空div
标签clear:both
3)父级div
定义height
4)父级div
定义display:table
5)父级div
也一起浮动
6)父级div
定义overflow:auto/hidden
(必须定义width
或zoom:1
,同时不能定义height
,浏览器会自动检查浮动区域的高度)
4.移动端上click事件在某些浏览器有没有遇到延迟的问题
1)静止缩放<meta name="viewport" content="width=device-width user-scalable='no' ">
或<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
2)引入`fastclick.jswindow.addEventListen
er(function(){
FastClick.attach(document.body);
1},false)`
5.HTTP的缓存机制
1)强制缓存:当所请求的数据在缓存数据库中尚未过期时,不与服务器进行交互,直接使用缓存数据库中的数据。Expire / Cache-Control
2)协商缓存:从缓存数据库中取出缓存的标识,然后向浏览器发送请求验证请求的数据是否已经更新,如果已更新则返回新的数据,若未更新则使用缓存数据库中的缓存数据。etag / last-modifind
6.实现三栏布局(左右两边固定宽度,中间自适应)
1)浮动布局
左右两边固定宽度,并分别设置float:left
和float:right
。(但这会带来高度塌陷的问题,所以要清除浮动。清除浮动的方式有:
a. 给父级盒子设置height
;
b.给父级盒子设置overflow:hidden
;
c.在父级盒子结束前的盒子添加clear:both
;
d.父级盒子也设置浮动;
e.父级div
定义伪类:after
和zoom
,
.clear::after{display:block;clear:both;content:"";visibility:hidden;height:0;}
.clear{zoom:1;}
2)绝对定位布局
左中右三个盒子都设置position:absolute
;然后分别设置定位
3)flex
布局
父盒子设置display:flex
;位于中间的子盒子设置flex:1
4)表格布局
父盒子设置display:table
;左中右三个盒子设置display:table-cell
;左右两个盒子分别设置宽度;
5)网格布局
父盒子设置display:grid
; grid-template-columns:300px auto 300px
;
7.== 和 === 的区别
===
为恒等符:当等号两边的值为相同类型的时候,直接比较等号两边的值,值相同则返回true
,若等号两边的值类型不同时直接返回false
。
==
为等值符: 当等号两边的值为相同类型时比较值是否相同,类型不同时会发生类型的自动转换,转换为相同的类型后再作比较。
a、如果一个是null
、一个是undefined
,那么相等。
b、如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。
c、如果任一值是 true
,把它转换成 1
再比较;如果任一值是 false
,把它转换成 0
再比较。
d、如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString
或者valueOf
方法。 js
核心内置类,会尝试valueOf
先于toString
;例外的是Date
,Date
利用的是toString
转换。那些不是JavaScript
语言核心中的对象则通过各自的实现中定义的方法转换为原始值。
e、任何其他组合,都不相等。
8.transition和animation
transition
1)语法transition
是一个复合属性,可设置四个过渡属性,简写方式如下:transition{ transition-property transition-duration transition-timing-function transition-delay}
transition-property
:是用来指定当元素其中一个属性改变时执行transition
效果,值有none
(没有属性改变)、all
(默认值,所有属性改变),indent
(某个属性名,一条transition
规则,只能定义一个属性的变化,不能涉及多个属性,如果要设置多个属性时,需分别设置,中间以逗号隔开)【当其值为none
时,transition
马上停止执行,当指定为all
时,则元素产生任何属性值变化时都将执行transition
效果】;transition-duration
:过度时间,是用来指定元素转换过程的持续时间,单位为s
(秒)或ms
(毫秒);transition-timing-function
:时间函数,根据时间的推进去改变属性值的变换速率,值ease
(逐渐变慢)、linear
(匀速)、ease-in
(加速)、ease-out
(减速)、ease-in-out
(加速然后减速)、cubic-bezier
:(自定义一个时间曲线);transition-delay
:延迟,指定一个动画开始执行的时间,也就是当改变元素属性值后多长时间开始执行transition
效果,单位为s
(秒)或ms
(毫秒);
2)触发方式
伪类触发::hover,:focus,:checked,:active
js
触发:toggleClass
3)以下情况下,属性值改变不能产生过渡效果
a.background-image
,如url(a.jpg)
到url(b.jpg)
(与浏览器支持相关,有的浏览器不支持)等
b.float
浮动元素
c.height
或width
使用auto
值
d.display
属性在none
和其他值(block、inline-block、inline
)之间变换
e.position
在static
和absolute
之间变换transition
示例:
<style>
#box2{
height: 100px;
100px;
background: blue;
}
#box2:hover{
transform: rotate(180deg) scale(.5, .5);
background: red;
transition: background 2s ease, transform 2s ease-in 1s;}
</style>
</head>
<body>
<div id="box1">BOX1</div>
<div id="box2">BOX2</div>
</body>
animation
1)语法animation{ animation-name animation-duration animatino-timing-function animation-delay animation-iteration-count animation-direction animtion-play-state animation-fill-mode}
animation-name
:用来调用@keyframes定义好的动画,与@keyframes定义的动画名称一致;animation-duration
:指定元素播放动画所持续的时间;animation-timing-function
:和transition
中的transition-timing-function
中的值一样。根据上面的@keyframes
中分析的animation
中可能存在多个小动画,因此这里的值设置是针对每一个小动画所在所在时间范围内的属性变换速率;animation-delay
:定义在浏览器开始执行动画之前的等待的时间、这里是指整个animation
执行之前的等待时间,而不是上面所说的多个小动画;animation-iteration-count
:定义动画的播放次数,通常是整数,默认是1
,若为infinity
,动画将无限多次的播放;animation-direction
:主要用来设置动画播放次数,其主要有两个值:normal
:默认值,动画每次训话都是按顺序播放;alternate
:动画播放在第偶数次向前播放,第奇数次想反方向播放(animation-iteration-count
取值大于1
时设置有效)animation-play-state
:属性用来控制元素动画的播放状态。主要有两个值:running
:可以通过该值将暂停的动画重新播放,这里的重新播放不是从元素动画的开始播放,而是从暂停的那个位置开始播放;paused:
暂停播放。animation-fill-mod
: 默认情况下,动画结束后,元素的样式将回到起始状态,animation-fill-mode
属性可以控制动画结束后元素的样式。主要具有四个属性值:none
(默认,回到动画没开始时的状态。),forwards
(动画结束后动画停留在结束状态),backwords
(动画回到第一帧的状态),both
(根据animation-direction
轮流应用forwards
和backwards
规则)。animation
示例:
<style>
.box{height:100px;100px;border:15px solid black;
animation: changebox 10s ease-in-out 3 alternate paused;
}
.box:hover{
animation-play-state: running;
}
@keyframes changebox {
10% { background:red; }
50% { 80px; }
70% { border:15px solid yellow; }
100% { 180px; height:180px; }
}
</style>
<body>
<div class="box"></div>
</body>
9.事件冒泡 事件捕获
事件冒泡,事件会从最内层的元素开始发生,一直向上传播,直到document
对象;
事件捕获则跟事件冒泡相反,事件会从document
对象开始发生,直到最具体的元素;
10.GET和POST的区别
1.发送方式:GET
请求数据放在url
上,即HTTP
的协议头中;而POST
把数据放在HTTP
的包体中。
2.大小的限制:GET
传的参数有长度的限制,因为浏览器对url
的长度有限制;而POST理论上是没有限制的。
3.安全性:GET
请求可被缓存,请求保存在浏览器的历史记录中;POST
则不能被缓存。与POST
相比,GET
的安全性较差,因为发送的数据是URL
的一部分。
11.var的变量提升的底层原理是什么?
JS
引擎的工作方式是
1)先解析代码,获取所有被声明的变量;
2)然后再执行。
也就是分为预处理和执行这两个阶段。
变量提升:所有用var
声明变量的语句都会被提升到代码头部。另外function
也可看作变量声明,也存在变量提升的情况。
12.垂直水平居中的方式?
1)定位
父元素设置为:position: relative
;
子元素设置为:position: absolute
;
距上50%
,据左50%
,然后减去元素自身宽度的距离就可以实现
100px;
height: 100px;
position: absolute;
left: 50%;
top: 50%;
margin: -50px 0 0 -50px;
2)flex布局
display: flex; //flex布局
justify-content: center; //使子项目水平居中
align-items: center; //使子项目垂直居中
3)tabel-cell
display: table-cell;
vertical-align: middle;//使子元素垂直居中
text-align: center;//使子元素水平居中
13.如何判断一个对象是否为数组
1) Array.prototype.isPrototypeOf(obj)
方法,判定Array
是不是在obj
的原型链中,如果是,则返回true
,否则false
;
2) obj instanceof Array
;
3) Object.prototype.toString.call(obj);(==="[object Array]")
4) Array.isArray(obj)
;
14.margin塌陷?
当两个盒子在垂直方向上设置margin
值时,会出现塌陷现象
解决方法:
1.给父盒子添加border
2.给父盒子添加padding-top
3.给父盒子添加overflow:hidden
4.父盒子:position:fixed
5.父盒子:display:table
6.给子元素的前面添加一个兄弟元素
属性为:content:"";
overflow:hidden;
解决方法的主要原理就是设置盒子为BFC
BFC
为页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
15.伪类与伪元素的区别
1)伪类
伪类用于选择DOM
树之外的信息,或是不能用简单选择器进行表示的信息。前者包含那些匹配指定状态的元素,比如:link,:visited,:hover,:active
;后者包含那些满足一定逻辑条件的DOM树中的元素,比如:first-child,:first-of-type,:target
。
2)伪元素
伪元素为DOM
树没有定义的虚拟元素。不同于其他选择器,它不以元素元素为最小选择单元,它选择的是元素制定单元。比如::before
表示选择元素内容的之前内容;::selection
表示选择元素被选中的内容。
3)伪类/伪元素一览表
<伪类如下>
/*
:active 选择正在被激活的元素
:hover 选择被鼠标悬浮着元素
:link 选择未被访问的元素
:visited 选择已被访问的元素
:first-child 选择满足是其父元素的第一个子元素的元素
:lang 选择带有指定 lang 属性的元素
:focus 选择拥有键盘输入焦点的元素
:enable 选择每个已启动的元素
:disable 选择每个已禁止的元素
:checked 选择每个被选中的元素
:target 选择当前的锚点元素
*/
<伪元素如下>
/*
::first-letter 选择指定元素的第一个单词
::first-line 选择指定元素的第一行
::after 在指定元素的内容后面插入内容
::before 在指定元素的内容前面插入内容
::selection 选择指定元素中被用户选中的内容
*/
16.介绍一下JS的基本数据类型
Undefined,Null,Boolean,Number,String
17.JavaScript的typeof返回那些数据类型
undefined,string,boolean,number,symbol(ES6),object,function
18.介绍一下JS有哪些内置对象?
数据封装类对象:Object、Array、Boolean、Number、String
其他对象:Function、Argument、Math、Date、RegExp、Error
19.null和undefined的区别
1)null
表示一个对象被定义了,值为“空值”;undefined
表示不存在这个值。
2)变量被定义了,但是没有赋值时,就等于undefined
。
3)注意:在验证null
时,要用===
,因为==
无法区分null
和undefined
。typeof null // "object"
说明:null
是一个没有任何属性和方法的对象
20.对JSON的了解
1) JSON(JavaScript Object Notation)
是一种轻量级的数据交换格式。
2) 它是基于JavaScript
的一个子集。数据格式简单,易于读写,占用带宽小。 如:{"age":"12", "name":"back"}
21.列举3种强制类型转换和2种隐式类型转换
强制:parseInt(),parseFloat(),Number()
,(Boolean(),String()
)
隐式:==
,!
22.input的type属性有哪些?
text
:文本框password
:密码radio
:单选按钮checkbox
:复选框file
:文件选择域hidden
:隐藏域button
:按钮reset
:重置按钮submit
:表单提交按钮image
:图片按钮
23.IE和标准下有哪些兼容性的写法
var ev = ev || window.event
document.documentElement.clientWidth || document.body.clientWidth
var target = ev.srcElement||ev.target
24.如何阻止事件冒泡
ie
:阻止冒泡ev.cancelBubble = true
;
非IE
ev.stopPropagation()
;
25.如何阻止默认事件
1)return false
;2) ev.preventDefault()
;
26.说说前端中的事件流?
事件流描述的是从页面接收事件的顺序,DOM2
级事件流包括下面几个阶段。
事件捕获阶段
处理事件阶段
事件冒泡阶段
(addEventListener
:addEventListener
是DOM2
级事件新增的指定事件处理程序的操作,这个方法接收3
个参数:要处理的事件名,作为事件处理程序的函数和一个布尔值。最后的布尔值如果为true
,表示在捕获阶段调用事件处理程序;如果为false
,表示在冒泡阶段调用事件处理程序,默认为false
)
27.如何实现一个自适应的正方形
1)CSS 3vw
单位CSS3
中新增了一组相对于可视区域百分比的长度单位vw、vh、vmin、vmax
。其中vw
是相对于视口宽度百分比的单位,1vw=1%viewport width
,vh
是相对于视口高度百分比的单位,1vh=1%viewport height
;vmin
是相对于当前视口宽高中较小的一个的百分比单位,同理vmax
是相对当前视口宽高中较大的一个百分比单位。
代码实现:
.placeholder{
50vw;
height: 50vw;
}
优点:简洁方便
缺点:浏览器兼容不好
2)设置垂直方向的 padding
撑开容器margin、padding
的百分比数值是相对于父元素宽度计算的。由此可以发现只需要将元素垂直方向的padding
值设定为与width
相同的百分比就可以制作出自适应正方形了:
代码实现:
.placeholder{
100%;
padding-bottom:100%;
}
如果正方形中没有内容(相当于只是一个几何里面的正方形,并没有展示其他任何内容),一切看起来都很正常;但是,如果正方形中有其他内容(这种情况会更常见一些,比如说有一些文本和图片),此时容器的高度就会被拉伸,因为盒子模型中的padding
是不包含在 content
中的,所以我们可以通过 height:0
解决这个问题;这种方案简洁明了,且兼容性好;但是除了填充内容后会出现问题以外,还有可能碰上max-height
不收缩,于是第三种方案来了:
3)利用伪元素的margin(padding)-top
撑开容器
在方案二中,我们利用百分比数值的 padding-bottom
属性撑开容器内部空间,但是这样做会导致在元素上设置的 max-height
属性失效;而失效的原因是 max-height
属性只限制于 height
,也就是只会对元素的 content height
起作用。那么我们是不是能用一个子元素撑开 content
部分的高度,从而使 max-height
属性生效呢?我们来试试:
.placeholder {
20%;
background-color: #000;
/* overflow: hidden; */
/* display: inline-block; */
float: left;
/*设置成BFC才能使margin-top撑起高度*/
}
.placeholder:after {
content: '';
display: block;
margin-top: 100%;
/* margin 百分比相对父元素宽度计算 */
}
28.js中的位置关系
offsetParent
:该属性返回一个对象的引用,这个对象是距离调用offsetParent
的元素最近的(在包含层次中最靠近的),已进行过CSS
定位的容器元素。 如果这个容器元素未进行CSS
定位, 则offsetParent
属性的取值为body
元素的引用。 当容器元素的style.display
被设置为 "none"
时(译注:IE
和Opera
除外),offsetParent
属性 返回 null
。top
:该属性一般对用过css
定位的元素有效(position
为“static”
时为auto
,不产生效果),定义了一个top
属性有效的元素(即定位元素)的上外边距边界与其包含块上边界之间的偏移。clientTop
:元素上边框的厚度,当没有指定边框厚底时,一般为0
。scrollTop
:位于对象最顶端和窗口中可见内容的最顶端之间的距离,简单地说就是滚动后被隐藏的高度。offsetTop
:获取对象相对于由offsetParent
属性指定的父坐标(css
定位的元素或body
元素)距离顶端的高度。clientHeight
:内容可视区域的高度,也就是说页面浏览器中可以看到内容的这个区域的高度,一般是最后一个工具条以下到状态栏以上的这个区域,与页面内容无关。scrollHeight
:IE
、Opera
认为 scrollHeight
是网页内容实际高度,可以小于clientHeight
。FF
认为scrollHeight
是网页内容高度,不过最小值是 clientHeight
。offsetHeight
:获取对象相对于由offsetParent
属性指定的父坐标(css
定位的元素或body
元素)的高度。IE
、Opera
认为 offsetHeight
= clientHeight
+ 滚动条 + 边框。FF
认为 offsetHeight
是网页内容实际高度,可以小于clientHeight
。offsetHeight
在新版本的FF和IE中是一样的,表示网页的高度,与滚动条无关,chrome
中不包括滚动条。
*诸如left、clientLeft、offsetLeft、clientWidth、scrollWidth等,和top、height类似,不再赘述。
clientX
、clientY
:相对于浏览器窗口可视区域的X
,Y
坐标(窗口坐标),可视区域不包括工具栏和滚动条。IE
事件和标准事件都定义了这2
个属性。pageX
、pageY
:类似于event.clientX
、event.clientY
,但它们使用的是文档坐标而非窗口坐标。这2
个属性不是标准属性,但得到了广泛支持。IE
事件中没有这2
个属性。offsetX
、offsetY
:相对于事件源元素(target
或srcElement
)的X
,Y
坐标,只有IE
事件有这2
个属性,标准事件没有对应的属性。screenX
、screenY
:相对于用户显示器屏幕左上角的X
,Y
坐标。标准事件和IE
事件都定义了这2
个属性
29.Doctype
作用? 严格模式与混杂模式如何区分?它们有何意义?
Doctype
声明于文档最前面,告诉浏览器以何种方式来渲染页面,这里有两种模式,严格模式和混杂模式。
严格模式的排版和 JS
运作模式是 以该浏览器支持的最高标准运行。
混杂模式,向后兼容,模拟老式浏览器,防止浏览器无法兼容页面。
30.link
标签和import
标签的区别?
link
属于html
标签,而@import
是css
提供的
页面被加载时,link
会同时被加载,而@import
引用的css
会等到页面加载结束后加载。link
是html
标签,因此没有兼容性,而@import
只有IE5
以上才能识别。link
方式样式的权重高于@import
的。
31.元素的文本省略号?
单行:
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap
多行:
1)直接用css
属性设置(只有-webkit内核才有作用)
display: -webkit-box
-webkit-box-orient:vertical
-webkit-line-clamp:3
overflow:hidden
移动端浏览器绝大部分是WebKit
内核的,所以该方法适用于移动端;-webkit-line-clamp
用来限制在一个块元素显示的文本的行数,这是一个不规范的属性(unsupported WebKit property
),它没有出现在 CSS
规范草案中。display: -webkit-box
将对象作为弹性伸缩盒子模型显示 。-webkit-box-orient
设置或检索伸缩盒对象的子元素的排列方式 。text-overflow: ellipsis
以用来多行文本的情况下,用省略号“…”
隐藏超出范围的文本。
32.XML和JSON的区别?
1)数据体积方面JSON
相对于XML
来讲,数据的体积小,传递的速度更快些
2)数据描述方面JSON
和JavaScript
交互更加方便,更容易解析处理,更容易交互
3)数据描述方面JSON
对数据的描述性比XML
差
4)传输速度方面JSON
的速度要远远快于XML
33.前端需要注意哪些SEO?
合理的title
、description
、keywords
:搜索对着三项的权重逐个减少,title
值强调重点即可,重要关键词不要超过两次,而且要靠前,不同页面的title
要有所不同;description
把页面的内容高度概括,长度合适,不可过分分堆砌关键词,不同页面的description
有所不同;keywords
列举重要关键词即可;
// title标题
<title>标题</title>
// keywords 关键词
<meta name="description" content="关键词1,关键词2,关键词3">
// description 内容摘要
<meta name="description" content="网页的简述">
语义化的HTML
代码,符合W3C
规范:语义化代码让搜索引擎容易理解网页;
重要内容的HTML
代码放在最前:搜索引擎抓取HTML
顺序是从上到下,有的搜索引擎对抓取长度有限制,所以要保证重要内容一定会被抓取;
重要内容不要用JS
输出:爬虫不会执行JS
获取内容;
少用iframe
:搜索引擎不会抓取iframe
中的内容;
非装饰性图片必须加alt
;
提高网站速度:网站速度是搜素引擎排序的一个重要指标;
34.HTTP的几种请求方法用途?
1)GET
方法
发送一个请求来取得服务器上的某一资源
2)POST
方法
向URL
指定的资源提交数据或附加新的数据
3)PUT
方法
跟POST
方法很像,也是想服务器提交数据。但是,它们之间有不同。PUT
指定了资源在服务器上的位置,而POST
没有
4)HEAD
方法
只请求页面的首部
5)DELETE
方法
删除服务器上的某资源
6)OPTIONS
方法
它用于获取当前URL
所支持的方法。如果请求成功,会有一个Allow
的头包含类似“GET,POST”
这样的信息
7)TRACE
方法TRACE
方法被用于激发一个远程的,应用层的请求消息回路
8)CONNECT
方法
把请求连接转换到透明的TCP/IP
通道
35.如何进行网页性能优化?
1)content
方面
减少HTTP
请求:合并文件、CSS精灵图
减少DNS
查询:DNS缓存、将资源分布到恰当数量的主机名
减少DOM
元素数量
2)Server
方面
使用CDN
配置ETag
对组件使用Gzip
压缩
3)Cookie
方面
减少cookie
大小
4)CSS
方面
将样式表放到页面顶部
不使用CSS
表达式
使用<link>
不使用@import
5)JavaScript
方面
将脚本放到页面底部
将JavaScript
和CSS
从外部引入
压缩JavaScript
和CSS
删除不需要的脚本
减少DOM
访问
6)图片方面
优化CSS
精灵
不要再HTML
中拉伸图片
36.语义化的理解
HTML
语义化就是让页面的内容结构化,便于对浏览器、搜索引擎解析;
在没有CSS
样式情况下也以一种文档格式显示,并且是容易阅读的;
搜索引擎的爬虫依赖于标记来确定上下文的各个关键字的权重,利于SEO
;
使阅读源代码的人更容易将网站分块,便于阅读维护理解;
37.WEB标准以及W3C标准是什么
标签闭合、标签小写、不乱嵌套、使用外链CSS
和JS
、结构行为表现的分离
38.说说对作用域链的理解
作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window
对象即被终止,作用域链向下访问变量是不被允许的;
即作用域就是变量与函数的可访问范围,即作用域控制这变量与函数的可见性和生命周期;
39.原生JS都有哪些方式可以实现两个页面间的通信?
1)通过url
地址栏传递参数;
例如:点击列表中的每一条数据,跳转到一个详情页面,在URL
中传递不同的参数区分不同的页面;
2)通过本地存储cookie
、localStorage
、sessionStorage
;
例如京东的登陆,把登陆后获得的页面信息存储到本地,其他页面需要用户信息的话就从本地的存储数据中获取;
3)使用iframe
例如在A
页面中嵌入B
页面,在A
中可以通过一些属性和实现方法和B
页面的通信;
4)利用postMessage
实现页面间的通信
例如父窗口往子窗口传递信息,子窗口往父窗口传递信息
40.ES6中的let,const,var的区别是什么?
var
:声明全局常量;let
:声明块级常量,即局部常量,定以后可以修改;const
:用于声明常量,定义后不能再修改值或者引用值的常量,也具有块级作用域;
41.对数组进行去重,es5或者es6方法
//es5四种方式:
//方式一:
Array.prototype.unique1 = function() {
// 1. 定义数组
var temp = [];
// 2. 遍历当前数组
for(var i = 0; i < this.length; i++) {
// 3.如果当前数组的第i已经保存进了临时数组,
// 那么跳过,否则把当前项push到临时数组里面
if (-1 === temp.indexOf(this[i])) {
temp.push(this[i]);
}
}
return temp;
};
//方式二:
Array.prototype.unique2 = function() {
//1. hash为hash表,r为临时数组
var hash = {}, temp=[];
// 2.遍历当前数组
for(var i = 0; i < this.length; i++)
{
// 3. 如果hash表中没有当前项
if (!hash[this[i]])
{
// 4.存入hash表
hash[this[i]] = true;
// 5.把当前数组的当前项
// push到临时数组里面
temp.push(this[i]);
}
}
return temp;
};
//方式三:
Array.prototype.unique3 = function() {
var n = [this[0]];
for(var i = 1; i < this.length; i++){
if (this.indexOf(this[i]) === i) {
n.push(this[i]);
}
}
return n;
};
//方式四:
Array.prototype.unique4 = function() {
this.sort();
var re=[this[0]];
for(var i = 1; i < this.length; i++)
{
if( this[i] !== re[re.length-1])
{
re.push(this[i]);
}
}
return re;
};
//es6实现方式:
Array.prototype.unique =
Array.prototype.unique
|| function () {
return [...new Set(this)];
};
42.页面加载过程中可能触发哪些事件?它们的顺序是?
页面加载时,大致可以分为以下几个步骤:
1)开始解析HTML
文档结构
2)加载外部样式表及JavaScript
脚本
3)解析执行JavaScript
脚本
4)DOM
树渲染完成
5)加载未完成的外部资源(如 图片)
6)页面加载成功
执行顺序:
1)document readystatechange
事件
2)document DOMContentLoaded
事件
3)window load
事件
43.什么是CDN,CDN对于网络有什么意义,它有什么的缺点?
CDN
又称为内容分发网络;本意在于尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。
主要目的:解决因分布、带宽、服务器性能带来的访问延迟问题,适用于站点的加速、点播、直播等场景。使用户就近取得所需内容,解决Internet
网络拥挤的状况,提高用户访问网站的响应速度和成功率。
缺点:1)实施复杂,投资大
2)目前大部分的CDN
还只是对静态的内容加速,对动态加速效果不好;而双线对动态加速的效果跟静态是一样的。
44.vue-router中$route和$router的区别?
1)$route
为当前router
跳转对象里面可以获取name
、path
、query
、params
等
2)$router
为VueRouter
实例,想要导航到不同URL
,则使用$router.push
方法
返回上一个history
也是使用$router.go
方法
45.vue路由传参query与params两种方式的区别
query
要用path
来引入,例如ths.$router.push({ path:"detail",query:{id:"00"}})
,接收参数为this.$route.query.id
,params
要用name
来引入,例如ths.$router.push({ name:"detail",params:{id:"00"}})
,接收参数为this.$route.params.id
。以query
传输的参数会在类似于get
传参,在浏览器地址栏中显示参数。
46.描述一下渐进增强和优雅降级
优雅降级(graceful degradation
):一开始就构建站点的完整功能,然后针对浏览器测试和修复。
渐进增强(progressive enhancement
):一开始只构建站点的最少特性,然后不断针对各浏览器追加功能。
47.为什么利用多个域名来请求网络资源会更有效?
动静分离请求,使用不同的服务器处理请求,提高效率;
突破浏览器的并发限制,同一时间针对同一域名下的请求有一定的数量限制。
节约主域名的连接数,从而提高客户端网络带宽的利用率,优化页面响应。
48.HTML5有哪些新特性、移除了哪些元素?
1)绘画标签canvas
;
2)用于媒介回放的video
和audio
元素;
3)本地离线存储localStorage
长期存储数据,浏览器关闭后数据不丢失;
4)sessionStorage
的数据在浏览器关闭后自动删除;
5)语义化更好的内容元素,比如article
、footer
、header
、nav
、section
;
6)表单控件,calendar
、data
、time
、email
、url
、search
;
7)webworker
、websocket
、Geolocation
;
移除的元素:
1)纯表现的元素:basefont
、big
、center
、font
、s
、strike
、tt
2)对可用性产生负面影响的元素:frame
、frameset
、noframes
49.display:none;与visibility:hidden;的区别?
相同点:它们都能让元素不可见‘
不同点:display:none;
会让元素完全从渲染树中消失,渲染的时候不占据任何空间;visibility:hidden;
不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见;display:none;
是非继承属性,子孙节点的消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示;visibility:hodden;
是继承属性,子孙节点的消失由于继承了hidden,通过设置visibility:visible;
可以让子孙节点显示;
修改常规流中元素的display
通常会造成文档重排。修改visibility
属性只会造成本元素的重绘;
读屏器不会读取display:none;
元素内容;会读取visibility:hidden;
元素内容;
50.CSS去掉inline-block元素间隙的几种方法?
间隙是怎么来的:间隙是由换行或者回车导致的;只要把标签写成一行或者标签没有空格,就不会出现间隙;
去除方法:
方法一:
元素间的间隙出现的原因,是元素标签之间的空格,把空格去掉间隙就会消失
<div class="itlike">
<span>lhh</span><span>lhh</span>
</div>
方法二:
利用HTML
注释标签
<div class="demo">
<span>lhh</span><!--
--><span>lhh</span>
</div>
方法三:
取消标签闭合
<div class="demo">
<span>lhh
<span>lhh
<span>lhh
<span>lhh
</div>
方法四:
在父容器上使用font-size:0;
可以消除间隙
<div class="demo">
<span>lhh</span>
<span>lhh</span>
<span>lhh</span>
<span>lhh</span>
</div>
.demo {font-size: 0;}
51.apply,call,bind有什么区别?
三者都可以把一个函数应用到其他对象上,apply
,call
是直接执行函数调用,bind
是绑定,执行需要再次调用。 apply
和call
的区别是apply
接受数组作为参数,而call
是接受逗号分隔的无限多个参数列表。
代码如下:
function Person() {
}
Person.prototype.sayName() { alert(this.name); }
var obj = {name: 'michaelqin'}; // 注意这是一个普通对象,它不是Person的实例
// 1) apply
Person.prototype.sayName.apply(obj, [param1, param2, param3]);
// 2) call
Person.prototype.sayName.call(obj, param1, param2, param3);
// 3) bind
var liaoke = Person.prototype.sayName.bind(obj);
liaoke ([param1, param2, param3]); // bind需要先绑定,再执行
liaoke (param1, param2, param3); // bind需要先绑定,再执行
52.介绍一下defineProperty,hasOwnProperty, propertyIsEnumerable
Object.defineProperty(obj,prop,descriptor)
用来给对象定义属性,有value
,writeable
,enumerable
,set/get
,configurable
,hasOwnProperty
用于检查某一属性是不是存在于对象本身,propertyIsEnumerable
用来检测某一属性是否可遍历,也就是能不能用for...in
循环来取到。
53.JS常用设计模式的实现思路(单例、工厂、代理、装饰、观察者模式等)
// 1) 单例: 任意对象都是单例,无须特别处理
var obj = {name: 'michaelqin', age: 30};
// 2) 工厂: 就是同样形式参数返回不同的实例
function Person() { this.name = 'Person1'; }
function Animal() { this.name = 'Animal1'; }
function Factory() {}
Factory.prototype.getInstance = function(className) {
return eval('new ' + className + '()');
}
var factory = new Factory();
var obj1 = factory.getInstance('Person');
var obj2 = factory.getInstance('Animal');
console.log(obj1.name); // Person1
console.log(obj2.name); // Animal1
// 3) 代理: 就是新建个类调用老类的接口,包一下
function Person() { }
Person.prototype.sayName = function() { console.log('michaelqin'); }
Person.prototype.sayAge = function() { console.log(30); }
function PersonProxy() {
this.person = new Person();
var that = this;
this.callMethod = function(functionName) {
console.log('before proxy:', functionName);
that.person[functionName](); // 代理
console.log('after proxy:', functionName);
}
}
var pp = new PersonProxy();
pp.callMethod('sayName'); // 代理调用Person的方法sayName()
pp.callMethod('sayAge'); // 代理调用Person的方法sayAge()
// 4) 观察者: 就是事件模式,比如按钮的onclick这样的应用.
function Publisher() {
this.listeners = [];
}
Publisher.prototype = {
'addListener': function(listener) {
this.listeners.push(listener);
},
'removeListener': function(listener) {
delete this.listeners[listener];
},
'notify': function(obj) {
for(var i = 0; i < this.listeners.length; i++) {
var listener = this.listeners[i];
if (typeof listener !== 'undefined') {
listener.process(obj);
}
}
}
}; // 发布者
function Subscriber() {
}
Subscriber.prototype = {
'process': function(obj) {
console.log(obj);
}
}; // 订阅者
var publisher = new Publisher();
publisher.addListener(new Subscriber());
publisher.addListener(new Subscriber());
publisher.notify({name: 'michaelqin', ageo: 30}); // 发布一个对象到所有订阅者
publisher.notify('2 subscribers will both perform process'); // 发布一个字符串到所有订阅者
54.处理字符串常用的十个函数
charAt() // 返回在指定位置的字符。
concat() // 连接字符串。
fromCharCode() // 从字符编码创建一个字符串。
indexOf() // 检索字符串。
match() // 找到一个或多个正则表达式的匹配。
replace() // 替换与正则表达式匹配的子串。
search() // 检索与正则表达式相匹配的值。
slice() // 提取字符串的片断,并在新的字符串中返回被提取的部分。
split() // 把字符串分割为字符串数组。
substr() // 从起始索引号提取字符串中指定数目的字符。
substring() // 提取字符串中两个指定的索引号之间的字符。
toLocaleLowerCase() // 把字符串转换为小写。
toLocaleUpperCase() // 把字符串转换为大写。
toLowerCase() // 把字符串转换为小写。
toUpperCase() // 把字符串转换为大写。
toString() // 返回字符串。
valueOf() // 返回某个字符串对象的原始值。
55.如何判断一个变量是对象还是数组
function isObjArr(variable){
if (Object.prototype.toString.call(value) === "[object Array]") {
console.log('value是数组');
}else if(Object.prototype.toString.call(value)==='[object Object]'){//这个方法兼容性好一点
console.log('value是对象');
}else{
console.log('value不是数组也不是对象')
}
}
// 注意:千万不能使用typeof来判断对象和数组,因为这两种类型都会返回"object"。
56.ES5的继承和ES6的继承有什么区别?
ES5
的继承是通过prototype
或构造函数机制来实现。ES5
的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this
上(Parent.apply(this)
)。ES6
的继承机制实质上是先创建父类的实例对象this
(所以必须先调用父类的super()
方法),然后再用子类的构造函数修改this
。具体为ES6
通过class
关键字定义类,里面有构造方法,类之间通过extends
关键字实现继承。子类必须在constructor
方法中调用super
方法,否则新建实例报错。因为子类没有自己的this
对象,而是继承了父类的this
对象,然后对其调用。如果不调用super
方法,子类得不到this
对象。
注意:super关键字指代父类的实例,即父类的this对象。在子类构造函数中,调用super后,才可使用this关键字,否则报错。
57.下面的ul,如何点击每一列的时候alert其index?(闭包)
<ul id="test">
<li>这是第一条</li>
<li>这是第二条</li>
<li>这是第三条</li>
</ul>
// 方法一:
var lis=document.getElementById('test').getElementsByTagName('li');
for(var i=0;i<3;i++)
{
lis[i].index=i;
lis[i].onclick=function(){
alert(this.index);
};
}
//方法二:
var lis=document.getElementById('test').getElementsByTagName('li');
for(var i=0;i<3;i++)
{
lis[i].index=i;
lis[i].onclick=(function(a){
return function() {
alert(a);
}
})(i);
}
58.对于MVVM的理解
MVVM
是 Model-View-ViewModel
的缩写。Model
代表数据模型,也可以在Model
中定义数据修改和操作的业务逻辑。View
代表UI
组件,它负责将数据模型转化成UI
展现出来。ViewModel
监听模型数据的改变和控制视图行为、处理用户交互,
简单理解就是一个同步View
和 Model
的对象,连接Model
和View
。
在MVVM
架构下,View
和 Model
之间并没有直接的联系,
而是通过ViewModel
进行交互,Model
和 ViewModel
之间的交互是双向的,
因此View
数据的变化会同步到Model
中,而Model
数据的变化也会立即反应到View
上。ViewModel
通过双向数据绑定把 View
层和 Model
层连接了起来,
而View
和 Model
之间的同步工作完全是自动的,无需人为干涉,
因此开发者只需关注业务逻辑,不需要手动操作DOM
,
不需要关注数据状态的同步问题,
复杂的数据状态维护完全由 MVVM
来统一管理。
59.解释Vue的生命周期
Vue
实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom->渲染、更新->渲染、销毁等一系列过程,称之为Vue
的生命周期。
Vue
的生命周期包括:beforeCreate
(创建前)在数据观测和初始化事件还未开始,created
(创建后)完成数据观测,属性和方法的运算,初始化事件,$el
属性还没有显示出来;beforeMount(
载入前)在挂载开始之前被调用,相关的render
函数首次被调用,实例已完成以下的配置:编译模板,把data
里面的数据和模板生成html
,注意此时还没有挂载html
到页面上;mounted
(载入后)在el
被新创建的vm.$el
替换,并挂载到实例上去之后调用,实例已完成以下配置:用上面编译好的html
内容替换el
属性指向的DOM
对象,完成模板中的html
渲染到html
页面中,此过程中进行ajax
交互。beforeUpdate
(更新前)在数据更新之前调用,发生在虚拟DOM
重新渲染和打补丁之前,可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。updated
(更新后)在由于数据更改导致的虚拟DOM
重新渲染和打补丁之后调用。调用时,组件DOM
已经更新,所以可以执行依赖于DOM
的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环,该钩子在服务器渲染期间不被调用。beforeDestroy
(销毁前)在实例销毁之前调用,实例仍然完全可用。destroyed
(销毁后)在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
60.为什么使用Node.js,它有哪些优缺点?
优点:
事件驱动,通过闭包很容易实现客户端的生命活期。
不用担心多线程,锁,并行计算的问题V8
引擎速度非常快
对于游戏来说,写一遍游戏逻辑代码,前端后端通用
缺点:node.js
更新很快,可能会出现版本兼容node.js
还不算成熟,还没有大制作node.js
不像其他的服务器,对于不同的链接,不支持进程和线程操作
61.什么是错误优先的回调函数?
错误优先(Error-first
)的回调函数(Error-First Callback
)用于同时返回错误和数据。
第一个参数返回错误,并且验证它是否出错;其他参数返回数据。
fs.readFile(filePath, function(err, data)
{
if (err)
{
// 处理错误
return console.log(err);
}
console.log(data);
});
62.使用npm有哪些好处?
通过npm
,你可以安装和管理项目的依赖,
并且能够指明依赖项的具体版本号。
对于Node
应用开发而言,
可以通过package.json
文件来管理项目信息,
配置脚本,以及指明依赖的具体版本。
63.在JavaScript源文件的开头包含 use strict 有什么意义和好处?
use strict
是一种在JavaScript
代码运行时自动实行更严格解析和错误处理的方法。(严格模式)
将值分配给一个未声明的变量会自动创建该名称的全局变量。这是JavaScript
中最常见的错误之一。在严格模式下,这样做的话会抛出错误。消除 this
强制。
当检测到对象(例如,var object = {foo: "bar", foo: "baz"};
)中重复命名的属性,或检测到函数中(例如,function foo(val1, val2, val1){}
)重复命名的参数时,严格模式会抛出错误,因此捕捉几乎可以肯定是代码中的bug
可以避免浪费大量的跟踪时间。比eval()
更安全。
64.vuejs与angularjs以及react的区别?
与AngularJS
的区别
相同点:
都支持指令:内置指令和自定义指令。
都支持过滤器:内置过滤器和自定义过滤器。
都支持双向数据绑定。
都不支持低端浏览器。
不同点:
1.AngularJS
的学习成本高,比如增加了Dependency Injection
特性,而Vue.js
本身提供的API
都比较简单、直观。
2.在性能上,AngularJS
依赖对数据做脏检查,所以Watcher
越多越慢。Vue.js
使用基于依赖追踪的观察并且使用异步队列更新。所有的数据都是独立触发的。
对于庞大的应用来说,这个优化差异还是比较明显的。
与React
的区别
相同点:React
采用特殊的JSX
语法,Vue.js
在组件开发中也推崇编写.vue
特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用。
中心思想相同:一切都是组件,组件实例之间可以嵌套。
都提供合理的钩子函数,可以让开发者定制化地去处理需求。
都不内置列数AJAX
,Route
等功能到核心包,而是以插件的方式加载。
在组件开发中都支持mixins
的特性。
不同点:React
依赖Virtual DOM
,而Vue.js
使用的是DOM
模板。React
采用的Virtual DOM
会对渲染出来的结果做脏检查。Vue.js
在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM
。
65.标签keep-alive的作用是什么?
<keep-alive></keep-alive>
包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。
66.WeakMap 和 Map 的区别?
WeakMap
结构与 Map
结构基本类似,唯一的区别是它只接受对象作为键名( null
除外),不接受其他类型的值作为键名,而且键名所指向的对象,不计入垃圾回收机制。WeakMap
最大的好处是可以避免内存泄漏。一个仅被 WeakMap
作为 key
而引用的对象,会被垃圾回收器回收掉。WeakMap
拥有和 Map
类似的 set(key, value)
、get(key)
、has(key)
、delete(key)
和 clear()
方法, 没有任何与迭代有关的属性和方法。
67.http和https的基本概念?
http
: 超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP
),用于从WWW
服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。https
: 是以安全为目标的HTTP
通道,简单讲是HTTP
的安全版,即HTTP
下加入SSL
层,HTTPS
的安全基础是SSL
,因此加密的详细内容就需要SSL
。https
协议的主要作用是:建立一个信息安全通道,来确保数组的传输,确保网站的真实性。
68.git fetch和git pull的区别?
git pull
:相当于是从远程获取最新版本并merge
到本地git fetch
:相当于是从远程获取最新版本到本地,不会自动merge
69.介绍一下对浏览器内核的理解?
主要分成两部分:渲染引擎(layout engineer
或Rendering Engine
)和JS
引擎。
渲染引擎:负责取得网页的内容(HTML
、XML
、图像等等)、
整理讯息(例如加入CSS
等),以及计算网页的显示方式,然后会输出至显示器或打印机。
浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。
所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。JS
引擎:解析和执行javascript
来实现网页的动态效果。
最开始渲染引擎和JS
引擎并没有区分的很明确,后来JS
引擎越来越独立,内核就倾向于只指渲染引擎。
70.什么是微格式
微格式(Microformats
)是一种让机器可读的语义化XHTML
词汇的集合,是结构化数据的开放标准。
是为特殊应用而制定的特殊格式
优点:将智能数据添加到网页上,让网站内容在搜索引擎结果界面可以显示额外的提示。
71.数据绑定基本的实现
// 实现一个方法,可以给 obj 所有的属性添加动态绑定事件,当属性值发生变化时会触发事件
let obj = {
key_1: 1,
key_2: 2
}
function func(key) {
console.log(key + ' 的值发生改变:' + this[key]);
}
bindData(obj, func);
obj.key_1 = 2; // 此时自动输出 "key_1 的值发生改变:2"
obj.key_2 = 1; // 此时自动输出 "key_2 的值发生改变:1"
答案:
function bindData(obj, fn) {
for (let key in obj) {
Object.defineProperty(obj, key, {
set(newVal) {
if (this.value !== newVal) {
this.value = newVal;
fn.call(obj, key);
}
},
get() {
return this.value;
}
})
}
}
72.介绍一下对webpack的认识?
WebPack
是一个模块打包工具,可以使用WebPack
管理模块依赖,并编绎输出模块们所需的静态文件。
它能够很好地管理、打包Web
开发中所用到的HTML
、javaScript
、CSS
以及各种静态文件(图片、字体等),让开发过程更加高效。
对于不同类型的资源,webpack
有对应的模块加载器。webpack
模块打包器会分析模块间的依赖关系,最后 生成了优化且合并后的静态资源。webpack
的两大特色:
1)code splitting
(可以自动完成)
2)loader
可以处理各种类型的静态文件,并且支持串联操作webpack
是以commonJS
的形式来书写脚本,但对 AMD/CMD
的支持也很全面,方便旧项目进行代码迁移。webpack
具有requireJs
和browserify
的功能,但仍有很多自己的新特性:
1) 对 CommonJS
、 AMD
、ES6
的语法做了兼容
2) 对js
、css
、图片等资源文件都支持打包
3) 串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对CoffeeScript
、ES6
的支持
4) 有独立的配置文件webpack.config.js
5) 可以将代码切割成不同的chunk
,实现按需加载,降低了初始化时间
6) 支持 SourceUrls
和 SourceMaps
,易于调试
7) 具有强大的Plugin
接口,大多是内部插件,使用起来比较灵活
8)webpack
使用异步 IO
并具有多级缓存。这使得 webpack
很快且在增量编译上更加快
73.关于HTTP2.0的认识
HTTP/2
引入了“服务端推(server push
)”的概念,它允许服务端在客户端需要数据之前就主动地将数据发送到客户端缓存中,从而提高性能。HTTP/2
提供更多的加密支持,HTTP/2
使用多路技术,允许多个消息在一个连接上同时交差。
它增加了头压缩(header compression
),因此即使非常小的请求,其请求和响应的header
都只会占用很小比例的带宽。
74.对AMD和Commonjs的理解?
CommonJS
是服务器端模块的规范,nodejs
采用了这个规范。CommonJS
规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD
规范则是非同步加载模块,允许指定回调函数。AMD
推荐的风格通过返回一个对象做为模块对象,CommonJS
的风格通过对module.exports
或exports
的
属性赋值来达到暴露模块对象的目的。
75.mongoDB和MySQL的区别?
MySQL
是传统的关系型数据库,MongoDB
则是非关系型数据库mongodb
以JSON
结构(二进制)进行存储,对海量数据存储有着很明显的优势。
对比传统关系型数据库,NoSQL
有着非常显著的性能和扩展性优势,与关系型数据库相比,MongoDB
的优点有:
①弱一致性(最终一致),更能保证用户的访问速度:
②文档结构的存储方式,能够更便捷的获取数据。
76.讲讲304缓存的原理?
服务器首先产生ETag
,服务器可在稍后使用它来判断页面是否已经被修改。
本质上,客户端通过将该记号传回服务器,要求服务器验证其(客户端)缓存。304
是HTTP
状态码,服务器用来标识这个文件没修改,不返回内容,浏览器在接收到个状态码后,会使用浏览器已缓存的文件。
客户端请求一个页面A
。
服务器返回页面A
,并在给A
加上一个ETag
。
客户端展现该页面,并将页面连同ETag
一起缓存。
客户再次请求页面A
,并将上次请求时服务器返回的ETag
一起传递给服务器。
服务器检查该ETag
,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304
(未修改——Not Modified
)和一个空的响应体。
77.数组方法
1)join()
把数组上午所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
该方法只接收一个参数,用作分隔符的字符串,然后返回包含所有数组项的字符串,如果不给join()
方法传入任何值,则使用逗号作为分隔符。
var a = [1,2,3];
console.log(a.join());//'1,2,3'
console.log(a.join(' '));//'1 2 3'
console.log(a.join(''));//'123'
var b = new Array(10);
b.join('-');//'---------',9个连字符组成的字符串
注意:如果join()
方法的参数是undefined
,标准浏览器以逗号为分隔符返回字符串,而IE7-浏览器以"undefined"
为分隔符返回字符串;
如果数组中某一项的值是null
或者undefined
,则该值在join()
方法返回的结果中以空字符串表示。
2)push()
方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并且返回修改后数组的长度。
var a = [];
console.log(a,a.push(1));//[1] 1
console.log(a,a.push('a'));//[1,'a'] 2
console.log(a,a.push(true, {}));//[1,'a',true,{}] 4
console.log(a,a.push([5,6]));//[1,'a',true,{},[5,6]] 5
3)pop()
方法从数组末尾移除最后一项,减少数组的length
,然后返回移除的项。
var a = ['a', 'b', 'c'];
console.log(a,a.pop()); // ['a', 'b'] 'c'
注意:给pop
参数传其他数字不起作用,也不报错。还是只删除最后一项;
对空数组使用pop()
方法,不会报错,而是返回undefined
4)shift()
方法移除数组中的第一个项并返回该项,同时数组的长度减1
var a = ['a', 'b', 'c'];
console.log(a,a.shift());//['b', 'c'] 'a'
var arr6 = [1];
console.log(arr6,arr6.shift()); //[] 1
注意:对空数组使用shift()
方法,不会报错,而是返回undefined
5)unshift()
方法在数组前面添加任意个项并返回新数组长度。
var a = ['a', 'b', 'c'];
console.log(a,a.unshift('x')); //['x', 'a', 'b', 'c'] 4
注意:当传入多个参数时,是一次性插入。最终的数组中插入的元素的顺序和它们在参数列表中的 顺序一致;
在IE-7
浏览器中,unshift()
方法的返回值总是undefined
6)reserve()
方法用于反转数组的顺序,返回经过排序之后的数组;而原来数组的顺序也发生改变。
var array = [1,2,4,3,5];
console.log(array,array.reverse());//[5,3,4,2,1] [5,3,4,2,1]
var array = ['str',true,3];
console.log(array,array.reverse());//[3,true,'str'] [3,true,'str']
7)sort()
按照字符编码的顺序进行排序。sort()
方法会调用每个数组项的toString()
方法,然后比较得到的字符串排序,返回经过排序之后的数组,而原数组顺序也发生改变。
var array = [2,1,4,3,5];
console.log(array,array.sort());//[1,2,3,4,5] [1,2,3,4,5]
var array = ['3str',3,2,'2'];
console.log(array,array.sort());//[2, "2", 3, "3str"] [2, "2", 3, "3str"]
注意:如果数组包含undefined
元素,它们会被排到数组的尾部;
arrayObject.sort(sortby)
参数可选。规定排序顺序。必须是函数。比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0
,如果第一个参数应该位于第二个之后则返回一个正数。
8)concat()
方法基于当前数组中的所有项创建一个新的数组,先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。所以concat()
不影响原数组。
// 如果不给concat()方法传递参数时,它只是复制当前的数组;
var arr = [1,2,3];
console.log(arr,arr.concat()); //[1,2,3] [1,2,3]
// 如果参数是一个或多个数组,则该方法会将这些数组中的每一项都添加到结果数组中;
console.log(arr,arr.concat([6,7,8],[77,33,44]));
//[1, 2, 3] [1, 2, 3, 6, 7, 8, 77, 33, 44]
var arr1 = [4,5,6];
console.log(arr,arr.concat(arr1)); //[1,2,3] [1,2,3,4,5,6]
// 如果传递的值不是数组,这些值就会被简单地添加到结果数组的末尾。console.log(arr,arr.concat(4,5));//[1,2,3] [1,2,3,4,5]
console.log(arr,arr.concat(4,[5,[6,7]]));
//[1,2,3] [1, 2, 3, 4, 5, [6,7]]
浅拷贝
如果不提供参数,concat()
方法返回当前数组的一个浅拷贝。
// 该方法实际只复制了数组的第一维。
// 数组第一维存放的是第二维的引用,而第二维才是实际存放他们的内容
var numbers = [1,2];
var newNumbers = numbers.concat();
console.log(numbers,newNumbers);//[1,2] [1,2]
numbers[0] = 0;
console.log(numbers,newNumbers);//[0,2] [1,2]
var numbers = [[1,2]];
var newNumbers = numbers.concat();
console.log(numbers,newNumbers);//[[1,2]] [[1,2]]
numbers[0][0] = 0;
console.log(numbers,newNumbers);//[[0,2]] [[0,2]]
9)slice()
方法基于当前数组中的一个或多个项创建一个新数组,接受一个或两个参数,最后返回新数组,所以slice()
不影响原数组。slice(start,end)
方法需要两个参数start
和end
,返回这个数组从start
位置到end
位置(不包含)的一个子数组,左闭右开。
注意:a.如果end
为undefined
或不存在,则返回从start
位置到数组结尾的所有项;
b.如果没有参数,则返回原数组,即返回当前数组的一个浅拷贝;
10)splice()
方法用于删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员,该方法会改变原数组。splice()
返回一个由删除元素组成的数组,或者如果没有删除元素就返回一个空数组splice(start,number...)
的第一个参数start
指定了插入或删除的起始位置,第二个参数number
指定了应该从数组中删除的元素的个数,如果后面还有更多的参数,则表示这些就是要被插入数组的新元素。
11)indexOf(search,start)
方法接收search
和start
两个参数,返回search
首次出现的位置,如果没有找到则返回-1
,start
代表从start
位置开始寻找。
12)lastIndexOf(search,start)
方法从右向左查找。
接收search
和start
两个参数,返回search
第一次出现的位置,如果没有找到则返回-1
13)reduce()
方法需要两个参数,第一个是执行化简操作的函数,化简函数的任务就是用某种方法把两个值组合或化简为一个值,并返回化简后的值。
var total = [0, 1, 2, 3].reduce(function(sum, value) {
return sum + value;
}, 0);
// total is 6
reduceRight()
则从右到左执行对应的化简函数
14)map()
方法对数组中的每一项运行给定的函数,返回每次函数调用的结果组成的数组,map
方法还可以接受第二个参数,表示回调函数执行时this所指向的对象。
15)forEach()
方法对数组中的每一项运行给定的函数,这个方法没有返回值。本质上和for
循环迭代数组一样。如果需要有返回值,一般使用map
方法。forEach()
方法除了接受一个必须的回调函数参数,第二个参数还可以接受一个可选的上下文参数(改变回调函数里面的this指向)
array.forEach(callback(currentValue, index, array){
//do something
}, this)
16)filter()
方法对数组中的每一项运行给定的函数,返回该函数会返回true
的项组成的数组。该方法常用于查询符合条件的所有数组项。filter()
方法还可以接受第二个可选的上下文参数(改变回调函数里面的this
指向)
var arr= [1,10,20,30]
var brr = arr.filter((item)=>{
return item>10;
})
//[20,30]
17)some()
方法对数组中的每一项运行给定函数,如果该函数对任一项返回true
,则返回true
。并且当且仅当数值中的所有元素调用判定函数都返回false
,它才返回false
注意:在空数组上调用some()
方法会返回false
const isBiggerThan10 = (element, index, array) => {
return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10);
// false
[12, 5, 8, 1, 4].some(isBiggerThan10);
// true
18)every()
方法对数组中的每一项运行给定函数,如果函数对每一项都返回true
,则返回true
;只要有一项返回false
,则返回false
19)fill()
方法,用一个固定值填充一个数组中起始索引到终止索引内的全部元素
arr.fill(value, start, end)
var numbers = [1, 2, 3]
numbers.fill(1);
// results in [1, 1, 1]
20)find()
方法返回数组中满足提供的测试函数的第一个元素的值
function isBigEnough(element) {
return element >= 15;
}
[12, 5, 8, 130, 44].find(isBigEnough); // 130
21)findIndex()
方法返回数组中满足提供的测试函数的一个元素的索引
function isBigEnough(element) {
return element >= 15;
}
[12, 5, 8, 130, 44].findIndex(isBigEnough);
//'3'
22)includes()
方法用来判断一个数组是否包含一个指定的值,如果是,则返回true
,如果没有则返回false
let a = [1, 2, 3];
a.includes(2);
// true
a.includes(4);
// false
23)toLocaleString()
方法返回一个字符串表示数组中的元素。数组中的元素将使用各自的toLocaleString
方法转成字符串,这些字符串将使用一个特定语言环境的字符串(例如一个逗号",")隔开
var number = 1337;
var date = new Date();
var myArr = [number, date, "foo"];
var str = myArr.toLocaleString();
console.log(str);
// 输出 "1,337,2019/2/15 下午8:32:24,foo"
24)copyWithin(target,start,end)
方法浅复制数组的一部分到同一数组的另一个位置
25)Array.isArray()
方法用于确定传递的值是否是一个Array
Array.isArray([]) => true;
Array.isArray({}) => false;
26)Array.of()
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]
27)Array.from()
对伪数组或可迭代对象(包括arguments Array
,Map
,Set
,String…
)转换成数组对象
语法 Array.from(arrayLike, mapFn, thisArg)
arrayLike
想要转换成数组的伪数组对象或可迭代对象。
mapFn
(可选参数)
如果指定了该参数,新数组中的每个元素会执行该回调函数。
thisArg
(可选参数)
可选参数,执行回调函数 mapFn 时 this 对象。
返回值
一个新的数组实例