js面试题

JavaScript023

js面试题,第1张

1.eventLoop

2.setTimeout 误差原因

3.深浅拷贝

4.跨域原因及解决方案

5.css放在头部,js放在尾部

6.css触发bfc

7.webpack plugin和loader区别

8.前端优化

9.协商缓存

10.长列表优化

11.webview交互

12.vue响应式原理

13.原型

14.算法题:数组中有n个元素,排列

EventLoop是计算机系统的运行机制,js就是运行这个机制,因为js是单线程语言,所以一旦遇到一个耗时很长的任务就会卡住,js为了解决这个问题就有了EventLoop

Event Loop是一个程序结构,用于等待和发送消息和事件。

就是在程序中有了两个线程,一个负责应用本身,主线程,另一个负责主线程和其它进程,称为EventLoop

1、js是单线程语言

基本数据类型存放在栈中的简单数据段

引用数据类型存放在堆中的对象

因为定时器是宏任务,如果执行栈的时间大于定时器花费的时间,那么定时器的回调在 宏任务(macrotask) 里,来不及去调用,所有这个时间会有误差。所以就会有误差

宏任务是宿主发起的比如script,setTimeout

css放在头部是因为页面加载html生成dom树的时候就可以同时对dom树进行渲染,防止闪跳,白屏

js放在尾部是因为js会修改dom树,需要一个稳定的dom树

BFC是css的一个布局概念,块级格式化上下文

浮动float不为none的时候

定位为position:absolute和fixed的

display的时候

overflow不为visible

解决浮动父元素坍塌问题

解决自适应布局的问题

解决外边距垂直方向重合问题

loader是文件加载器,运行在nodejs中,并对文件进行打包,压缩转换

plugin是插件,用于拓展webpack的功能

浅拷贝有两种定于,第一种是赋值,第二种是拷贝对象的第一层属性,深层还是一样的

深拷贝是指将对象拷贝一份,无论如何修改都不会改变原有的

响应式原理就是当数据发生改变的时候视图也会跟着更新

VUE是利用了Object.defineProperty的方法里面的setter 与getter方法的观察者模式来实现。

71.IE 和标准下有哪些兼容性的写法

参考答案:

参与互动

72.变量提升

参考答案:

A、js 代码执行的过程

B、变量提升发生的环境:发生在代码所处的当前作用域。

解析:

对应面试题

参与互动

73.如何阻止冒泡与默认行为

参考答案:

解析:

当需要阻止冒泡行为时,可以使用

当需要阻止默认行为时,可以使用

参与互动

74.js 中 this 闭包 作用域

参考答案:

this:指向调用上下文

闭包:定义一个函数就开辟了一个局部作用域,整个 js 执行环境有一个全局作用域

作用域:一个函数可以访问其他函数中的变量(闭包是一个受保护的变量空间)

参与互动

75.javascript 的本地对象,内置对象和宿主对象

参考答案:

1.本地对象

ECMA-262 把本地对象(native object)定义为“独立于宿主环境的 ECMAScript 实现提供的对象"。简单来说,本地对象就是 ECMA-262 定义的类(引用类型)。它们包括:Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError

2.内置对象

JS中内置了17个对象,常用的是Array对象、Date对象、正则表达式对象、string对象、Global对象

3.宿主对象

由ECMAScript实现的宿主环境提供的对象,可以理解为:浏览器提供的对象。所有的BOM和DOM都是宿主对象。

参与互动

76.javascript 的同源策略

参考答案:一段脚本只能读取来自于同一来源的窗口和文档的属性

解析:

同源策略:限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。(来自 MDN 官方的解释)

简单来说就是:一段脚本只能读取来自于同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合 具体解释:

(1)源包括三个部分:协议、域名、端口(http 协议的默认端口是 80)。如果有任何一个部分不同,则源不同,那就是跨域了。

(2)限制:这个源的文档没有权利去操作另一个源的文档。这个限制体现在:(要记住)

Cookie、LocalStorage 和 IndexDB 无法获取。

无法获取和操作 DOM。

不能发送 Ajax 请求。我们要注意,Ajax 只适合同源的通信。

同源策略带来的麻烦:ajax 在不同域名下的请求无法实现,需要进行跨域操作

参与互动

77.事件冒泡与事件捕获

参考答案:

事件冒泡:由最具体的元素(目标元素)向外传播到最不具体的元素

事件捕获:由最不确定的元素到目标元素

参与互动

78.foo = foo||bar ,这行代码是什么意思?为什么要这样写?

参考答案:

这种写法称为短路表达式

解析:

相当于

常用于函数参数的空判断

参与互动

79.复杂数据类型如何转变为字符串

参考答案:

参与互动

80.javascript 中 this 的指向问题

参考答案:

解析:

全局环境下,this 始终指向全局对象(window),无论是否严格模式;

2.1 普通函数

普通函数内部的 this 分两种情况,严格模式和非严格模式。

(1)非严格模式下,没有被上一级的对象所调用, this 默认指向全局对象 window。

(2)严格模式下,this 指向 undefined。

2.2 函数作为对象的方法

(1)函数有被上一级的对象所调用,那么 this 指向的就是上一级的对象。

(2)多层嵌套的对象,内部方法的 this 指向离被调用函数最近的对象(window 也是对象,其内部对象调用方法的 this 指向内部对象, 而非 window)。

特殊例子

2.3 原型链中的 this

(1)如果该方法存在于一个对象的原型链上,那么 this 指向的是调用这个方法的对象,就像该方法在对象上一样。

上述例子中,对象 p 没有属于它自己的 f 属性,它的 f 属性继承自它的原型。当执行 p.f()时,会查找 p 的原型链,找到 f 函数并执行。因为 f 是作为 p 的方法调用的,所以函数中的 this 指向 p。

