javascript题目

# javascript题目

# HTML

# 的 title 和 alt 有什么区别?

alt 主要是无法加载显示图片时,代替文字,搜索引擎时主要是 altalt 只适用于图片 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 与火狐的事件机制有什么区别?什么是事件冒泡?如何阻止冒泡?

  1. 我们在网页中的某个操作(有的操作对应多个事件)。例如:当我们点击一个按钮就会产生一个事件。是可以被 JavaScript 侦测到的行为
  2. 事件处理机制:IE 是事件冒泡、firefox 同时支持两种事件模型,也就是:捕获型事件和冒泡型事件
  3. ev.stopPropagation();
  • 注意旧 ie 的方法:ev.cancelBubble = true;

# 在浏览器地址栏中输入一个 URL 后回车,背后会进行哪些技术步骤?

# 编程实现获取 URL 中的参数:

  1. 指定参数名称,返回该参数的值或者空字符串;

  2. 不指定参数名称,返回全部的参数对象或者{};

  3. 如果存在多个同名参数,则返回数组;

/**
 * @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 有何区别?

参考详情 (opens new window)

# 通过 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 实现跨域的几种方式?

参考详情 (opens new window)

# 列举几种立即执行函数的实现方式。

参考详情 (opens new window)

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

  1. 实现对该数组的倒排,输出[5, 1, 4, 2, 6, 3]
  2. 实现对该数组的的将序排列,输出[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 示例

参考详情 (opens new window)

# JavaScript 有哪些方法定义对象?

参考详情 (opens new window)

# HTTP

# HTTP request 报文结构是怎样的?

  • 请求行: {请求方法} {资源路径} {协议版本}

  • 请求头: 紧跟请求行的下一行,所有的请求头,除 Host 外都是可选的。

  • 空行: 告诉服务器请求头部到此为止。

  • 消息体: 消息的主体部分,消息体的数据格式通过 header 里面的 Content-Type 属性指定。

# 描述常见的 HTTP 状态码和 HTTP 方法

  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它 URL
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误

根据 HTTP 标准,HTTP 请求可以使用多种请求方法。

HTTP1.0 定义了三种请求方法: GET, POSTHEAD 方法。

HTTP1.1 新增了五种请求方法:OPTIONS, PUT, DELETE, TRACECONNECT 方法。

序号 方法 描述
1 GET 请求指定的页面信息,并返回实体主体。
2 HEAD 类似于 get 请求,只不过返回的响应中没有具体的内容,用于获取报头
3 POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
4 PUT 从客户端向服务器传送的数据取代指定的文档的内容。
5 DELETE 请求服务器删除指定的页面。
6 CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
7 OPTIONS 允许客户端查看服务器的性能。
8 TRACE 回显服务器收到的请求,主要用于测试或诊断。

# HTTP 状态码及其含义?

参考链接 (opens new window)

# Vue

# 请简单描述 Vue 双向绑定底层实现原理,常用到的指令及 Vue 实例的生命周期

# 算法题

# 给出两个单词 word1 和 word2,找出将 word1 转换成 word2 所使用的最少的步骤数(每个操作记为一步)。

你可以对一个单词进行以下三种操作

  1. 插入一个字符;
  2. 删除一个字符;
  3. 替换一个字符;
/**
 * @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 端的在移动端同样适用