1.JavaScript数据类型?
基本数据类型:
string、number、null、underfined、boolean、symbol、bigInt
引用数据类型:
object、array、date、function、RegExp
object是所有对象的父对象。
2.浅谈JavaScript中变量和函数声明的提升?
在js中变量和函数声明的提升会被提升到最顶部执行;
函数的提升高于变量的提升;
如果在函数内部用var声明了与外部相同的变量,则不向下寻找;
匿名函数不会被提升;
不同块中互不影响。
3.什么是闭包?闭包有什么特性,闭包的使用场景?
闭包就是能够读取其他函数内部变量的函数。闭包基本上就是一个函数内部返回一个函数。
闭包有三个特性:
函数嵌套函数
函数内部可以引用外部的参数和变量
参数和变量不会被垃圾回收机制回收
使用场景:
应用场景,设置私有变量和方法
不适用场景:返回闭包的函数是个非常大的函数
4.说说对闭包的理解和闭包的作用?
- 使用闭包就是为了设置私有变量和方法。
- 闭包的好处:能够实现封装和缓存;
- 闭包的坏处:就是内存消耗,使用不当可能会造成内存溢出的问题。
- 好处:
函数内部可以嵌套函数;
内部函数可以直接访问外部函数的参数和变量;
可以将变量始终保持在内存中;
可以封装对象的私有属性和私有方法。
- 坏处:
比较耗费内存、使用不当会造成内存溢出的问题;
参数和变量不会被垃圾回收机制回收。
5.说说this对象的理解?
- this总是指向函数的直接调用者;
- 如果有new关键字,则只想new出来的那个对象;
- 在事件中,this指向出发这个事件的对象,特殊的是,再IE中的attachEvent中的this总是指向全局对象window。
6.事件模型的理解?
冒泡型事件:当使用冒泡型事件时,自己元素先触发,父级元素后触发。
捕获型事件:当使用捕获型事件时,父级元素先触发,子级元素后触发。
7.new操作符具体做了干了什么?
创建一个空对象,并且this变量引用该对象,同时还继承了该函数的原型;
属性和方法被加入到了this引用的对象中;
新创建的对象由this所引用,并且最后隐式地返回this。
8.说说栈和堆的区别?
- 栈内存:存储的都是局部变量,后进先出,栈内存的更新速度很快,因为局部变量的生命周期都很短。
- 堆内存:存储的都是数组和对象,堆里面的实体不会被释放,但是会被当成垃圾,java有垃圾回收机制不定时的收取。
9.JS数组和对象的遍历方式,以下几种方式的比较。
- for循环——循环每进行一次,就要检查一下数组的长度,速度比较慢。
- for in 循环——需要分析出array的每一个属性,这个操作性能开销很大。
- forEach循环——不能遍历对象,不可以使用continue、break跳出循环,且使用return是跳出本次循环。
- for-of循环——用来遍历数据,例如数组中的值,不仅支持数组,还支持大多数数组对象,例如DOM NodeList对象。也支持字符串遍历,支持Set和Map的遍历。
10.map和forEach的区别?
forEach是最基本的遍历与循环,默认有三个参数:遍历的数组内容item、数组索引index、当前遍历数组array。
map的用法和forEach基本一致,不同的是它会返回一个数组,所以callback需要有return值,如果没有、会返回undefined。
11.说说箭头函数与普通函数的区别?
- 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象;
- 不可以当作构造函数,也就是说不能使用new关键字,否则会抛出一个错误;
- 不可以使用arguments对象,该对象在函数体内不存在。如果要使用,可以用Rest参数代替;
- 不可以使用yield命令,因此箭头函数不能当作Generator函数。
- 箭头函数的特点:不需要function关键字来创建函数,省略return关键字,改变this指向
12.JavaScript定义类的四种方法?
工厂方法、构造函数方法、原型方法、组合使用构造函数和原型方法。
13.JavaScript实现继承的三种方法?
借用构造函数法,对象冒充、组合继承。
14.对原生JavaScript的了解程度?
数据类信、运算、对象、Function、继承、闭包、作用域、原型链、事件、RegExp、JSON、Ajax、ECMAScript、DOM、BOM、内存泄漏、跨域、异步装载、模板引擎、前端MVC、路由、模块化、Canvas。
15.JS动画和CSS动画区别及相应实现?
CSS3的动画优点:
在性能上稍微好一点、浏览器会对CSS3的动画进行一些优化;
代码相对简单。
缺点:兼容性差、在动画上控制不够灵活。
JavaScript的动画正好弥补了这两个缺点。在实现一些小的效果的时候,尽量使用css3。
16.谈一谈你对“函数式编程”的理解?
简单来说,函数式编程是一种编程规范,也就是如何编写程序的方法论。
17.说说你对作用域链的理解?
作用域链可以理解为一组对象列表,包含父级和自身的变量对象,因此我们便能通过作用域链访问到父级里声明的变量或者函数。
作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的。
18.JavaScript原型、原型链是什么?有什么特点?
每个对象都在其内部初始化一个属性,就是prototype(属性),当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去prototype里面去找这个属性,这个prototype又有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链。
关系:instance.constructor.prototype = instance.proto。
所有的函数都有prototype属性(原型)
所有的对象都有_proto_属性
在 js 中,每个函数都有一个原型属性prototype指向自身的原型,而由这个函数创建的对象也有一个proto属性指向这个原型,而函数的原型是一个对象,所以这个对象也会有一个proto指向自己的原型,这样逐层深入到object对象的原型,这样就形成了原型链。
19.说说什么是事件代理?
事件代理又称之为事件委托。就是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。
20.说说ajax的原理,过程?
Ajax的原理简单来说就是在用户和服务器之间加了一个中间层(Ajax引擎),由XmlHttpRequest对象来向服务器发送异步请求,从服务器获取数据,然后用JavaScript来操作DOM而更新页面。
过程:
(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象.
(2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
(3)设置响应HTTP请求状态变化的函数.
(4)发送HTTP请求.
(5)获取异步调用返回的数据.
(6)使用JavaScript和DOM实现局部刷新.
21.说说如何解决跨域问题?
- 通过JSONP跨域;
- 通过document.domain.iframe跨域;
- nginx跨域;
- node.js中间件代理跨域;
- 后端在头部信息里面设置安全域名解决跨域。
22.异步加载JS的方式有哪些?
defer,只支持IE;async;创建,插入到DOM中,加载完毕后callBack。
23.有哪些操作会导致内存泄漏?
- 定义:程序中已动态分配的堆内存由于某种原因程序未释放或无法释放引发的各种问题。
- js 中可能出现内存泄漏情况的结果:变慢、崩溃、延迟大等。
- js中可能出现的内存泄漏的原因:
全局变量使用不当;
dom清空时,还存在引用;
延时器或定时器未清除;
setTimeout的第一个参数是字符串而非函数的话,会造成内存泄漏;
子元素存在引起的内存泄露;
闭包使用不当。
24.介绍JS有哪些内置对象?
- 数据封装类对象:Object、Array、Number、Boolean、String。
- 其他对象:Function、Argument、Math、Date、RegExp、Error。
25.说几条写JavaScript的基本规范?
- 不要在同一行声明多个变量;
- 使用===!==来判断true、false;
- 不要使用全局函数;
- Switch语句必须使用带有default分支;
- if语句必须使用大括号;
- for in 循环中的变量应该使用var关键字明确限定作用域,从而避免作用域污染。
26.eval是做什么的?
- eval可以把字符串解析成JS代码并运行;
- 避免使用eval,不安全,非常消耗性能;
- 把JSON字符串转换成JSON对象时可以使用eval。
27.null 和 undefined 的区别?
- null表示定义了一个对象,值为“空值”;
- undefined表示这个不存在这个值。
28.说说同步和异步的区别?
- 同步:在同一时间内不允许出现别的操作。
- 异步:在同一时间内允许不同的操作。
29.defer 和 async 的区别?
- script标签用于加载脚本与执行脚本,是前端开发中非常重要的标签。
- 直接使用script脚本的话,html会按照顺序来加载并执行脚本,在脚本加载及执行分过程中,会阻塞后续的DOM渲染。
- 现在script提供了async和defer两个属性来解决DOM渲染阻塞的问题。
- 没有defer或async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该script标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
- 有async,加载和渲染后续文档元素的过程将和script.js的加载与执行并行进行(异步)。异步脚本不能保证按照它们在页面中出现的次序执行。
- 有defer,加载后续文档元素的过程将和script.js的加载并行进行(异步),但是script.js的执行要在所有元素解析完成之后,DOMContentLoaded事件触发之前完成。
- 推迟的脚本原则上按照它们被列出的次序执行。
30. [1,2,3].map(parseInt)的输出结果是什么?
[1,NAN,NaN],因为parseInt需要两个参数(val,radix)。
31. use strict 的理解和作用?
use strict 是ES5新增的一种严格运行模式,可以使得JS代码在严格模式下运行,是的编码更加规范更加严谨,消除一些怪异行为。
32.说说严格模式的限制?
- 变量必须先声明后使用;
- 函数的参数不能出现同名属性,否则报错;
- 不能使用with语句;
- 禁止this指向全局对象。
33.== 和 === 的区别
== 是非严格意义上的相等,值相等就相等。
=== 是严格意义上的相等,会比较两边的数据类型和值的大小,值和引用地址都相等才相等。
34.同源策略
同源是指域名、协议、端口号相同。同源策略是一种安全协议。
35.es6新增
- 新增模板字符串;
- 箭头函数;
- for-of (用来遍历数据——例如数组中的值);
- es6 将Promise 对象纳入规范,提供了原生的 Promise 对象;
- 增加了 let 和 const 命令,用来声明变量;
- 还有就是引入了 module 模块的概念。
36. attribute 和 property 的区别是什么?
attribute 是 dom 元素在文档中作为 html 标签拥有的属性;
property 是 dom 元素在 js 中作为对象拥有的属性。
对于 html 的标准属性来说,attribute 和 property 是同步的,是会自动更新的,但是对于自定义的属性来说,他们是不同步的。
37. var、let 和 const 的区别是什么?
var 存在变量提升。
let 命令不存在变量提升,如果在let前使用,会导致报错,如果块区中存在 let 和 const 命令,就会形成封闭作用域,不允许重复声明。只能在块级作用域内访问。
const 定义的是常量,必须初始化,不能修改,但是如果定义的是对象,可以修改对象内部的数据。
38. script 引入方式?
html 静态 <script> 引入
js 动态插入 <script>
<script defer> : 异步加载,元素解析完成后执行
<script async> : 异步加载,但执行时会阻塞元素渲染
39. 数组 array 方法
map:遍历数组,返回一个新的数组
forEach:无法break,可以用 try/catch 中 throw new Error 来停止
filter:过滤
some: 有一项返回true,则整体为true
every:有一项返回false,则整体为false
join:通过指定连接符生成字符串
push/pop:末尾推入和弹出,改变原数组,返回推入和弹出项
unshift/shift:头部推入和弹出,改变原数组,返回操作项
sort(fn) / reserve:排序与反转,改变原数组
concat:连接数组,不影响原数组,浅拷贝
slice(start,end):返回截断后的新数组,不改变原数组
splice(start,number,value...):返回删除元素组成的数组,value为插入项,改变原数组
indexOf / lastIndexOf(value,fromIndex):查找数组项,返回对应的下标
reduce / reduceRight(fn(prev,cur), defaultPrev):两两执行,prev为上次化简函数的return值,cur为当前值(从第二项开始)
40. JavaScript 深浅拷贝
浅拷贝:Object.assign
深拷贝:可以通过JSON.parse(JSON.stringify(object))来解决
41. 说说异步编程的实现方式?
1.回调函数
优点:简单、容易理解
缺点:不利于维护,代码耦合高
2.事件监听
优点:容易理解,可以绑定多个事件,每个事件可以指定多个回调函数
缺点:事件驱动型,流程不够清晰
3.发布/订阅(观察者模式)
类似于事件监听,但是可以通过“消息中心”,了解现在有多少发布者,多少订阅者
4.Promise对象
优点:可以利用then方法,进行链式写法,可以书写错误时等我回调函数
缺点:编写和理解,相对比较难
5.Generator函数
优点:函数体内外的数据交换、错误处理机制
缺点:流程管理不方便
6.async函数
优点:内置执行器、更好的语义、更广的适用性,返回的是Promise、结构清晰
缺点:错误处理机制
42. 说说面向对象编程思想?
基本思想是使用对象、类、继承、封装等基本概念来进行程序设计
优点:易维护、易扩展、开发工作的重用性、继承性高,降低重复工作量,缩短了开发周期
43. 项目性能优化
减少http请求次数
减少DNS查询
使用CDN
避免重定向
图片懒加载
减少DOM元素数量和DOM操作
使用外部 js 和 css
压缩 js、css、字体、图片等
优化 CSS Sprite
使用 iconfont
多域名分发划分内容到不同域名
尽量减少 iframe 使用
避免图片 src 为空
把样式表放在 link 中
把 js 放在页面底部
44. 什么是单线程,和异步的关系
单线程:只有一个线程,只能做一件事情
原因:避免 DOM 渲染的冲突
浏览器需要渲染 DOM
JS可以修改DOM结果
JS执行的时候,浏览器DOM渲染会暂停
两段 JS 也不能同时执行(都修改DOM就冲突了)
webworker 支持多线程,但是不能访问 DOM
解决方案:异步
45. 说说负载均衡
单台服务器共同协作,不让其中某一台或几台超额工作,发挥服务气的最大作用
http 重定向负载均衡:调度者根据策略选择服务器以302响应请求,缺点只有第一次有效果,后续操作维持在该服务器
dns负载均衡:解析域名时,访问多个ip服务器中的一个(可监控性较弱)原因:避免DOM渲染的冲突
反向代理负载均衡:访问统一的服务器,由服务器进行调度访问实际的某个服务器,对统一的服务要求大,性能受到服务器群的数量
46. js 的垃圾回收机制
1. 概述
js的垃圾回收机制是为了防止内存泄漏(已经不需要的某一块内存还一直存在着),垃圾回收机制就是不停歇的寻找这些不在使用的变量,并且释放掉它所指向的内存。在js中,js的执行环境会负责管理代码执行过程中使用的内存。
2.变量生命周期
当一个变量的生命周期结束之后,它所指向的内存就会被释放。js有两种变量,局部变量和全局变量,局部变量是在他当前的函数中产生作用,当该函数结束之后,该变量内存会被释
放,全局变量的话会一直存在,知道浏览器关闭为止。
3.js的垃圾回收机制
有两种方式:标记清除、引用计数
标记清除:大部分浏览器使用这种垃圾回收,当变量进入执行环境(声明变量)的时候,垃圾回收器将变量进行了标记,当该变量离开环境的时候,将其再度标记,随之进行删除。
引用计数:这种方式常常会引起内存泄漏,主要存在于低版本的浏览器,它的机制就是跟踪某一个值的引用次数,当声明一个变量并且将一个引用类型赋值给变量的时候引用次数加1,当这个变量指向其他一个时引用次数减一,当为0时出发回收机制进行回收。
47. 逐进增强和优雅降级
逐进增强:针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高版本浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
48. 判断一个值是什么类型有哪些方法?
typeof 运算符
instanceof 运算符
Object.prototype.toString 方法
49. 怎么判断一个变量arr的话是否为数组(此题用 typeof 不行)?
arr instanceof Array arr.constructor == Array Object.protype.toString.call(arr) == '[Object Array]'
50. new操作符具体干了什么呢?
- 创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
- 属性和方法被加入到 this 引用的对象中。
- 新创建的对象由 this 所引用,并且最后隐式的返回 this 。
51. JSON 的了解?
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小 {'age':'12', 'name':'back'}
52. documen.write 和 innerHTML 的区别?
document.write 只能重绘整个页面
innerHTML 可以重绘页面的一部分