大厂前端面试题

1、[单选题] 有以下 ES6 代码 

function * gen() { 
  yield 1;
  yield 2;
  yield 3; 
} 

下面选项描述正确的是哪个? 

A.gen()执行后返回 2

B.gen()执行后返回 undefined

C.gen()执行后返回一个 Generator 对象

D.gen()执行后返回 1

答案:C

提示:这是 ES6 的新 feature, function 后面带  * 的叫做 generator function。函数运行时, 返回一个迭代器。 

2、[不定项选择题] 语句 var arr=[a,b,c,d];执行后,数组 arr 中每项都是一个整数,下面得到其中最大整数语 句正确的是哪几项? 

A.Math.max(arr)

B.Math.max(arr[0], arr[1], arr[2], arr[3])

C.Math.max.call(Math, arr[0], arr[1], arr[2], arr[3])

D.Math.max.apply(Math,arr) 

答案:B C D 

提示: A 选项错误 

因为函数 Math.max(x);的参数是 Number 类型,可以使小数,整数,正数,负数或者是 0.如果不是上面所述类型就会返回 NaN. 

3、[问答题] 写一个 traverse 函数,输出所有页面宽度和高度大于 50 像素的节点。 

<script language="javascript">
  function traverse() {
    var arr = [];
    var elements = [];
    if (document.all) {
      elements = document.all;
    } else {
      elements = document.getElementsByTagName("*");
    }
    for (var i = 0; i < elements.length; i++) {
      var ele = elements[i];
      // width 返回的是字符串   offsetWidth 返回的是带边框的 Number 型的数字 
      var width = parseFloat(ele.style.width) || ele.offsetWidth;
      var height = parseFloat(ele.style.height) || ele.offsetHeight;
      if (width > 50 && height > 50) {
        arr.push(elements[i].tagName);
      }
    }
    return arr;
  }
  window.onload = function () {
    console.log(traverse());
    console.log("a");
    console.log('a');
  }
</script>

4、[问答题] 请写一个表格以及对应的 CSS,使表格奇数行为白色背景,偶数行为灰色背景,鼠标移 上去时为黄色背景。 

<table>
  <tr><td>第一行</td></tr>
  <tr><td>第二行</td></tr>
  <tr><td>第三行</td></tr>
  <tr><td>第四行</td></tr>
  <tr><td>第五行</td></tr>
</table>
table tr:nth-child(odd){
  background-color: white;
}
table tr:nth-child(even){
  background-color: gray;
}
table tr:hover{
  background-color: yellow;
}

5、[问答题]  写一个求和的函数 sum,达到下面的效果  

// Should equal 15 
sum(1, 2, 3, 4, 5); 
// Should equal 0 
sum(5, null, -5); 
// Should equal 10 
sum('1.0', false, 1, true, 1, 'A', 1, 'B', 1, 'C', 1, 'D', 1, 'E', 1, 'F', 1, 'G', 1); 
// Should equal 0.3, not 0.30000000000000004 
sum(0.1, 0.2)

function sum() {
  var nResult = 0;
  for (var i = 0, l = arguments.length; i < l; i++) {
    nResult += window.parseFloat(arguments[i]) || 0;
  }
  return nResult.toFixed(3) * 1000 / 1000;
}

6、[填空题] 删除给定数组中的第二项和第三项,并且在得到的新的数组中第二项后面添加一个新的 值:

var arr1 = ['a','b','c','d','e']; 

var arr2 = arr1. 1 ( 2 , 3 ,'newvalue') 

var arr1 = ['a','b','c','d','e']; 
var arr2 = arr1.splice( 1,2 ,'newvalue') 
console.log(arr1);

7、[填空题] 在空白处填入适当的代码使输出结果成立:

function showMoney() {
  1
};
var personA = new Object;
var personB = new Object;
personA.money = "100";
personB.money = "150";
personA.showMoney = showMoney;
personB.showMoney = showMoney;

// 输出结果:
personA.showMoney(); //"100"  
personB.showMoney(); //"150"

答案: return this.money

8、[填空题] 使用 for in 循环数组中的元素会枚举原型链上的所有属性,过滤这些属性的方式是使 用 ? 函数 

hasOwnProperty 

9、[问答题] 请实现一个 fibonacci 函数,要求其参数和返回值如下所示:

/** 
 * @desc: fibonacci  
 * @param: count {Number}  
 * @return: result {Number} 
 * 第 count 个 fibonacci 值,计数从 0 开始   
 * fibonacci 数列为:[1, 1, 2, 3, 5, 8, 13, 21, 34 „]   
 * 则 getNthFibonacci(0)返回值为 1   
 * 则 getNthFibonacci(4)返回值为 5  */
