js基础面试题61-70道题目

JavaScript021

js基础面试题61-70道题目,第1张

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 为冒泡阶段。

参与互动

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方法的观察者模式来实现。

场景:var str = “hello world!”

a.str.char() //返回指定下标的值

Str.char(2) //”l”

b.Str.indexOf() //返回指定值的下标

Str.indexOf(‘e’) //’1’

c.Str.lastIndexOf() //返回最后指定值的下标

Str.lastIndexOf(‘l’) //’9’

d.Str.concat() //拼接字符串

Str.concat(“mother fuck!”) //”hello world!mother fuck!”

Console.log(str) //”hello world!”

e.Str.substr(n,m) //从n开始截取m个字符

Str.substr(1,2) //’el’

f.Str.substring(n,m) //从n开始m结束截取字符串,不包含m

Str.substring(6,11) //”world”

g.Str.slice(n,m) //同substring,slice可以截取数组,substring不能截取数组

Str.slice(6,11) //”world”

h.Str.split //返回数组

Str.split(‘ ’) //[‘hello’, ‘world!’]

Str.aplit(‘l’) //[‘he’, ‘’, ‘o wor’, ‘d!’]

i.Str.replace() //以下三个方法都是通过正则表达式对原字符串进行更改的

j.Str.match()

k.Str.search()

场景:const obj = {x: 0, y: 1}

Const obj2 = {x: 1, z: 2,fn: {number: 1}}

a.Object.assign() //合并对象,实行的是浅拷贝

Object.assign(obj, obj2)

Console.log(obj) //{x: 1, y: 1, z: 2,fn: {number: 1}}

b.Object.create() //新建一个对象,可以使用原型链继承

Var newObj = Object.create(obj, {newValue: ‘newAdd’})

Console.log(newObj) //{newValue: ‘newAdd’}

Console.log(newObj.x) //0

c.Object.defineProperties() //往对象里面添加或修改新属性,值类型

Object.defineProperties(obj, {name: {value: ‘欧’}}) //添加属性

Console.log(obj) //{x: 0, y: 1, name: ‘欧’}

Object.defineProperties(obj, {name: {value: ‘林’, writable: true}}) //修改属性

Console.log(obj) //{x: 0, y: 1, name: ‘林’}

d.Object.defineProperty() //往对象里面添加新属性,可以是引用类型

Object.defineProperty(obj, ‘name’, {value: function() {return ‘欧’}})

Console.log(obj.name()) //’欧’

e.Object.keys() //返回对象所有key,以数组类型输出

Console.log(Object.keys(obj)) //[‘x’, ‘y’]

f.Object.values() //返回对象所有的value,以数组类型输出

Console.log(Object.values(obj)) //[0, 1]

场景:var arr = new array(1,2,3)

a.push() //向数组尾部添加元素

arr.push(4)

console.log(arr) //[1,2,3,4]

b.unshift() //向数组头部添加元素

arr.unshift(0)

console.log(arr) //[0,1,2,3]

c.pop() //删除数组尾部的元素

arr.pop()

console.log(arr) //[1,2]

d.shift() //删除数组头部的元素

arr.shift()

console.log(arr) //[2,3]

e.indexOf() //返回指定元素的下标

arr.indexOf(2) //1

f.slice(n,m) //从n开始m结束截取数组,不包括m,此方法不会更改元数组

console.log(arr.slice(1,2)) // [2]

console.log(arr) //[1,2,3]

g.splice() //删除数组指定元素

arr.splice(1) //删除从下标1开始到最后的所有元素

console.log(arr) //[1]

arr.splice(1,2) //删除从下标1开始往后的2个元素

console.log(arr) //[1]

arr.splice(1,2,3,4) //删除从下标1开始往后2个元素并用3,4替代

console.log(arr) //[1,3,4]

h.reverse() //数组翻转

arr.reverse()

console.log(arr) //[3,2,1]

i.sort() //从小到大排序数组

arr.sort()

console.log(arr) //[1,2,3]

j.forEach() //以下提供了几种遍历的方法

k.map()

l.filter() //数组过滤,如果数组的元素的对象,可以通过对象的属性名来过滤元素,用法跟C#的Linq一样。

var newArr = [{id:1,name:’元素1’},{id:2,name:’元素2’}]

console.log(newArr.filter(item =>item.id===1)) //[{id:1,name:’元素1’}]

console.log(newArr) //[{id:1,name:’元素1’},{id:2,name:’元素2’}]

m.every()

n.some()

o.find()

p.findIndex()

增删改查

场景:<div class=”div” id=”div”></div>

a.document.createElement() //创建节点

var newDiv = document.createElement()

b.document.craeteTextNode() //创建文本节点

var newDivText = document.craeteTextNode(‘这是新创建的节点’)

c.div.appendChild() //向节点添加最后一个子节点

newDiv.appendChild(newDivText)

d.document.getElementById() //通过Id获取节点

var div = document.getElementById(‘div’)

e.div.parentNode //获取父节点

f.div.childNode //获取子节点,返回一个集合

var child = div.childNodes

g.div.nextSibling,div.previousSibling,div.firstChild,div.lastChild

分别为,获取下一个兄弟节点,上一个兄弟节点,第一个子节点,最后一个子节点。

h.div.insetBefore() //插入到特定位置

div.insetBefore(newDiv, null) //插入到最后,跟appendchild用法一样

div.insetBefore(newDiv, div.firstChild) //插入到第一个子节点之前

div.insetBefore(newDiv, div.lastChild) //插入到最后节点之前

i.div.replaceChild() //替换节点

div.replaceChild(newDiv, div.firstChild) //替换第一个子节点,原节点会被删除

j.div.removeChild() //删除子节点

k.cloneNode(true/false) //克隆节点,true为深克隆,false为浅克隆

l.document.querySelector(),document.querySelectorAll() //通过css选择器搜索匹配的节点,querySelector返回匹配的第一个节点,querySelectorAll返回所有节点

document.querySelector(‘div.div’) //返回class为div的div标签节点

document.querySelector(‘#div’) //返回id为div的节点

m.document.getElementsByTagName(),document.getElementsByName(),document.getElementsByClassName() //返回符合需求的集合

n.div.setAttribute() //给元素添加属性

div.setAttribute(‘name’: ‘div’)

o.removeAttribute(),getAttribute(),hasAttribute() //各种操作属性的方法