(2)相同的概念也适用于当函数在一个 getter 或者 setter 中被调用。用作 getter 或 setter 的函数都会把 this 绑定到设置或获取属性的对象。

(3)call()和 apply()方法:当函数通过 Function 对象的原型中继承的方法 call() 和 apply() 方法调用时, 其函数内部的 this 值可绑定到 call() &apply() 方法指定的第一个对象上, 如果第一个参数不是对象,JavaScript 内部会尝试将其转换成对象然后指向它。

(4)bind()方法:由 ES5 引入, 在 Function 的原型链上, Function.prototype.bind。通过 bind 方法绑定后, 函数将被永远绑定在其第一个参数对象上, 而无论其在什么情况下被调用。

2.4 构造函数中的 this

当一个函数用作构造函数时(使用 new 关键字),它的 this 被绑定到正在构造的新对象。

构造器返回的默认值是 this 所指的那个对象,也可以手动返回其他的对象。

特殊例子

当 this 碰到 return 时

2.5 setTimeout &setInterval

(1)对于延时函数内部的回调函数的 this 指向全局对象 window;

(2)可以通过 bind()方法改变内部函数 this 指向。

3.1 作为一个 DOM 事件处理函数

当函数被用作事件处理函数时,它的 this 指向触发事件的元素(针对 addEventListener 事件)。

3.2 作为一个内联事件处理函数

(1)当代码被内联处理函数调用时,它的 this 指向监听器所在的 DOM 元素;

(2)当代码被包括在函数内部执行时,其 this 指向等同于 普通函数直接调用的情况,即在非严格模式指向全局对象 window,在严格模式指向 undefined:

4.1 全局环境中

在全局代码中,箭头函数被设置为全局对象:

4.2 this 捕获上下文

箭头函数没有自己的 this,而是使用箭头函数所在的作用域的 this,即指向箭头函数定义时(而不是运行时)所在的作用域。

4.2 this 捕获上下文

箭头函数没有自己的 this,而是使用箭头函数所在的作用域的 this,即指向箭头函数定义时(而不是运行时)所在的作用域。

在 setTimeout 中的 this 指向了构造函数新生成的对象,而普通函数指向了全局 window 对象。

4.3 箭头函数作为对象的方法使用

箭头函数作为对象的方法使用,指向全局 window 对象;而普通函数作为对象的方法使用,则指向调用的对象。

4.4 箭头函数中,call()、apply()、bind()方法无效

4.5 this 指向固定化

箭头函数可以让 this 指向固定化,这种特性很有利于封装回调函数

上面代码的 init 方法中,使用了箭头函数,这导致这个箭头函数里面的 this,总是指向 handler 对象。如果不使用箭头函数则指向全局 document 对象。

4.6 箭头函是不适用场景

(1)箭头函数不适合定义对象的方法(方法内有 this),因为此时指向 window;

(2)需要动态 this 的时候,也不应使用箭头函数。

参与互动

61.作用域的分类

参考答案:块作用域、词法作用域、动态作用域

解析:

1 块作用域 花括号 {}

2 词法作用域(js 属于词法作用域) 作用域只跟在何处被创建有关系,跟在何处被调用没有关系

3 动态作用域 作用域只跟在何处被调用有关系,跟在何处被创建没有关系

参与互动

62.js 属于哪种作用域

参考答案:词法作用域(函数作用域)

解析:

参与互动

63.浮点数精度

参考答案:参考

参与互动

64.自执行函数? 用于什么场景?好处?

参考答案:

好处:防止变量弥散到全局,以免各种 js 库冲突。隔离作用域避免污染,或者截断作用域链,避免闭包造成引用变量无法释放。利用立即执行特性,返回需要的业务函数或对象,避免每次通过条件判断来处理

场景:一般用于框架、插件等场景

参与互动

65.多个页面之间如何进行通信

参考答案:有如下几个方式:

参与互动

66.css 动画和 js 动画的差异

参考答案:

1.代码复杂度,js 动画代码相对复杂一些 2.动画运行时,对动画的控制程度上,js 能够让动画,暂停,取消,终止,css 动画不能添加事件 3.动画性能看,js 动画多了一个 js 解析的过程,性能不如 css 动画好

解析:参考

参与互动

67.如何做到修改 url 参数页面不刷新

参考答案:

HTML5 引入了 history.pushState() 和 history.replaceState() 方法,它们分别可以添加和修改 历史 记录条目。

假设当前页面为 foo.html ,执行上述代码后会变为 bar.html ,点击浏览器后退,会变为 foo.html ,但浏览器并不会刷新。 pushState() 需要三个参数: 一个状态对象, 一个标题 (目前被忽略), 和 (可选的) 一个 URL.让我们来解释下这三个参数详细内容:

参与互动

68.数组方法 pop() push() unshift() shift()

参考答案:

参与互动

69.事件绑定与普通事件有什么区别

参考答案:

参与互动

70.IE 和 DOM 事件流的区别

参考答案:

1.事件流的区别

IE 采用冒泡型事件 Netscape 使用捕获型事件 DOM 使用先捕获后冒泡型事件 示例:

复制代码代码如下:

冒泡型事件模型: button->p->body (IE 事件流)

捕获型事件模型: body->p->button (Netscape 事件流)

DOM 事件模型: body->p->button->button->p->body (先捕获后冒泡)

2.事件侦听函数的区别

IE 使用:

DOM 使用:

bCapture 参数用于设置事件绑定的阶段,true 为捕获阶段,false 为冒泡阶段。

参与互动