function getNthFibonacci(count) {
  if (count <= 1) {
    return 1;
  }
  return getNthFibonacci(count - 1) + getNthFibonacci(count - 2);
} 

10、[填空题] 

输出对象中值大于 2 的 key 的数组 

var data = {a: 1, b: 2, c: 3, d: 4}; 

Object.keys(data).filter(function(x) { return ? ;})

期待输出:[“c”,”d”] 

答案: data[x] > 2 

11、[填空题] 填写内容让下面代码支持 a.name = “name1”; b.name = “name2”;

function obj(name) {
  ?
}
obj.? = "name2";
var a = obj("name1");
var b = new obj; 
function obj(name) {
  if(name){
    this.name = name
  }
  return this
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj; 

12、JavaScript语言特性中,有很多方面和我们接触的其他编程语言不太一样,比如说,JavaScript语言实现继承机制的核心就是 《prototype》,而不是Java语言那样的类式继承。JavaScript解析引擎在读取一个 Object 的属性的值时,有沿着《原型链》向上寻找,如果最终没有找到,则该属性值为《undefined》;如果最终找到该属性的值,则返回结果。与这个过程不同的是,当JavaScript解析引擎执行“给一个Object的某个属性赋值”的时候,如果当前Object存在该属性,则改写该属性的值,如果当前的Object本身并不存在该属性,则赋值该属性的值。

13、[单选题] 下面有关 html 的描述,不推荐的是? 

A.在页面顶部添加 doctype 声明; 

B.在 </head> „ <body> 中间插入 HTML 代码; 

C.避免使用 <font> 标签; 

D.使用 <table> 元素展现学生成绩表等数据。 

答案:B

14、[单选题] 下面关于 CSS 布局的描述,不正确的是? 

A.块级元素实际占用的宽度与它的 width 属性有关; 

B.块级元素实际占用的宽度与它的 border 属性有关; 

C.块级元素实际占用的宽度与它的 padding 属性有关; 

D.块级元素实际占用的宽度与它的 background 属性有关。 

答案:D

15:、[单选题]下列事件哪个不是由鼠标触发的事件()

A.click 

B.contextmenu 

C.mouseout 

D.keydown 

答案:D

16、[问答题] 请说说 cache-control 是怎么回事? 

  网页的缓存是有 HTTP 消息头中的 “Cache-control” 来控制的,常见的取值有 private 、no-cache、max-age、must-revalidate 等,默认为 private

  Expires 头部字段提供一个日期和时间,响应在该日期和时间后被认为失效。允许客户端在这个时间之前不去检查(发请求),等同 max-age 的效果。但是如果同时存在,则被 Cache-Control 的 max-age 覆盖

  Expires = "Expires" : "HTTP-date"

  例如: Expires: Thu,01 Dec 1994 16:00:00 GMT  (必须是GMT格式)

  如果把它设置为-1,则表示立即过期

  Expires 和 max-age 都可以用来指定文档的过期时间,但是二者有一些细微差别

  1.Expires 在 HTTP/1.0 中已经定义,Cache-Control:max-age 在HTTP/1.1中才有定义,为了向下兼容,仅使用 max-age不够。

  2.Expires 指定一个绝对的过期时间(GMT 格式),这么做会导致至少 2 个问题: 

    2.1 客户端和服务器时间不同步导致 Expires 的配置出现问题。 

     2.2 很容易在配置后忘记具体的过期时间,导致过期来临出现浪涌现象 

  3. max-age 指定的是从文档被访问后的存活时间,这个时间是个相对值(比如:3600s), 相对的是文档第一次被请求时服务器记录的 Request_time(请求时间) 

  4. Expires 指定的时间可以是相对文件的最后访问时间(Atime)或者修改时间(MTime),而 max-age 相对对的是文档的请求时间(Atime) 

  5.如果值为 no-cache,那么每次都会访问服务器。如果值为 max-age,则在过期之前不 会重复访问服务器。

17、[问答题] 你了解 HTTP 状态码吗,请随便介绍一下。 

  100 Continue  继续,一般在发送 post 请求时,已发送了 http header 之后服务端将返回 此信息,表示确认,之后发送具体参数信息 

  200 OK   正常返回信息 

  201 Created  请求成功并且服务器创建了新的资源 

  202 Accepted  服务器已接受请求,但尚未处理 

  301 Moved Permanently  请求的网页已永久移动到新位置 

  302 Found  临时性重定向 

  303 See Other  临时性重定向,且总是使用 GET 请求新的 URI 

  304 Not Modified  自从上次请求后,请求的网页未修改过 

  400 Bad Request  服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容 发起请求 

  401 Unauthorized  请求未授权 

  403 Forbidden  禁止访问 

  404 Not Found  找不到如何与 URI 相匹配的资源 

  500 Internal Server Error  最常见的服务器端错误 

  503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护) 

