# javascript题目
# HTML
#
的 title 和 alt 有什么区别?
alt 主要是无法加载显示图片时,代替文字,搜索引擎时主要是 alt
,alt
只适用于图片 img。 鼠标悬浮文字上显示文字的诗 title
属性,title
适用于很多标签。
# 什么是 web 语义化?html5 有哪些语义化标签?语义化有什么好处?
W3C 组织意识到了之前 HTML 版本的不足,推出的 HTML5 进一步推进了 Web 语义化发展,采用了诸如 footer、section 等语义化标签,弥补了采用 id="footer"或者 class="footer"形式的不足,以更好的推动 Web 的发展。
<nav>
、
<article>
、<sections
>、
<aside>
、
<footer></footer></aside
></sections>
</article>
</nav>
# CSS
# display: none;与 visibility: hidden;的区别?
是否是继承属性:display 不是继承属性,而 visibility 是继承属性。
# 如何分别水平、垂直居中一个元素?
- 行内水平居中
#container {
text-align: center;
}
- 块状水平居中
#center {
margin: 0 auto;
}
- 多个块状元素的水平居中
#container {
text-align: center;
}
#center {
display: inline-block;
}
<!-- flex -- > #container {
justify-content: center;
display: flex;
}
- 已知高度宽度元素的水平垂直居中
<!-- 1 -- > #container {
position: relative;
}
#center {
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin: -50px 0 0 -50px;
}
<!-- 2 -- > #container {
position: relative;
}
#center {
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
- 未知高度和宽度元素的水平垂直居中
<!-- base -- > #container {
display: table-cell;
text-align: center;
vertical-align: middle;
}
#center {
}
<!-- css3 -- > #container {
position: relative;
}
#center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<!-- flex -- > #container {
display: flex;
justify-content: center;
align-items: center;
}
#center {
}
# JS
# 如何实现一个 JS 对象的深度克隆?
先来说一下什么是深度克隆:深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。 举个例子,一个人名叫张三,后来用他克隆(假设法律允许)了另外一个人,叫李四,不管是张三缺胳膊少腿还是李四缺胳膊少腿都不会影响另外一个人。
在 JavaScript 中,对于 Object 和 Array 这类引用类型值,当从一个变量向另一个变量复制引用类型值时,这个值的副本其实是一个指针,两个变量指向同一个堆对象,改变其中一个变量,另一个也会受到影响。
// 对象
var o1 = { a: 1 }
var o2 = o1
console.log(o1 === o2) // =>true
o2.a = 2
console.log(o1.a) // => 2
// 数组
var o1 = [1, 2, 3]
var o2 = o1
console.log(o1 === o2) // => true
o2.push(4)
console.log(o1) // => [1,2,3,4]
这种拷贝分为两种情况:拷贝引用和拷贝实例,也就是我们说的浅拷贝和深拷贝
浅拷贝(shallow copy)代码实现:
function shallowClone(source) {
if (!source || typeof source !== 'object') {
throw new Error('error arguments')
}
var targetObj = source.constructor === Array ? [] : {}
for (var keys in source) {
if (source.hasOwnProperty(keys)) {
targetObj[keys] = source[keys]
}
}
return targetObj
}
深拷贝(deep copy) 深拷贝也就是拷贝出一个新的实例,新的实例和之前的实例互不影响,深拷贝的实现有几种方法,首先我们可以借助 jQuery,lodash 等第三方库完成一个深拷贝实例。在 jQuery 中可以通过添加一个参数来实现递归 extend,调用$.extend(true, {}, ...)就可以实现一个深拷贝。
深拷贝(deep copy)代码实现:
// 递归实现一个深拷贝
function deepClone(source) {
//判断传入的参数是否是对象
if (!source || typeof source !== 'object') {
throw new Error('error arguments', 'shallowClone')
}
// 判断要深拷贝的是数组还是对象
var targetObj = source.constructor === Array ? [] : {}
// 遍历复制对象
for (var keys in source) {
if (source.hasOwnProperty(keys)) {
// 判断如果为对象的key还是对象的话就递归调用
if (source[keys] && typeof source[keys] === 'object') {
targetObj[keys] = source[keys].constructor === Array ? [] : {}
targetObj[keys] = deepClone(source[keys])
} else {
targetObj[keys] = source[keys]
}
}
}
// 返回克隆完的对象
return targetObj
}
// test example
var o1 = {
arr: [1, 2, 3],
obj: {
key: 'value'
},
func: function() {
return 1
}
}
var o3 = deepClone(o1)
console.log(o3 === o1) // => false
console.log(o3.obj === o1.obj) // => false
console.log(o2.func === o1.func) // => true
# 事件冒泡
# IE 与火狐的事件机制有什么区别?什么是事件冒泡?如何阻止冒泡?
- 我们在网页中的某个操作(有的操作对应多个事件)。例如:当我们点击一个按钮就会产生一个事件。是可以被 JavaScript 侦测到的行为
- 事件处理机制:IE 是事件冒泡、firefox 同时支持两种事件模型,也就是:捕获型事件和冒泡型事件
- ev.stopPropagation();
- 注意旧 ie 的方法:ev.cancelBubble = true;
# 在浏览器地址栏中输入一个 URL 后回车,背后会进行哪些技术步骤?
# 编程实现获取 URL 中的参数:
指定参数名称,返回该参数的值或者空字符串;
不指定参数名称,返回全部的参数对象或者{};
如果存在多个同名参数,则返回数组;
/**
* @param {string} Url
* @param {string} Key
* @return {Object}
*/
function getUrlParam(Url, Key) {
var param = Url.split('#')[0].split('?')[1]
if (Key) {
//指定参数名称
var strs = param.split('&')
var arrs = new Array() //如果存在多个同名参数,则返回数组
for (var i = 0, len = strs.length; i < len; i++) {
var tmp = strs[i].split('=')
if (tmp[0] == Key) {
arrs.push(tmp[1])
}
}
if (arrs.length == 1) {
//返回该参数的值或者空字符串
return arrs[0]
} else if (arrs.length == 0) {
return ''
} else {
return arrs
}
} else {
//不指定参数名称,返回全部的参数对象 或者 {}
if (param == undefined || param == '') {
return {}
} else {
var strs = param.split('&')
var arrObj = new Object()
for (var i = 0, len = strs.length; i < len; i++) {
var tmp = strs[i].split('=')
if (!(tmp[0] in arrObj)) {
arrObj[tmp[0]] = []
}
arrObj[tmp[0]].push(tmp[1])
}
return arrObj
}
}
}
// testUrl
//http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe
# 输入习题
# 以下程序输出结果是?
function fn(a) {
console.log(a)
var a = 2
function a() {}
console.log(a)
}
fn(1)
# 以下程序输出结果是?
var a = 10
a.pro = 10
console.log(a.pro + a)
var s = 'hello'
s.pro = 'world'
console.log(s.pro + s)
# 写出输出结果
console.log(typeof null)
console.log(typeof {})
console.log(typeof [])
console.log(typeof undefined)
# 写出输出结果?
function printing() {
console.log(1)
setTimeout(function() {
console.log(2)
}, 1000)
setTimeout(function() {
console.log(3)
}, 0)
console.log(4)
}
printing()
# 如何判断一个对象是否为函数?
function isFunction(fn) {
return Object.prototype.toString.call(fn) === '[object Function]'
}
# 写出几种 js 跳转的常见方式?
<!-- 第一种:直接跳转加参数 -->
<script language="javascript" type="text/javascript">
window.location.href="login.jsp?backurl="+window.location.href;
</script>
<!-- 直接跳转无参数: -->
<script>window.location.href='http://www.baidu.com';</script>
<!-- 第二种:返回上一次预览界面 -->
<script language="javascript">
alert("返回");
window.history.back(-1);
</script>
<!-- 标签嵌套: -->
<a href="javascript:history.go(-1)">返回上一步</a>
<a href="<%=Request.ServerVariables("HTTP_REFERER")%>">返回上一步</a>
<!-- 第三种:指定跳转页面 对框架无效。。。 -->
<script language="javascript">
window.navigate("top.jsp");
</script>
<!-- 第四种:指定自身跳转页面 对框架无效。。 -->
<script language="JavaScript">
self.location='top.htm';
</script>
<!-- 第五种:指定自身跳转页面 对框架有效。。 -->
<script language="javascript">
alert("非法访问!");
top.location='xx.aspx';
</script>
<!-- 第六种:按钮式 在button按钮添加 事件跳转。 -->
<input name="pclog" type="button" value="GO" onClick="location.href='login.aspx'">
<!-- 第七种:在新窗口打开: -->
<a href="javascript:" onClick="window.open('login.aspx','','height=500,width=611,scrollbars=yes,status=yes')">开新窗口</a>
# 写出客户端存储 localStorage 和 sessionStorage 的 set、get 方法,localStorage 和 sessionStorage 有何区别?
# 通过 JS 获取页面尺寸、屏幕的方法?
网页可见区域宽:document.body.clientWidth
网页可见区域高:document.body.clientHeight
网页可见区域宽:document.body.offsetWidth (包括边线的宽)
网页可见区域高:document.body.offsetHeight (包括边线的宽)
网页正文全文宽:document.body.scrollWidth
网页正文全文高:document.body.scrollHeight
网页被卷去的高:document.body.scrollTop
网页被卷去的左:document.body.scrollLeft
网页正文部分上:window.screenTop
网页正文部分左:window.screenLeft
屏幕分辨率的高:window.screen.height
屏幕分辨率的宽:window.screen.width
屏幕可用工作区高度:window.screen.availHeight
屏幕可用工作区宽度:window.screen.availWidth
# 列举 JS 实现跨域的几种方式?
# 列举几种立即执行函数的实现方式。
# var numberArray = [3, 6, 2, 4, 1, 5];
- 实现对该数组的倒排,输出[5, 1, 4, 2, 6, 3]
- 实现对该数组的的将序排列,输出[6, 5, 4, 3, 2, 1];
# 编写一个方法,去掉一个数组的重复元素
function unique(arr) {
var newArr = []
for (var i = 0, item; (item = arr[i++]); ) {
if (newArr.indexOf(item) === -1) {
newArr.push(item)
}
}
return newArr
}
# 写一个简单的 ajax 示例
# JavaScript 有哪些方法定义对象?
# HTTP
# HTTP request 报文结构是怎样的?
请求行: {请求方法} {资源路径} {协议版本}
请求头: 紧跟请求行的下一行,所有的请求头,除 Host 外都是可选的。
空行: 告诉服务器请求头部到此为止。
消息体: 消息的主体部分,消息体的数据格式通过 header 里面的 Content-Type 属性指定。
# 描述常见的 HTTP 状态码和 HTTP 方法
200
- 请求成功301
- 资源(网页等)被永久转移到其它 URL404
- 请求的资源(网页等)不存在500
- 内部服务器错误
根据 HTTP 标准,HTTP 请求可以使用多种请求方法。
HTTP1.0 定义了三种请求方法: GET
, POST
和 HEAD
方法。
HTTP1.1 新增了五种请求方法:OPTIONS
, PUT
, DELETE
, TRACE
和 CONNECT
方法。
序号 | 方法 | 描述 |
---|---|---|
1 | GET | 请求指定的页面信息,并返回实体主体。 |
2 | HEAD | 类似于 get 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
3 | POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。 |
4 | PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
5 | DELETE | 请求服务器删除指定的页面。 |
6 | CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 |
7 | OPTIONS | 允许客户端查看服务器的性能。 |
8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
# HTTP 状态码及其含义?
# Vue
# 请简单描述 Vue 双向绑定底层实现原理,常用到的指令及 Vue 实例的生命周期
# 算法题
# 给出两个单词 word1 和 word2,找出将 word1 转换成 word2 所使用的最少的步骤数(每个操作记为一步)。
你可以对一个单词进行以下三种操作
- 插入一个字符;
- 删除一个字符;
- 替换一个字符;
/**
* @param {string} word1
* @param {string} word2
* @return {number}
*/
var minDistance = function(word1, word2) {
var len1 = word1.length,
len2 = word2.length,
matrix = [],
i,
j
if (len1 === 0 || len2 === 0) {
return Math.max(len1, len2)
}
//initialization
for (i = 0; i <= len1; i++) {
matrix[i] = []
matrix[i][0] = i
}
for (j = 0; j <= len2; j++) {
matrix[0][j] = j
}
for (i = 1; i <= len1; i++) {
for (j = 1; j <= len2; j++) {
if (word1.charAt(i - 1) === word2.charAt(j - 1)) {
matrix[i][j] = matrix[i - 1][j - 1]
} else {
matrix[i][j] =
Math.min(matrix[i - 1][j], matrix[i][j - 1], matrix[i - 1][j - 1]) + 1
}
}
}
return matrix[len1][len2]
}
# 性能优化
# 如何进行网站性能优化,请简述。
- 代码层面:避免使用 css 表达式,避免使用高级选择器,通配选择器。
- 缓存利用:缓存 Ajax,使用 CDN,使用外部 js 和 css 文件以便缓存,添加 Expires 头,服务端配置 Etag,减少 DNS 查找等
- 请求数量:合并样式和脚本,使用 css 图片精灵,初始首屏之外的图片资源按需加载,静态资源延迟加载。
- 请求带宽:压缩文件,开启 GZIP, 代码层面的优化
- 用 hash-table 来优化查找
- 少用全局变量
- 用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能
- 用 setTimeout 来避免页面失去响应
- 缓存 DOM 节点查找的结果
- 避免使用 CSS Expression
- 避免全局查询
- 避免使用 with(with 会创建自己的作用域,会增加作用域链长度)
- 多个变量声明合并
- 避免图片和 iFrame 等的空 Src。空 Src 会重新加载当前页面,影响速度和效率
- 尽量避免写在 HTML 标签中写 Style 属性
- 移动端性能优化
- 尽量使用 css3 动画,开启硬件加速。
- 适当使用 touch 事件代替 click 事件。
- 避免使用 css3 渐变阴影效果。
- 可以用 transform: translateZ(0) 来开启硬件加速。(见下面的详细解释)
- 不滥用 Float。Float 在渲染时计算量比较大,尽量减少使用
- 不滥用 Web 字体。Web 字体需要下载,解析,重绘当前页面,尽量减少使用。
- 合理使用 requestAnimationFrame 动画代替 setTimeout
- CSS 中的属性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、WebGL、Video)会触发 GPU 渲染,请合理使用。过渡使用会引发手机过耗电增加
- PC 端的在移动端同样适用