前端面试题整理
Posted 詹玉阁
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端面试题整理相关的知识,希望对你有一定的参考价值。
概念题
1.position的absolute与fixed共同点与不同点
A:共同点: 1.改变行内元素的呈现方式,display被置为inline-block;2.让元素脱离普通流,不占据空间;3.默认会覆盖到非定位元素上
B不同点: absolute的”根元素“是可以设置的,而fixed的”根元素“固定为浏览器窗口。当你滚动网页,fixed元素与浏览器窗口之间的距离是不变的。
2.CSS3有哪些新特性?
圆角(border-radius),阴影(box-shadow),对文字加特效(text-shadow),
渐变(Gradients),transition(过渡),
transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);//旋转,缩放,位移,倾斜
CSS选择器nth-child(),nth-of-type():not()
background-size: 属性规定背景图片的尺寸。在 CSS3 之前,背景图片的尺寸是由图片的实际尺寸决定的。在 CSS3 中,可以规定背景图片的尺寸,这就允许我们在不同的环境中重复使用背景图片
::selection选择器匹配元素中被用户选中或处于高亮状态的部分。
::selection只可以应用于少数的CSS属性:color, background, cursor,和outline。
@media(媒体查询),多栏布局(multi-column) ,border-image,阴影( box-shadow),反射(box-reflect)
3.对BFC规范的理解?
BFC 类似一个“结界”,如果一个 DOM 元素具有 BFC,那么它内部的子元素不会影响外面的元素;外面的元素也不会影响到其内部元素。
4.解释下浮动和它的工作原理?清除浮动的技巧
原理:浮动元素脱离文档流,不占据空间。浮动元素碰到包含它的边框或者浮动元素的边框停留。
清浮动:1)使用空标签清除浮动。<div style="clear:both;"></div> 这种方法是在所有浮动标签后面添加一个空标签 定义css clear:both. 弊端就是增加了无意义标签。
2)使用overflow。设置overflow为hidden或者auto 给包含浮动元素的父标签添加css属性 overflow:auto; zoom:1; zoom:1用于兼容IE6。
3)使用after伪对象清除浮动。
使用中需注意以下几点。一、该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素
4)父级div定义 height
原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。
优点:简单、代码少、容易掌握
缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题
5.垂直居中的方法
1)单行文字
可以设置padding-top,padding-bottom
将height和line-height设为相等
2)多行文字
<style> div{ display: table-cell; vertical-align:middle; border:1px solid #ccc; width:200px; height: 200px; } </style> <div> <p>123</p> <p>123</p> </div>
<style> div { display: flex; flex-direction: column; justify-content: center; align-content: center; text-align: center; border: 1px solid #ccc; width: 200px; height: 200px; } </style> <div> <p>123</p> <p>123</p> </div>
3)块级元素
<style> .wrapper { display: flex; justify-content: center; align-items: center; width: 200px; height: 200px; border: 1px solid #ccc; } .inner { width: 100px; height: 100px; border: 1px solid #ccc; } </style> <div class="wrapper"> <div class="inner"></div> </div>
<style> .wrapper { position: relative; width: 200px; height: 200px; border: 1px solid #ccc; } .inner { position: absolute; width: 100px; height: 100px; border: 1px solid #ccc; left: 50%; top: 50%; transform: translate(-50%,-50%); } </style> <div class="wrapper"> <div class="inner"></div> </div>
<style> .wrapper { position: relative; width: 200px; height: 200px; border: 1px solid #ccc; } .inner { position: absolute; width: 100px; height: 100px; border: 1px solid #ccc; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } </style> <div class="wrapper"> <div class="inner"></div> </div>
6.rem 和 em的区别?
em相对于父元素,rem相对于根元素
7.px和em的区别
相同点:px和em都是长度单位;
异同点:px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。
8.简述一下src与href的区别
href 指向网络资源所在的位置, 用于在当前文档和引用资源间确定联系。常用的有:link、a
浏览器会识别href引用的文档并行下载该文档,并且不会停止对当前文档的处理
src指向外部资源的位置, 用于替换当前元素。src指向的内容会嵌入到文档中当前标签所在的位置。常用的有:img、script、iframe。
当浏览器解析到src引用时,会暂停浏览器的渲染,直到该资源加载完毕。这也是将js脚本放在底部而不是头部的原因。
9.介绍一下CSS的盒子模型?
盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border)
W3C盒子模型——属性高(height)和属性宽(width)这两个值不包含 填充(padding)和边框(border )
IE盒子模型——属性高(height)和属性宽(width)这两个值包含 填充(padding)和边框(border)
W3C盒子模型:box-sizing: content-box
IE盒模型: box-sizing: border-box;
10.CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算? CSS3新增伪类有那些?
id选择器( # myid)
类选择器(.myclassname)
标签选择器(div, h1, p)
相邻选择器(h1 + p)
子选择器(ul > li)
后代选择器(li a)
通配符选择器( * )
属性选择器(a[rel = "external"])
伪类选择器(a: hover, li:nth-child)
可继承的样式: font-size, font-family ,color , text-indent , opacity
优先级先根据权重,如果权重相同则已依据加载顺序
!important > id > class > tag important 比 内联优先级高,但内联比 id 要高
CSS3新增伪类举例:
p:first-of-type,
p:last-of-type
p:only-child
p:nth-child(2)
:enabled 表单元素可用
:disabled表单元素不可用
:checked 单选框或复选框被选中
10.解释下CSS sprites,以及你要如何在页面或网站中使用它。
CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background-repeat”,“background-position”的组合进行背景定位,background-position可以用数字能精确的定位出背景图片的位置
11. 浏览器端的js包括哪几个部分?
答: 核心( ECMAScript) , 文档对象模型(DOM), 浏览器对象模型(BOM)
12..js有几种数据类型?
一共七种数据类型
五种基本类型: Undefined、Null、Boolean、Number和String。
一种复杂的数据类型————Object,Object本质上是由一组无序的名值对组成的。
ES6 新增Symbol
js的常见内置对象类:Date,Array,Math、Number、Boolean、String、Array、RegExp、Function...
13.常见的HTTP状态码
200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
404 (未找到) 服务器找不到请求的网页。
其他的遇到了百度
14.从前端角度出发谈谈做好seo需要考虑什么?
答:
了解搜索引擎如何抓取网页和如何索引网页
语义化html标签
meta标签优化
合理的title, description, keywords;
重要的html代码放前面
少用iframe, 搜索引擎不会抓取iframe中的内容
图片加上alt
付费给搜索引擎
15.在书写高效 CSS 时会有哪些问题需要考虑?
答:
1)reset初始化文件
2)规范命名。尤其对于没有语义化的html标签,例如div,所赋予的class值要特别注意。
3)抽取可重用的部件,注意层叠样式表的“优先级”。
16.css动画和js动画的优缺点
CSS3的动画
优点:1.在性能上会稍微好一些,浏览器会对CSS3的动画做一些优化(比如专门新建一个图层用来跑动画) 2.代码相对简单
缺点:1.在动画控制上不够灵活2.兼容性不好3.部分动画功能无法实现(如滚动动画,视差滚动等)
javascript的动画
优点:1.控制能力很强,可以单帧的控制、变换 2.兼容性好,写得好完全可以兼容IE6,且功能强大。
缺点:计算没有css快,另外经常需要依赖其他的库。
结论
所以,不复杂的动画完全可以用css实现,复杂一些的,或者需要交互的时候,用js会靠谱一些~
17.如果设计中使用了非标准的字体,你该如何去实现?
图片替代
web : fonts在线字库
@font-face { font-family: myFirstFont; src: url(\'Sansation_Light.ttf\') ,url(\'Sansation_Light.eot\'); /* IE9 */ }
18.关于margin塌陷问题
兄弟级的块之间,margin这个属性上下边距,经常会发生重叠的情况,以数值大的为准,而不会相加。
父子级的块之间,子级的上margin会与父级上下margin重叠,以数值大的为准,而不会相加。
19.JS如何获取某个DOM节点,节点遍历方式
getElementById//通过元素Id,唯一性
getElementsByClassName//通过元素的ClassName属性的值
getElementsByTagName//通过标签名称
getElementsByName//通过元素的Name属性的值
20.JS创建节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
21.JS添加、移除、替换、插入节点
appendChild() //添加
removeChild() //移除
replaceChild() //替换
insertBefore() //插入
22.web标准中结构,表现,行为分别对应什么
html、css、js
23.介绍一下webpack和gulp,以及项目中具体的使用
相同点:都可用于项目打包,文件压缩,文件监测等功能。
不同点:两种工具的侧重点不同,webpack主要侧重于模块的打包,适合于单页面的项目,,我们可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源。而gulp侧重于前端开发的工作流程,我们可以通过配置一系列的task,定义task处理的事务(例如文件压缩合并、雪碧图、启动server、版本控制等),然后定义执行顺序,来让gulp执行这些task,从而构建项目的整个前端开发流程。
24.$(this) 和 this 关键字在 jQuery 中有何不同?
$(this) 返回一个 jQuery 对象,你可以对它调用多个 jQuery 方法,比如用 text() 获取文本,用val() 获取值等等。
而 this 代表当前元素,它是 JavaScript 关键词中的一个,表示上下文中的当前 DOM 元素。你不能对它调用 jQuery 方法,直到它被 $() 函数包裹,例如 $(this)。
25.数组方法
Push()尾部添加
pop()尾部删除
Unshift()头部添加
shift()头部删除
sort() 对数组的元素按照ASCII 字符顺序进行升序排列
reverse()对数组的元素按照ASCII 字符顺序进行降序排列
toString() 把数组转换为字符串,并返回结果
toLocaleString() 方法可根据本地时间把 Date 对象转换为字符串,并返回结果
toSource() 返回该对象的源代码
concat() 连接两个或更多的数组,并返回结果
join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔
valueOf() 返回数组对象的原始值
slice() 从某个已有的数组返回选定的元素,不会影响原数组
splice() 删除元素,并向数组添加新元素,会改变原数组
26.字符串方法
split() 方法用于把一个字符串分割成字符串数组
indexOf() – 返回字符串中一个子串第一处出现的索引。如果没有匹配项,返回 -1
lastIndexOf() 返回字符串中一个子串最后一处出现的索引,如果没有匹配项,返回 -1
search() 执行一个正则表达式匹配查找。如果查找成功,返回字符串中匹配的索引值,否则返回 -1
slice() slice() – 提取字符串的一部分,并返回一个新字符串
substring() 返回字符串的一个子串。传入参数是起始位置和结束位置
substr() 函数 返回从string的startPos位置,长度为length的字符串
replace() 用来查找匹配一个正则表达式的字符串,然后使用新字符串代替匹配的字符串
toUpperCase() 将整个字符串转成大写字母
toLowerCase() 将整个字符串转成小写字母
concat() 将两个或多个字符的文本组合起来,返回一个新的字符串
trim() 方法删除字符串两端的空白符
charAt() – 返回指定位置的字符
charCodeAt() 方法返回字符串中指定索引的字符 unicode 编码
ECMAScript 5 (2009) 允许对字符串的属性访问 [ ]
split() 将字符串转换为数组
match()检查一个字符串是否匹配一个正则表达式
length 返回字符串的长度,所谓字符串的长度是指其包含的字符的个数
27.apply和call的用法和区别
* apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
* call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。
call 与 apply 的相同点:
* 方法的含义是一样的,即方法功能是一样的;
* 第一个参数的作用是一样的;
call 与 apply 的不同点:两者传入的列表形式不一样
* call可以传入多个参数;
* apply只能传入两个参数,所以其第二个参数往往是作为数组形式传入
28.输出今天的日期,以YYYY-MM-DD的方式,
<script> var d=new Date(); // 获取年,getFullYear()返回4位的数字 var year = d.getFullYear(); // 获取月,月份比较特殊,0是1月,11是12月 var month = d.getMonth() + 1; // 变成两位 month = month < 10 ? \'0\' + month : month; // 获取日 var day = d.getDate(); day = day < 10 ? \'0\' + day : day; console.log(year+\'年\'+month+\'月\'+day+\'日\'); </script>
29.正序与倒序输出。
sort() 方法用于对数组的元素进行正序排列
reverse();方法用于对数组的元素进行倒序排列,
默认情况下在使用sort()对数组进行排序的时候会调用toString()函数将数组元素转换成字符串再进行比较,是按ASCII进行比较的。
sort() 方法可以接受一个 方法为参数 ,这个方法有两个参数。分别代表每次排序比较时的两个数组元素。sort()排序时每次比较两个数组元素都会执行这个参数,并把两个比较的数组元素作为参数传递 给这个函数。当函数返回值大于0时就交换两个数组元素的顺序,否则就不交换。
<script> var arr=[0,5,55,45,12,99]; // sort() 方法用于对数组的元素进行正序排列 // reverse();方法用于对数组的元素进行倒序排列 console.log(arr.sort(function(a,b){ return a-b;//正序 })); console.log(arr.reverse(function(a,b){ return a-b; })); </script>
30.JS怎么创建一个类?
方式1 : var obj = new Object();
方式2 : var obj = {};
31.什么叫优雅降级和渐进增强?
渐进增强 progressive enhancement:
针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级 graceful degradation:
一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
区别:
a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给
b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要
c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带
32.浏览器的内核分别是什么?
IE: trident内核
Firefox:gecko内核
Safari:webkit内核
Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核
Chrome:Blink(基于webkit,Google与Opera Software共同开发)
IEedge Blink
33.HTML与XHTML二者有什么区别
HTML是一种基本的WEB网页设计语言,
XHTML:可扩展超文本标记语言,是将超文本标记语言HTML,作为XML应用而重新定义的标准。
最主要的不同
* XHTML 元素必须被正确地嵌套。
* XHTML 元素必须被关闭。
* 标签名必须用小写字母。
* XHTML 文档必须拥有根元素。
34. 请写出至少5个html5新增的标签,并说明其语义和应用场景
header:定义页面或章节的头部。它经常包含 logo、页面标题和导航性的目录。
nav:定义只包含导航链接的章节
section:定义文档中的一个章节
aside:定义和页面内容关联度较低的内容——如果被删除,剩下的内容仍然很合理。
footer:定义页面或章节的尾部。它经常包含版权信息、法律信息链接和反馈建议用的地址。
35.DOCTYPE(文档类型)的作用是什么?
<!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前。
<!DOCTYPE> 声明不是 HTML 标签;它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令。
在 HTML 4.01 中,<!DOCTYPE> 声明引用 DTD,因为 HTML 4.01 基于 SGML。DTD 规定了标记语言的规则,这样浏览器才能正确地呈现内容。
HTML5 不基于 SGML,所以不需要引用 DTD。
36.Navigator 对象
Navigator 对象包含有关浏览器的信息。
注意: 没有应用于 navigator 对象的公开标准,不过所有浏览器都支持该对象。
37.jQuery中的Delegate()函数有什么作用?
delegate()会在以下两个情况下使用到:
1)如果你有一个父元素,需要给其下的子元素添加事件,这时你可以使用delegate()了,代码如下:
$("ul").delegate("li", "click", function(){ $(this).hide(); });
2)当元素在当前页面中不可用时,可以使用delegate()
38.什么样的前端代码是好的
高复用低耦合,这样文件小,好维护,而且好扩展。
39.JSON 的了解?
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小{\'age\':\'12\', \'name\':\'back\'}
40.”==”和“===”的不同?
前者会自动转换类型
后者不会
41.例举强制类型转换和隐式类型转换?
强制(parseInt,parseFloat,number)
隐式+ == -
42.看下列代码,输出什么?
undefined == null; // true
1 == true; // true
2 == true; // false
0 == false; // true
0 == \'\'; // true
NaN == NaN; // false
[] == false; // true
[] == ![]; // true
var foo = "11" + 2 - "1"; console.log(foo);//111 console.log(typeof foo);//number
43.sessionStorage 、localStorage 和 cookie
cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端,Cookie数据不能超过4K,适用于会话标识
cookie只在设置了Cookid过期时间之前一直有效,即使关闭窗口或者浏览器
sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存
web storage数据存储可以达到5M;
sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。
而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。
44.sessionStorage和页面js数据对象的区别
答:页面中一般的 js 对象或数据的生存期是仅在当前页面有效,因此刷新页面或转到另一页面这样的重新加载页面的情况,数据就不存在了。
而sessionStorage 只要同源的同窗口(或tab)中,刷新页面或进入同源的不同页面,数据始终存在。也就是说只要这个浏览器窗口没有关闭,加载新页面或重新加载,数据仍然存在。
45.浅谈CSS定义超链接<a>正确顺序L-V-H-A
a:link {} 超链接的默认样式
a:visited {} 已访问过的链接的样式
a:hover {} 处于鼠标悬停状态的链接的样式
a:active {} 被激活(鼠标左键按下的一瞬间)的链接的样式
46.ES6里头的箭头函数的this对象与其他的有啥区别
普通函数中的this:
1. this总是代表它的直接调用者(js的this是执行上下文), 例如 obj.func ,那么func中的this就是obj
2.在默认情况(非严格模式下,未使用 ‘use strict’),没找到直接调用者,则this指的是 window (约定俗成)
3.在严格模式下,没有直接调用者的函数中的this是 undefined
4.使用call,apply,bind(ES5新增)绑定的,this指的是 绑定的对象
箭头函数中的this
箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象),而不是执行时的对象, 定义它的时候,可能环境是window; 箭头函数可以方便地让我们在 setTimeout ,setInterval中方便的使用this
47.什么是use strict? 其好处坏处分别是什么?
答: 在所有的函数 (或者所有最外层函数) 的开始处加入 "use strict"; 指令启动严格模式。
"严格模式"有两种调用方法:
1)将"use strict"放在脚本文件的第一行,则整个脚本都将以"严格模式"运行。如果这行语句不在第一行,则无效,整个脚本以"正常模式"运行。如果不同模式的代码文件合并成一个文件,这一点需要特别注意。
2)将整个脚本文件放在一个立即执行的匿名函数之中。
好处
- 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的Javascript做好铺垫。
坏处
同样的代码,在"严格模式"中,可能会有不一样的运行结果;一些在"正常模式"下可以运行的语句,在"严格模式"下将不能运行
注:经过测试IE6,7,8,9均不支持严格模式。
48.$(document).ready()方法和window.onload有什么区别?
(1)、window.onload方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行的。
(2)、$(document).ready() 方法可以在DOM载入就绪时就对其进行操纵,并调用执行绑定的函数。
49.一个页面上有大量的图片(大型电商网站),加载很慢,你有哪些方法优化这些图片的加载,给用户更好的体验。
a. 图片懒加载,滚动到相应位置才加载图片。
b. 图片预加载,如果为幻灯片、相册等,将当前展示图片的前一张和后一张优先下载。
c. 使用CSSsprite,SVGsprite,Iconfont、Base64等技术,如果图片为css图片的话。
d. 如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩的特别厉害的缩略图,以提高用户体验。
50.行内元素有哪些?块级元素有哪些?
块级元素:div、ul、li、dl、dt、dd、p、h1-h6、blockquote
行内元素: a、b、span、img、input、strong、select、label、em、button、textarea
空元素:即系没有内容的HTML元素,例如:br、meta、hr、link、input、img
51.JavaScript prototype 属性
prototype 属性使您有能力向对象添加属性和方法。
<script type="text/javascript"> function employee(name, job, born) { this.name = name; this.job = job; this.born = born; } var bill = new employee("Bill Gates", "Engineer", 1985); employee.prototype.salary = null; bill.salary = 20000; document.write(bill.salary); </script>
52.setTimeout
<script> for(var i=1;i<=3;i++){ setTimeout(function(){ console.log(i); //4 }); }; </script>
原因:Javascript事件处理器在线程空闲之前不会运行。
53.将数组转化为json字符串,json字符串转换为 JavaScript 对象?
JSON.stringify(array);//json对象转化成json字符串
JSON.parse(array);//json字符串转换为 JavaScript 对象
54.eval()的作用
把字符串参数解析成JS代码并运行,并返回执行的结果;
eval("2+3");//执行加运算,并返回运算值。
eval("varage=10");//声明一个age变量
function a(){ eval("var x=1"); //等效于 var x=1; console.log(x); //输出1 } a(); console.log(x);//错误 x没有定
避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。
55.JavaScript中如何检测一个变量是一个String类型?请写出函数实现
typeof(obj) === "string"
typeof obj === "string"
obj.constructor === String
56.比较typeof与instanceof?
相同点:
JavaScript 中 typeof 和 instanceof 常用来判断一个变量是否为空,或者是什么类型的。
不同处:
1)typeof的定义和用法:
返回值是一个字符串,用来说明变量的数据类型。
具体用法细节:
typeof 一般只能返回如下几个结果:
\'undefined\' :这个值未定义。
\'boolean\':这个值是布尔值。
\'string\' :这个值是字符串。
\'number\' :这个值是数值。
\'object\':这个值是对象或null。
\'function\' :这个值是函数。
对于 Array,Null 等特殊对象使用 typeof 一律返回 object,这正是 typeof 的局限性。
2)Instanceof定义和用法:
Instanceof定义和用法:instanceof 用于判断一个变量是否属于某个对象的实例。也可以用来判断某个构造函数的prototype属性是否存在另外一个要检测对象的原型链上。
57.看下列代码,输出什么?解释原因。
var a = null; alert(typeof a); //object
解释:null是一个只有一个值的数据类型,这个值就是null。表示一个空指针对象,所以用typeof检测会返回”object”。
var a; alert(typeof a); // undefined alert(b); // 报错
解释:Undefined是一个只有一个值的数据类型,这个值就是“undefined”,在使用var声明变量但并未对其赋值进行初始化时,这个变量的值就是undefined。而b由于未声明将报错。注意未申明的变量和声明了未赋值的是不一样的。
58.如何判断一个对象是否属于某个类?
if(a instanceof Person){ alert(\'yes\'); }
59.Array 对象属性
constructor 返回对创建此对象的数组函数的引用。
length 设置或返回数组中元素的数目。
prototype 使您有能力向对象添加属性和方法。
60.new操作符具体干了什么呢?
new共经过了4几个阶段
1)创建一个空对象
var obj=new Object();
2)设置原型链
obj.__proto__= Func.prototype;
3)让Func中的this指向obj,并执行Func的函数体。
var result =Func.call(obj);
4)判断Func的返回值类型:
如果是值类型,返回obj。如果是引用类型,就返回这个引用类型的对象
if (typeof (result) == "object") { func = result; } else { func = obj;; }
61.git fetch和git pull的区别
git pull:相当于是从远程获取最新版本并merge到本地
git fetch:相当于是从远程获取最新版本到本地,不会自动merge
62.简述同步和异步的区别
同步是阻塞模式,异步是非阻塞模式。
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
63.$.ajax标准写法
<script> $.ajax({ url:"http://www.microsoft.com", //请求的url地址 dataType:"json", //返回格式为json async:true,//请求是否异步,默认为异步,这也是ajax重要特性 data:{"id":"value"}, //参数值 type:"POST", //请求方式 beforeSend:function(){ //请求前的处理 }, success:function(req){ //请求成功时处理 }, complete:function(){ //请求完成的处理 }, error:function(){ //请求出错处理 } }); </script>
64.什么是Ajax和JSON,它们的优缺点?
Ajax是异步JavaScript和XML,用于在Web页面中实现异步数据交互。
Ajax的最大的特点:Ajax可以实现动态不刷新(局部刷新)
readyState属性 状态 有5个可取值: 0=未初始化 ,1=正在加载 2=以加载,3=交互中,4=完成
优点:
可以使得页面不重载全部内容的情况下加载局部内容,降低数据传输量
避免用户不断刷新或者跳转页面,提高用户体验
Ajax在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器负载。
缺点:
对搜索引擎不友好
AJAX只是局部刷新,所以页面的后退按钮是没有用的
可能造成请求数的增加
跨域问题限制
安全问题 AJAX暴露了与服务器交互的细节。
破坏了程序的异常机制
对流媒体还有移动设备的支持不是太好等
不容易调试
JSON是一种轻量级的数据交换格式,ECMA的一个子集
优点:轻量级、易于人的阅读和编写,便于机器(JavaScript)解析,支持复合数据类型(数组、对象、字符串、数字)
65.如何进行网站性能优化
前端优化的途径有很多,按力度大致可以分为两类:
第一类是页面级别的优化,例如 HTTP请求数、脚本的无阻塞加载、内联脚本的位置优化等 ;
1)JavaScript 压缩和模块打包2.)按需加载资源3.)在使用 DOM 操作库时用上 array-ids4) 缓存5) 启用 HTTP/26) 应用性能分7.)使用负载均衡方案8) 为了更快的启动时间考虑一下同构9.)使用索引加速数据库查询10)使用更快的转译方案11)避免或最小化 JavaScript 和 CSS 的使用而阻塞渲染12) 用于未来的一个建议:使用 service workers + 流13)图片编码优化
第二类则是代码级别的优化,例如 Javascript中的DOM 操作优化、CSS选择符优化、图片优化以及 HTML结构优化等等。另外,本着提高投入产出比的目的,后文提到的各种优化策略大致按照投入产出比从大到小的顺序排列。
66.js有几种函数调用方式?
答: 方法调用模型
var obj = { func: function () {} } obj.func()
函数调用模式
var func = function () {} func();
构造器调用模式
apply/ call调用模式
67.重排(reflow)和重绘(repaint)
什么是重排:
引起DOM树重新计算的行为。
什么时候会发生重排:
添加或删除可见的DOM元素
元素的位置改变
元素的尺寸大小改变
元素的内容改变
页面渲染初始化
浏览器窗口尺寸改变
什么是重绘:
元素可见的外观被改变,但并没有影响到布局
什么时候会发生重绘:
DOM元素的字体颜色、改变visibility、outline、背景色。
重绘不会带来DOM元素的重新计算,所以并不一定伴随重排,但是重排一定会引起浏览器的重绘。
68.undefined 和 null 区别
1)null表示"没有对象",即该处不应该有值,转为数值时为0。典型用法是:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。
2)undefined表示"缺少值",就是此处应该有一个值,但是还没有定义,转为数值时为NaN。典型用法是:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
3)undeclared:js语法错误,没有申明直接使用,js无法找到对应的上下文
69.http 和 https 有何区别?如何灵活使用?
HTTP协议通常承载于TCP协议之上,在HTTP和TCP之间添加一个安全协议层(SSL或TSL),这个时候,就成了我们常说的HTTPS。
默认HTTP的端口号为80,HTTPS的端口号为443。
为什么HTTPS安全
因为网络请求需要中间有很多的服务器路由器的转发。中间的节点都可能篡改信息,而如果使用HTTPS,密钥在你和终点站才有。https之所以比http安全,是因为他利用ssl/tls协议传输。它包含证书,卸载,流量转发,负载均衡,页面适配,浏览器适配,refer传递等。保障了传输过程的安全性
70.事件、IE与火狐的事件机制有什么区别?如何阻止冒泡?
事件处理机制:IE是事件冒泡、火狐是 事件捕获;
e.stopPropagation();
71.关于JS事件冒泡与JS事件代理(事件委托)
1)事件冒泡:
通俗易懂的来讲,就是当一个子元素的事件被触发的时候(如onclick事件),该事件会从事件源(被点击的子元素)开始逐级向上传播,触发父级元素的点击事件。
2)事件委托
事件代理(Event Delegation),又称之为事件委托。是 JavaScript 中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能。
stopPropagation(e); //阻止继续冒泡
我页面中有很多按钮,如果不使用事件委托,我只能在每个按钮上注册事件。非常麻烦。但如果我把事件注册在一个大范围的div(假设所有的按钮都在这个div中),那么我只要注册一次事件,就可以处理所有按钮(只要按钮包含在上述div中)事件的响应了
72.B继承A的写法
1)原型继承:
var A = function () { this.a = 1; this.b = 2; this.add = function () { console.log(a + b); } } var B = function () {} B.prototype = new A(); B.prototype.c = 3; B.prototype.add = function () { console.log(B.a + B.b + B.c); } var b = new B(); console.log(b.a); console.log(b.b); console.log(b.c); b.add();
2)构造函数继承
var A = function () { this.a = 1; this.b = 2; this.add = function () { console.log(a + b); } } var B = new A(); B.c = 3; B.add = function () { console.log(B.a + B.b + B.c); } console.log(B.a); console.log(B.b); console.log(B.c); B.add();
3)call、apply实现继承
function A() { this.a = 1; this.b = 2; this.add = function () { console.log(a + b); } } function B() { A.call(this); this.c = 3; this.add = function () { console.log(this.a + this.b + this.c); } } var b = new B(); console.log(b.a); console.log(b.b); console.log(b.c); b.add();
73.请用js去除字符串空格?
方法一:使用replace正则匹配的方法
去除所有空格: str = str.replace(/s*/g,""); 去除两头空格: str = str.replace(/^s*|s*$/g\\,""\\); 去除左空格: str = str\\.replace\\( /^s\\*/\\, “”\\); 去除右空格: str = str\\.replace\\(/\\(s\\*$)/g, ""); str为要去除空格的字符串,实例如下: var str = " 23 23 "; var str2 = str.replace(/s*/g,""); console.log(str2); // 2323
方法二:使用str.trim()方法
str.trim()局限性:无法去除中间的空格,实例如下:
var str = " xiao ming "; var str2 = str.trim(); console.log(str2); //xiao ming
同理,str.trimLeft(),str.trimRight()分别用于去除字符串左右空格。
方法三:使用jquery,$.trim(str)方法
$.trim(str)局限性:无法去除中间的空格,实例如下:
var str = " xiao ming "; var str2 = $.trim(str) console.log(str2); // xiao ming
74.jquery中$.get()提交和$.post()提交有区别
相同点:都是异步请求的方式来获取服务端的数据;
不同点:
1)请求方式不同:$.get() 方法使用GET方法来进行异步请求的。$.post() 方法使用POST方法来进行异步请求的。
2)参数传递方式不同:get请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给Web服务器的,这种传递是对用户不可见的。
3)数据传输大小不同:get方式传输的数据大小不能超过2KB 而POST要大的多
4)安全问题: GET 方式请求的数据会被浏览器缓存起来,因此有安全问题。
75.[get 和 post的区别,何时使用post?](https://www.cnblogs.com/webmc/p/11103919.html)
GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符
POST:一般用于修改服务器上的资源,对所发送的信息没有限制。
GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值,也就是说Get是通过地址栏来传值,而Post是通过提交表单来传值。
然而,在以下情况中,请使用 POST 请求:
1)无法使用缓存文件(更新服务器上的文件或数据库)
2)向服务器发送大量数据(POST 没有数据量限制)
发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
1.Get 请求能缓存,Post 不能
2.Post 相对 Get 安全一点点,因为Get 请求都包含在 URL 里,且会被浏览器保存历史纪录,Post 不会,但是在抓包的情况下都是一样的。
3.Post 可以通过 request body来传输比 Get 更多的数据,Get 没有这个技术
4.URL有长度限制,会影响 Get 请求,但是这个长度限制是浏览器规定的,不是 RFC 规定的
5.Post 支持更多的编码类型且不对数据类型限制
76.ajax请求时,如何解释json数据?
使用eval parse 鉴于安全性考虑使用parse更靠谱
77.JS哪些操作会造成内存泄露
什么是内存泄漏
内存泄露是指当一块内存不再被应用程序使用的时候,由于某种原因,这块内存没有返还给操作系统或者内存池的现象。内存泄漏可能会导致应用程序卡顿或者崩溃。
常见的内存泄漏
1)意外的全局变量引起的内存泄露
function leak(){
leak="xxx";//leak成为一个全局变量,不会被回收
}
2)闭包引起的内存泄露
3)没有清理的DOM元素引用
4)被遗忘的定时器或者回调
5)子元素存在引起的内存泄露
78.谈谈垃圾回收机制方式及内存管理
js是一门具有自动垃圾回收机制的编程语言,开发人员不必关心内存分配和回收问题
离开作用域的值将被自动标记为可以回收, 因此将在垃圾收集期间被删除
原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。
实例如下:
function fn1() { var obj = {name: \'hanzichi\', age: 10}; } function fn2() { var obj = {name:\'hanzichi\', age: 10}; return obj; } var a = fn1(); var b = fn2();
fn1中定义的obj为局部变量,而当调用结束后,出了fn1的环境,那么该块内存会被js引擎中的垃圾回收器自动释放;在fn2被调用的过程中,返回的对象被全局变量b所指向,所以该块内存并不会被释放。
垃圾回收策略:标记清除(较为常用)和引用计数。
79.Javascript中闭包(closure)的理解与浅析
概念
1)声明在一个函数中的函数,叫做闭包函数。
2)能够读取其他函数内部变量的函数。
3)在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
特点
1)让外部访问函数内部变量成为可能;
2)局部变量会常驻在内存中;
3)可以避免使用全局变量,防止全局变量污染;
4)会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
function f1() { var n = 999; function f2() { alert(n); } return f2; } var result = f1(); result(); // 999
79.使用闭包的注意点
1)滥用闭包,会造成内存泄漏:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)会改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
80.伪类(:)和伪元素(::)的区别
伪类:用于已有元素处于某种状态时为其添加对应的样式,这个状态是根据用户行为而动态变化的。例如:当用户悬停在指定元素时,可以通过:hover来描述这个元素的状态,虽然它和一般css相似,可以为已有元素添加样式,但是它只有处于DOM树无法描述的状态下才能为元素添加样式,所以称为伪类。
伪元素:用于创建一些不在DOM树中的元素,并为其添加样式。例如,我们可以通过:before来在一个元素之前添加一些文本,并为这些文本添加样式,虽然用户可以看见这些文本,但是它实际上并不在DOM文档中。
伪类和伪元素的区别:
1)伪类的操作对象是文档树中已有的元素;而伪元素则是创建的文档树外的元素。
2)css3中,双冒号表示伪元素,单冒号代表伪类。
3)伪类侧重丰富选择器的选择语法范围内元素的选择能力,伪元素侧重表达或者定义不在语法定义范围内的抽象元素。
81.defer和async的区别
在没有defer或者async的情况下,会立即执行脚本,所以通常建议把script放在body最后
<script src="script.js"></script>
有async的话,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。但是多个js文件的加载顺序不会按照书写顺序进行
<script async src="script.js"></script>
有derer的话,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成,并且多个defer会按照顺序进行加载。
<script defer src="script.js"></script>
所以区别主要在于一个执行时间,defer会在文档解析完之后执行,并且多个defer会按照顺序执行,而async则是在js加载好之后就会执行,并且多个async,哪个加载好就执行哪个
82.事件绑定和普通事件有什么区别?
普通添加事件的方法:
var btn = document.getElementById("hello"); btn.onclick = function () { alert(1); } btn.onclick = function () { alert(2); }
执行上面的代码只会alert 2
事件绑定方式添加事件:
var btn = document.getElementById("hello"); btn.addEventListener("click", function () { alert(1); }, false); btn.addEventListener("click", function () { alert(2); }, false);
执行上面的代码会先alert 1 再 alert 2
普通添加事件的方法不支持添加多个事件,最下面的事件会覆盖上面的,而事件绑定(addEventListener)方式添加事件可以添加多个。
83.[js中的深克隆与浅克隆](https://www.cnblogs.com/zhiqiuyiye/p/12760648.html)
浅克隆:原始类型按值传递,对象类型按引用传递,与原对象共用一处内存,修改会使原对象也修改
let a = { age: 1 } let b = Object.assign({}, a) a.age = 2 console.log(b.age) // 1
深克隆:在内存中开辟一块新内存,将原对象中的所有值全部复制过去,与原对象完全脱离,修改新对象中的属性值不会影响原对象
let a = { age: 1 } let b = { ...a } a.age = 2 console.log(b.age) // 1
84. 什么是跨域?
由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。存在跨域的情况:
· 网络协议不同,如http协议访问https协议。
· 端口不同,如80端口访问8080端口。
· 域名不同,如qianduanblog.com访问baidu.com。
· 子域名不同,如abc.qianduanblog.com访问def.qianduanblog.com。
· 域名和域名对应ip,如www.a.com访问20.205.28.90
85.为什么利用多个域名来存储网站资源会更有效?
1. CDN 缓存更方便
2. 突破浏览器并发限制
3. 节约 cookie 带宽
4. 节约主域名的连接数,优化页面响应速度
5. 防止不必要的安全问题
86.一次js请求,一般会有哪些缓存处理
DNS缓存:短时间内多次访问某个网站,在限定时间内,不用多次访问DNS服务器。
CDN缓存:内容分发网络(人们可以在就近的代售点取火车票了,不用非得到火车站去排队)
浏览器缓存:浏览器在用户磁盘上,对最新请求过的文档进行了存储。
服务器缓存:将需要频繁访问的Web页面和对象保存在离用户更近的系统中,当再次访问这些对象的时候加快了速度。
87.304与200读取缓存的区别
200是正常,304是内容没有修改。
当你第一次访问时,服务器会返回给你200状态码,同时在头里追加ETag值给你。浏览器拿到后将其缓存。
下一次再访问时,因浏览器已经有该地址的ETag值了。会将其缓存的ETag值内容放在请求头的If-None-Match中,服务器检查其自身内容的ETag值是否与其一致,如果一致就会返回304状态码,告诉你内容和你保存的一致,没有发生改变过。
88.异步加载的方式?
1) 动态插入script标签
2)通过ajax去获取js代码,然后通过eval执行
3)script标签上添加defer或者async属性(创建script,插入到DOM中,加载完毕后callBack)、按需异步载入js
4)创建并插入iframe,让它异步执行js
5)延迟加载:有些 js 代码并不是页面初始化的时候就立刻需要的,而稍后的某些情况才需要的。
89.javascript的本地对象,内置对象和宿主对象?
本地对象为array obj regexp等可以new实例化
内置对象为gload Math 等不可以实例化的
宿主为浏览器自带的document,window 等
90.伪数组
把符合以下条件的对象称为伪数组:
* 具有length属性
* 按索引方式存储数据
* 不具有数组的push,pop等方法
伪数组(类数组):无法直接调用数组方法或期望length属性有什么特殊的行为,不具有数组的push,pop等方法,但仍可以用数组遍历方法来遍历它们。典型的是函数的argument参数,还有像调用document.getElementsByTagName, document.childNodes之类的,它们返回的NodeList对象都属于伪数组。
可以使用以下方法将伪数组转化为真正的Array对象。
Array.prototype.slice ES6中数组的新方法 Array.from() ES6展开操作符 jquery中的,jQuery.toArray()方法
91.Javascript中callee和caller的作用?
* caller是通过函数来调用,返回的是该函数的调用环境,也就是调用栈的最顶层(当最顶层为全局作用域时,返回null)
* callee是通过arguments对象来调用,返回的是执行时的函数环境,通常用于匿名函数递归调用自身
注意:在ES5严格模式中,该方法被废弃不再使用
92.javascript递归函数
递归函数:是指函数直接或间接调用函数本身,则称该函数为递归函数。
/*这是一个死循环*/ function foo(){ console.log("函数 foo 是递归函数。"); foo(); } foo()
正确用法:
在使用递归时,要注意对递归函数的参数类型的检查,一定要保证有一个终止处理或计算的出口。否则很容易演变为死循环,从而造成内存溢出。
var obj = { a: { name: "john", age: 26, sex: "male", child: { firstChild: "mak", laseChild: "loy" } }, b: { name: "joe", age: 28, sex: "female", child: { firstChild: "bill", secondChild: "ruth", laseChild: "yoki" } } }; function getObjValue(obj) { for (var k in obj) { if (typeof obj[k] !== "object") { console.log(obj[k]); //递归出口 } else { getObjValue(obj[k]); //函数调用函数自身 } } }; getObjValue(obj);
算法题
1.js数组去重
<script> var arr1 = [3, 3, 4, 5, 6, 6, 5, 4, 6, 7, 1, 2, 8, 8, 9, 10]; unique = function () { var arr2 = []; for (var i = 0; i < arr1.length; i++) { if (arr2.indexOf(arr1[i]) == -1) { //如果当前数组的第i已经保存进了临时数组,那么跳过, //否则把当前项push到临时数组里面 arr2.push(arr1[i]); } } console.log(arr2); } unique(); </script>
<script> var arr1 = [3, 3, 4, 5, 6, 6, 5, 4, 6, 7, 1, 2, 8, 8, 9, 10]; unique = function () { var arr2 = []; for (var i = 1; i < arr1.length; i++) { if (arr1.indexOf(arr1[i]) == i) { //如果当前数组的第i项在当前数组中第一次出现的位置不是i, //那么表示第i项是重复的,忽略掉。否则存入结果数组 arr2.push(arr1[i]); } } console.log(arr2); } unique(); </script>
2..判断一个字符串中出现次数最多的字符,统计这个次数
<script> var str = \'asdfssaaasasasasaa\'; var json = {}; for (var i = 0; i < str.length; i++) { if (!json[str.charAt(i)]) { json[str.charAt(i)] = 1; } else { json[str.charAt(i)]++; } }; var iMax = 0; var iIndex = \'\'; for (var i in json) { if (json[i] > iMax) { iMax = json[i]; iIndex = i; } } </script>
3.求数组的最大值和最小值
1)使用 Math 中的 max/min 方法
<script> var arr = [12, 6, 56, 25, 5, 82, 51, 22]; var max = Math.max.apply(null, arr); var min = Math.min.apply(null, arr); console.log(max, min) </script>
2)假设法
<script> var arr = [12, 6, 56, 25, 5, 82, 51, 22]; var max = arr[0]; var min = arr[0]; for (var i = 0; i < arr.length; i++) { max = max > arr[i] ? max : arr[i]; } for (var i = 0; i < arr.length; i++) { min = min < arr[i] ? min : arr[i]; } console.log(max); console.log(min); </script>
3)排序法
<script> var arr = [12, 6, 56, 25, 5, 82, 51, 22]; arr.sort(function (a, b) { return a - b; }) var min = arr[0]; var max = arr[arr.length - 1]; console.log(min); console.log(max); </script>
4.js的9*9乘法表
<script> for (var i = 1; i <= 9; i++) { for (var j = 1; j <= i; j++) { document.write(i + "x" + j + "=" + i * j + " "); } document.write("<br>
" + "<br>
"); } </script>
5.为了保证页面输出安全,我们经常需要对一些特殊的字符进行转义,请写一个函数escapeHtml,将<, >, &, “进行转义
<script> function escapeHtml(str) { return str.replace(/[<>"&]/g, function (match) { switch (match) { case "<": return "<"; case ">": return ">"; case "&": return "&"; case """: return """; } }); } </script>
6.已知有字符串foo=”get-element-by-id”,写一个function将其转化成驼峰表示法”getElementById”。
<script> var foo = "get - element - by - id"; function translate(res) { var arr = res.split("-"); // 以-为分隔符截取字符串,返回数组 for (var i = 1; i < arr.length; i++) { arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1); } res = arr.join(""); // 返回字符串 return res; } console.log(translate(foo)) </script>
7.有这样一个URL:http://item.taobao.com/item.h...,请写一段JS程序提取URL中的各个GET参数(参数名和参数个数不确定),将其按key-value形式返回到一个json结构中
<script> function serilizeUrl(url) { var result = {}; url = url.split("?")[1]; var map = url.split("&"); for (var i = 0; i < map.length; i++) { result[map[i].split("=")[0]] = map[i].split("=")[1]; } console.log(result); } var url = "http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e"; serilizeUrl(url); </script>
8..写一个function,清除字符串前后的空格。(兼容所有浏览器)
//重写trim方法 if (!String.prototype.trim) { String.prototype.trim = function () { return this.replace(/^s+/, "").replace(/s+$/, ""); } } //写fntrim去掉左右空格 function fntrim(str) { return str.replace(/^s+/, "").replace(/s+$/, ""); }
以上是关于前端面试题整理的主要内容,如果未能解决你的问题,请参考以下文章