18、[问答题] 如何获取 UA? 

通过JS获取浏览器UA(User Agent,用户代理)

//获取完整的浏览器名称
document.Browser.Name.value=navigator.appName; 
//获取浏览器的版本,一般不与实际的浏览器版本对应
document.Browser.Version.value=navigator.appVersion; 
//获取浏览器的名称。通常都是Mozilla,即使在非Mozilla的浏览器中也是如此
document.Browser.Code.value=navigator.appCodeName; 
//获取浏览器的用户代理字符串
document.Browser.Agent.value=navigator.userAgent;

19、[问答题] 说说对网站重构的理解。 

网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致性的行为。也就是说在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致性的UI

对于传统的网站来说,重构通常是:

(1)表格(table)布局改为 DIV + CSS

(2)使网页前端兼容于现代浏览器(针对于不合规范的CSS、如对 IE6 有效的)

(3)对于移动平台的优化

(4)针对SEO进行优化

(5)深层次的网站重构应该考虑的方面

(6)减少代码的耦合

(7)让代码保持弹性

(8)严格按规范编写代码

(9)设计可扩展的API

(10)代替旧有的框架、语言

(11)增强用户体验

(12)通常来说对于速度的优化也包含在重构中

(13)压缩JS、CSS、image 等前端资源(通常是由服务器来解决的)

(14)程序的性能优化(如数据读写)

(15)采用CDN来加速资源加载

(16)对于 JS DOM 的优化

(17)HTTP服务器的文件缓存

SEO:(Search Engine Optimization):汉译为搜索引擎优化。是一种方式:利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名。

目的是让其在行业内占据领先地位,获得品牌收益。很大程度上是网站经营者的一种商业行为,将自己或自己公司的排名前移。
 
20、[问答题] js 对象的深度克隆代码实现。 
function clone(obj) {
  let ret
  if (Array.isArray(obj)) {
    ret = [] // 创建一个空数组
    for (let i = 0; i < obj.length; i++) {
      ret[i] = clone(obj[i])
    }
    return ret
  } else if (Object.prototype.toString.call(obj) === "[object Object]") {
    ret = {} // 创建一个空对象
    for (let i in obj) {
      ret[i] = clone(obj[i])
    }
    return ret
  } else {
    return obj
  }
}

 21、[问答题] Ajax 是什么?Ajax 的交互模型?同步和异步的区别?如何解决跨域问题? 

(1)ajax 的全称是异步的 JavaScript 和 XML ,是一种创建快速动态的技术,通过在后台与服务器进行少量数据交互,实现网页的异步更新,在不重新加载整个界面的情况下,做到网页的部分刷新

(2)ajax的交互模型(ajax的过程)

  • 用户发出异步请求
  • 创建 XMLHttpRequest 对象
  • 告诉 XMLHttpRequest 对象哪个函数会处理  XMLHttpRequest 对象状态的改变,为此要把对象的 onReadyStateChange 属性设置为响应该事件的 JavaScript 函数的引用
  • 创建请求,用 open 方法指定是get还是post,是否异步,url地址
  • 发送请求,send方法
  • 接收结果并分析
  • 实现刷新

(3)同步和异步的区别:

  • 同步:脚本会停留并等待服务器发送回复然后在继续
  • 异步:脚本允许页面继续其进程并处理可能的回复

(4)跨域问题的解决:

  • 使用 document.domain + iframe 解决跨子域问题
  • 使用 window.name
  • 使用 flash
  • 使用 iframe + location.hase
  • 使用 html5 的 postMessage
  • 使用 jsonp (创建动态 script)

22、[问答题] IE 与火狐的事件机制有什么区别? 如何阻止冒泡? 

(1)我们在网页中的某个操作(有的操作对应多个事件)。例如:当我们点击一个按钮就会产生一个事件。是可以被JavaScript侦测到的行为

(2)事件处理机制:IE是事件冒泡,firefox 同时支持两种事件模型(捕获型事件和冒泡型事件)

(3)ev.stopPropagation()  ---注意旧 ie 的方法:ev.cancelBubble = true

23、[问答题]  WEB 应用从服务器主动推送 Data 到客户端有那些方式? 

(1)html5 websoket

(2)websocket 通过 flash

(3)XHR 长时间连接

(4)XHR Multipart Streaming

(5)不可见的 Iframe

(6)<sctipt>标签的长时间连接(可跨域)

24、[问答题] JavaScript 原型,原型链 ? 有什么特点? 

(1)原型对象也是普通的对象,是对象一个自带隐式的 __proto__ 属性,原型也有可能有自己的原型,如果一个原型对象的原型不为 null 的话,我们就称之为原型链

(2)原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链

25、[问答题]  Node.js 的适用场景 

(1)高并发

(2)聊天

(3)实时消息推送

26、[问答题]  eval 是做什么的,有什么建议? 

(1)它的功能是把对应的字符串解析成 JS 代码并运行

(2)应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)

27、[问答题]  哪些地方会出现 css 阻塞,哪些地方会出现 js 阻塞? 

(1)js的阻塞特性:
  所有浏览器在下载JS的时候,会阻止一切其他活动,比如其他资源的下载,内容的呈现等等。
  直到JS下载、解析、执行完毕后才开始继续并行下载其他资源并呈现内容。
  为了提高用户体验,新一代浏览器都支持并行下载JS,但是JS下载仍然会阻塞其它资源的下载(例如.图片,css文件等)。
由于浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以就会阻塞其他的下载和呈现。
嵌入JS会阻塞所有内容的呈现,而外部JS只会阻塞其后内容的显示,2种方式都会阻塞其后资源的下载。
也就是说外部样式不会阻塞外部脚本的加载,但会阻塞外部脚本的执行。
 
(2)CSS怎么会阻塞加载了?
CSS本来是可以并行下载的,在什么情况下会出现阻塞加载了(在测试观察中,IE6下CSS都是阻塞加载)
  • 当CSS后面跟着嵌入的JS的时候,该CSS就会出现阻塞后面资源下载的情况;
  • 而当把嵌入JS放到CSS前面,就不会出现阻塞的情况了。
根本原因:
  • 因为浏览器会维持html中css和js的顺序,样式表必须在嵌入的JS执行前先加载、解析完。
  • 而嵌入的JS会阻塞后面的资源加载,所以就会出现上面CSS阻塞下载的情况。
嵌入JS应该放在什么位置?
  • 放在底部,虽然放在底部照样会阻塞所有呈现,但不会阻塞资源下载。
  • 如果嵌入JS放在head中,请把嵌入JS放在CSS头部。
  • 使用defer(只支持IE)
  • 不要在嵌入的JS中调用运行时间较长的函数,如果一定要用,可以用`setTimeout`来调用

28、[问答题]  GET 和 POST 的区别,何时使用 POST? 

GET:一般用于信息获取,使用URL传递参数,对所发送的信息数量有限制,一般在 2000 个字符

POST:一般用于修改服务器上的资源,对所发送的信息没有限制

GET方式需要使用 Request.QueryString 来取得变量的值

POST方式通过 Request.Form 来获取变量的值

也就是说Get是通过地址栏来传值,而Post是通过提交表单来传值

在以下情况下,使用POST请求:

(1)无法使用缓存文件(更新服务器上的文件或数据库)

(2)向服务器发送大量数据(POST没有数据量限制)

(3)发送包含未知字符的用户输入时,POST比GET更稳定也更可靠

29、[问答题]  请解释一下 JavaScript 的同源策略。 

  同源策略是客户端脚本(尤其是JavaScript)的重要安全度量标准。其目的是防止某个文档或脚本从多个不同源装载。

  这里的同源策略指的是:协议、域名、端口号相同,同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性。

为什么要有同源限制:

  我们举例说明:比如一个黑客程序,他利用 Iframe 把真正的银行登录页面嵌入他的页面上,当你使用真实的用户名、密码登录时,他的页面就可以通过JavaScript读取到你的表单中input中的内容,这样用户名、密码就轻松到手了。

30、[问答题]  什么叫优雅降级和渐进增强? 

(1)优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作。由于 IE 独特的盒模型布局问题,针对不同版本的 IE 的 hack实践过优雅降级了,为那些无法支持功能的浏览器增加候选方案,使之在旧式浏览器上以某种形式降级体验却不至于完全失效。

(2)渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,向页面增加无害于基础浏览器的额外样式和功能。当浏览器支持时,它们会自动地呈现出来并发挥作用。

31、[问答题]  哪些操作会造成内存泄漏? 

内存泄漏指任何对象在你不在拥有或需要它之后仍然存在。

垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用为0(没有其他对象引用过该对象),或对该对象的唯一引用是循环的,那么该对象的内存即可回收。

(1)setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏

(2)闭包

(3)控制台日志

(4)循环引用(在两个对象彼此引用且彼此保留时,就会产生一个循环引用)

32、[问答题]  .call() 和 .apply() 的作用? 

动态改变某个类的某个方法的运行环境

33、[单选题] 

function Foo() {
  var i = 0;
  return function () {
    document.write(i++);
  }
}
var f1 = Foo(), f2 = Foo();
f1();
f1();
f2(); 

请问以上程序的输出是()

A.010 
B.012 
C.000 
D.011
答案:A
  这是一个闭包,闭包可以用在许多地方。它的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
  这里的局部变量 i ,对 f1() 来说是全局变量,对 f2() 来说也是全局变量,但是 f1() 的 i 和 f2() 的 i 有事相互独立不可见的,f1() 每执行一次,f1() 的 i 就加 1 ,f2() 每执行一次,f2() 的 i 就加 1,但是相互之间不影响,因此是 010
 
34、[单选题]  以下 Js 程序的输出是什么() 
var a = "undefined";
var b = "false";
var c = "";
function assert(aVar) {
  if (aVar)
    alert(true);
  else
    alert(false);
}
assert(a);
assert(b);
assert(c); 
A.true,true,true 
B.true,true,false 
C.false,false,true 
D.false,false,false 
答案:B
  undefined 和 false 都是 JavaScript的数据类型,但是用双引号引起了就是字符串了,空串相当于 false,否则是 true
 
35、[问答题]  请实现 javascript 中的 indexOf 功能,判断一个字符串 a 中是否包含另一个字符串 b。 
a)如果包含,需要返回匹配字符串 b 的位置。 
b)如果不包含,需要返回-1。 
如:indexOf("hello","el") return 1。 
// 方法1
function indexOf(str, subStr){
  var ret = str.match(subStr)
  return ret ? ret.index : -1
}

// 方法2
function indexOf(a, b){
  return a.search(b)
}

36、[单选题] 

var myObject = {
  foo: "bar",
  func: function () {
    var self = this;
    console.log(this.foo);
    console.log(self.foo);
    (function () {
      console.log(this.foo);
      console.log(self.foo);
    }());
  }
};
myObject.func(); 

程序的输出是什么?

A.bar bar bar bar 
B.bar bar bar undefined 
C.bar bar undefined bar 
D.undefined bar undefined bar 
答案:C
方法/函数是由谁(对象)调用的,方法/函数内部的this就是指向谁(对象)
注意:是被谁调用,不是处于谁的作用域,即使在作用域
1、func 是由 myObject 调用的,this 指向 myObject 
2、self 指向 myObject ,相当于 myObject 的this副本
3、这个立即执行匿名函数表达式(IIFE)是由window调用的,this指向window
4、IIEF 的作用域处于 myObject 的作用域中,本作用域找不到 self 变量,沿着作用域链向上查找 self 变量,找到了指向 myObject 的self
 
 
37、[不定项选择题] 下面有关 javascript 内部对象的描述,正确的有?
A.History 对象包含用户(在浏览器窗口中)访问过的 URL 
B.Location 对象包含有关当前 URL 的信息 
C.Window 对象表示浏览器中打开的窗口 
D.Navigator 对象包含有关浏览器的信息 
答案:ABCD
Navagator:提供有关浏览器的信息。
Window:Window对象处于对象层次的最顶层,它提供了处理Navagator窗口的方法和属性。
Location:提供了与当前打开的URL一起工作的方法和属性,是一个静态的对象。
History:提供了与历史清单有关的信息。
Document:包含与文档元素一起工作的对象,它将这些元素封装起来供编程人员使用。
 
38、[单选题] js 中字符串连接用那个比较高效? 
A.a+=b 
B.a = a+b 
C.Array.join() 
D.Array.push()
答案:C
JavaScript中字符串连接时用 Array.join() 替换 string += "xx" ,换来几十倍的速度提升
 
39、[单选题]  在 文 件 /home/somebody/workspace/somemodule.js 中 第 一 行 引 用 了 一 个 模 块 : require(‘othermodule‘),请问 required 的查找模块的顺序 
A. /home/somebody/workspace/mode_modules/othermodule/index.js  
B. /home/somebody/workspace/mode_modules/othermodule. Js  
C.CORE MODULES named othermodule  
D./home/somebody/mode_modules/othermodule/index.js 
 
A.C D A B 
B.C B D A 
C.C B A D 
D.C D B A 
答案:C
(1)首先,Node在当前目录下查找 package.json(CommonJS包规范定义的包描述文件),通过 JSON.parse() 解析出包描述对象,从中取出 main 属性指定的文件名进行定位。如果文件确实扩展名,将会进入扩展名分析的步骤。
(2)如果 main 属性制定的文件名错误,或者压根没有 package.json 文件,Node会将 index当做默认文件名,然后依次查找 index.js   index.node   index.json
(3)如果在目录分析的过程中没有定位成功任何文件,则自定义模块进入下一个路径进行查找。如果模块路径数组都被遍历完毕,依然没有查找到目标文件,则会抛出查找失败异常。
 
  按照上面的思路,首先应该查找 package.json 文件,看看里面有没有核心模块,应该是 C 最先,
othermodule不是核心模块,那么接着应该进入扩展名分析的步骤,就应该是查找 othermodule.js,对应B
紧接着就是以 index 为默认文件名,也就是A,
再接下来就是上一个文件目录 D 了
 
40、[单选题]如下代码输出的结果是什么: 
console.log(1 + "2" + "2");
console.log(1 + +"2" + "2");
console.log("A" - "B" + "2");
console.log("A" - "B" + 2); 
A.122 122 NaN NaN 
B.122 32 NaN NaN2 
C.122 32 NaN2 NaN 
D.122 32 NaN2 NaN2 
答案:C
(1)console.log(1+"2"+"2")
做加法时要注意双引号,当使用双引号时,JavaScript认为是字符串,字符串相加等于字符串合并
(2)console.log(1 + + "2" + "2")
第一个 + "2" 中的加号是一元加操作符,+"2" 会变成数值 2,因此 1 + + "2" 相当于 1+2=3
(3)console.log("A" - "B" + "2")
"A"-"B"的运算中,需要先把 "A" 和 "B" 用 Number函数转换成数值,其结果是 NaN,在减法操作中,如果有一个是 NaN,则结果是NaN,因此 "A"-"B"结果为 NaN
然后和 “2” 进行字符串拼接,变成了 NaN2
(4)console.log("A"-"B" + 2)
根据上述,"A"-"B"的结果为 NaN,然后和数值2进行加法操作,在加法操作中,如果有一个操作数是 NaN,则结果为 NaN
 
41、[不定项选择题] 下列关于比较 Ajax 与 Flash 的优缺点,相关描述正确的是? 
A.Ajax 的优势在意在于可搜索性,开放性,易用性及易于开发 
B.Flash 的优势在于多媒体处理,可以更容易的调用浏览器以外的外部资源 
C.Ajax 最主要的批评就是它可能破坏浏览器的后退功能 
D.flash 文件经常会很大,用户第一次使用的时候需要忍耐较长的等待时间 
答案:ABCD
(1)Ajax的优势:1.可搜索性 2.开放性 3.费用 4.易用性 5.易于开发
(2)Flash的优势:1.多媒体处理 2.兼容性 3.矢量图形 4.客户端资源调度
(3)Ajax的劣势:1.它可能破坏浏览器的后退功能  2.使用动态页面更新使得用户难于将某个特定的状态保存到收藏夹中   ---不过这些都有相关方法解决
(4)Flash的劣势:1.二进制格式  2.格式私有  3.flash文件经常会很大,用户第一次使用的时候需要忍耐较长的等待时间   4.性能问题
 
42、[不定项选择题]  下面哪些语句可以在 JS 里判断一个对象 oStringObject 是否为 String。 
A.oStringObject instanceof String 
B.typeof oStringObject == 'string'
C.oStringObject is String
D.以上答案都不正确 
答案:A
通常来说判断一个对象的类型使用 typeof,但是在 new String 的情况下,结果会是 object 此时需要通过 instanceof 来判断
 
43、[问答题]  Flappy Bird 是风靡一时的手机游戏,玩家要操作一只小鸟穿过无穷无尽的由钢管组成的 障碍。如果要你在 HTML 前端开发这个游戏,为了保证游戏的流畅运行,并长时间运行也不 会崩溃,请列举开发要注意的性能问题和解决的方法。 
(1)长时间运行会崩溃的原因就是 ‘内存泄漏’。我们在日常的JS程序中并不太在意内存泄漏问题,因为JS解释器会有垃圾回收机制,大部分无效内存会被回收,另一方面JS运行在客户端,即使出现内存泄漏也不是太大的问题,简单的刷新页面即可。但是如果要预防内存泄漏的场景还是要注意一些问题。
(2)针对这个场景来说,即使长期运行出现内存泄漏的可能还是很低。第一方面,数据量很少,水管维护一个数组即可,然后每隔一段时间更新数组,来达到水管长度不同的效果。小鸟只要维护一个对象即可。通过移动水管检查碰撞就可以实现游戏逻辑。因为在浏览器端,JS程序和页面UI渲染公用一条线程,如果计算时间过长会使渲染阻塞,在HTML5中利用 webworker 已经可以开辟一个新线程专门负责计算解决这个问题了。
 
44、[问答题]  以下代码输出的值为?( )
function f1() {
  var n = 100;
  nAdd = function () {
    n += 1
  }
  function f2() {
    alert(n);
  }
  return f2;
}
var result = f1();
result();
nAdd();
result(); 

输出:100   undefined   100

45、什么样的请求是简单请求?

 请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

 HTTP的请求头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain

46、能说说首屏加载优化有哪些方案吗?

  • Vue-Router路由懒加载(利用Webpack的代码切割)
  • 使用CDN加速,将通用的库从vendor进行抽离
  • Nginx的gzip压缩
  • Vue异步组件
  • 服务端渲染SSR
  • 如果使用了一些UI库,采用按需加载
  • Webpack开启gzip压缩
  • 如果首屏为登录页,可以做成多入口
  • Service Worker缓存文件处理
  • 使用link标签的rel属性设置 prefetch(这段资源将会在未来某个导航或者功能要用到,但是本资源的下载顺序权重比较低,prefetch通常用于加速下一次导航)、preload(preload将会把资源的下载顺序权重提高,使得关键数据提前下载好,优化页面打开速度)

47、谈谈你对作用域链的理解

了解作用域链之前我们要知道以下几个概念:

  • 函数的生命周期
  • 变量和函数的声明
  • Activetion Object(AO)、Variable Object(VO)

函数的生命周期:

  • 创建:JS解析引擎进行预解析,将函数声明提前,同时将该函数放到全局作用域或当前函数的上一级函数的局部作用域中。
  • 执行:JS引擎会将当前函数的局部变量和内部函数进行声明提前,然后再执行业务代码,当函数执行完退出时,释放该函数的执行上下文,并注销该函数的局部变量。

变量和函数的声明:如果变量名和函数名声明时相同,函数优先声明

Activetion Object(AO)、Variable Object(VO):

  • AO:Activetion Object(活动对象)
  • VO:Variable Object(变量对象)

VO对应的是函数创建阶段,JS解析引擎进行预解析时,所有的变量和函数的声明,统称为 Variable Object。该变量与执行上下文相关,知道自己的数据存储在哪里,并且知道如何访问。VO是一个与执行上下文相关的特殊对象,它存储着在上下文中声明的以下内容:

  • 变量(var,变量声明)
  • 函数声明(FunctionDeclaration)
  • 函数的形参

AO对应的是函数执行阶段,当函数被调用执行时,会建立一个执行上下文,该执行上下文包含了函数所需的所有变量,该变量共同组成了一个新的对象就是Activetion Object。该对象包含了:

  • 函数的所有局部变量
  • 函数的所有命名参数
  • 函数的参数集合
  • 函数的this指向

作用域链

        当代码在一个环境中创建时,会创建变量对象的一个作用域链来保证对执行环境有权访问的变量和函数。作用域第一个对象始终是当前执行代码所在环境的变量对象(VO)。如果是函数执行阶段,那么将其AO作为作用域链第一个对象,第二个对象是上级函数的执行上下文AO,下一个对象依次类推。

        当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。

 48、在ES5中如何实现继承

 寄生组合式继承:

  所谓寄生组合式继承,及通过借用构造函数来继承属性,通过原型链的混和形式来继承方法。其背后的基本思想是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本而已。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。

49、绝对定位

如果不设置子元素 left top的话,absolute的子元素是顶在父元素的 content左上方的

如果设置子元素 left = 0  top = 0 的话,子元素是顶在父元素的 padding 左上方的(在border内) 

  • 一旦给元素加上了 absolute 或 float 就相当于给元素加上了 display: block
  • absolute 元素覆盖正常文档流内元素(不用设 z-index,自然覆盖)
  • 可以减少重绘和回流的开销(如 absolute + top:-9999em,或 absolute + visibility:hidden,将动画效果放到 absolute 元素中)

属性介绍:

  • static:默认值,位置设置为 static 的元素,它始终会处于文档流给予的位置。
  • inherit:规定应该从父元素继承 position 属性的值。但是任何版本的 IE 都不支持属性值 “inherit”
  • fixed:生成绝对定位的元素。默认情况下,可定位于相对于浏览器窗口的指定坐标。但当祖先元素具有 transform 属性且不为 none 时,就会相对于祖先元素指定坐标,而不是浏览器窗口。
  • absolute:生成绝对定位的元素,相对于该元素最近的已定位的祖先元素进行定位。
  • relative:生成相对定位的元素,相对于该元素在文档中的初始位置进行定位。

浮动、绝对定位和固定定位会脱离文档流,相对定位不会脱离文档流,绝对定位相对于该元素最近的已定位的祖先元素,如果没有一个祖先元素设置定位,那么参照物是body

  • 如果祖先元素是块级元素,包含块则设置为该元素的内边距边界
  • 如果祖先元素是行内元素,包含块则设置为该祖先元素的内容边界

问答题:

  • 定位的元素的起始位置为父包含块的内边距(不会在border里,除非使用负值,会在padding里)
  • 定位的元素的margin还是能起作用的
  • background属性是会显示在border里的
  • z-index是由层叠层级的,需要考虑同一个层叠上下文的层叠优先级
  • z-index是负值不会覆盖包含块的背景色(但是如果有内容,会被包含块的内容覆盖)
  • z-index的值影响的元素是定位元素以及flex盒子
  • 上面一个定位元素,下面一个正常流的元素,定位元素会覆盖在正常流元素之上,除非给z-index是负值
  • 页面根元素html天生具有层叠上下文,称之为“根层叠闪现给我”

50、讲讲MVVM,说说与MVC有什么区别?

  MVC允许在不改变视图的情况下改变视图对用户输入的响应方式,用户对View的操作交给了Controller处理,在Controller中响应View的事件调用Model的接口对数据进行操作,一旦Model发生变化便通知相关视图进行更新。

  如果前端没有框架,只使用原生的 html+js,MVC模式可以这样理解。将html看作view;js看作controller,负责处理用户与应用的交互,响应对view的操作(对事件的监听),调用Model对数据进行操作,完成model与view的同步(根据model的改变,通过选择器对view进行操作);将js的ajax当做Model,也就是数据层,通过ajax从服务器获取数据。

  Model看成模型,View看成这个模型的视图化体现,而Controller根据需要写在各自的方法里。

  MVVM与MVC最大的区别就是:它实现了View和Model的自动同步,也就是当Model的属性改变时,我们不用再自己手动操作DOM元素,来改变View的显示,而是改变属性后该属性对应View层会自动改变。

  从整体来看,MVVM比MVC精简很多,不仅简化了业务与界面的依赖,还解决了数据频繁更新的问题,不用再使用选择器操作DOM元素。因为在MVVM中,View不知道Model的存在,Model和ViewModel也观察不到View,这种低耦合模式提高代码的可重用性。

51、说说事件委托有什么好处?

 事件委托就是利用事件冒泡机制指定一个事件处理程序,来管理某一类型的所有事件。

即:利用冒泡的原理,把事件加到父级上,触发执行效果。

好处:

  • 只在内存中开辟了一块空间,节省资源同时减少了DOM操作,提供性能
  • 对于新添加的元素也会有之前的事件

52、target和currentTarget的区别

  •  target在事件流的目标阶段
  •  currentTarget在事件流的捕获、目标及冒泡阶段

 只有当事件流处于目标阶段的时候,两个的指向才是一样的,而处于捕获和冒泡阶段的时候,target指向被单击的对象,而currentTarget指向当前事件活动的对象(注册该事件的对象,一般为父级)。

53、Service Worker的作用

  •  网络代理,转发请求,伪造响应
  • 离线缓存
  • 消息推送
  • 后台消息传递

54、如何判断两个变量相等

 Object.is()方法判断两个值是否是相同的值

NaN === NaN   // false

+0 === -0   // true

Object.is(NaN, NaN)  // true

Object.is(+0, -0)  // false

 在ES5中实现 Object.is() 的 polyfill

if (!Object.is) {
  Object.is = function(x, y) {
    if (x === y) { // Steps 1-5, 7-10
      // 针对 +0不等于-0
      return x !== 0 || 1 / x === 1 / y;
    } else {
      // 针对 NaN等于NaN
      return x !== x && y !== y;
    }
  };
}
原文地址:https://www.cnblogs.com/haishen/p/11697430.html