前端面试题整理-JS
JS
-
For-in、Object.keys、Object.getOwnPropertyNames、Object.getOwnPropertySymbols、Reflect.ownKeys区别
For-in:遍历自身和继承的可枚举属性,不含Symbol属性。
Object.keys(obj):返回数组,包含对象自身(不含继承)的可枚举属性,不含Symbol属性
Object.getOwnPropertyNames返回数组,包含对象自身所有属性,包括不可枚举,不含Symbol
Object.getOwnPropertySymbols(obj)返回数组,包含对象自身的所有Symbol
Reflect.ownKeys(obj):返回数组,包含对象自身的所有属性,不管是否枚举,Symbol或字符串
-
判断数据类型的方法
instanceof只能判断两个对象是否属于实例关系,而不能判断一个对象实例具体属于哪种类型
constructor不能判断null和undefined,当开发者重写prototype后constructor会默认为object
type of 对null,array,object的返回值都是object
Objet.prototype.toString.call(obj)可以正确判断出数据类型(string,number,boolean,undefined,null,object,array,function)
-
说说写JavaScript的基本规范?
- 不要在同一行声明多个变量。
- 请使用 ===/!==来比较true/false或者数值
- 使用对象字面量替代new Array这种形式
- 不要使用全局函数。
- Switch语句必须带有default分支
- 函数不应该有时候有返回值,有时候没有返回值。
- For循环必须使用大括号
- If语句必须使用大括号
- for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。
-
JavaScript原型,原型链 ? 有什么特点?
JS中每个函数都存在有一个原型对象属性prototype。并且所有函数的默认原型都是Object的实例。
每个继承父函数的子函数的对象都包含一个内部属性_proto_。该属性包含一个指针,指向父函数的prototype。若父函数的原型对象的_proto_属性为再上一层函数。在此过程中就形成了原型链。
原型链实现了继承。原型链存在两个问题:a 包含引用类型值的原型属性会被所有实例共享。b 在创建子类型时,无法向超类型的构造函数中传递参数。特点:JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的话,就会查找他的Prototype对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象。
-
JavaScript有几种类型的值?(堆:原始数据类型和 栈:引用数据类型),你能画一下他们的内存图吗?
栈:原始数据类型(先入后出),由编译器自动分配释放,一级缓存,调用完毕立即释放
堆:引用数据类型(利用完全二叉树结构维护数据,时间复杂度为o(logn)),由程序员分配释放,二级缓存,垃圾回收
完全二叉树:除了最后一层树全满,最后一层所有节点连续集中在最左边。上浮、下沉、插入、弹出
-
Javascript如何实现继承?
-
Javascript创建对象的几种方式?
构造函数、对象字面量、原型模式、object.create()
-
Javascript作用链域?
作用域链是函数被创建的作用域中对象的集合。作用域链可以保证对执行环境有权访问的所有变量和函数的有序访问。
作用域链的最前端始终是当前执行的代码所在环境的变量对象(如果该环境是函数,则将其活动对象作为变量对象),下一个变量对象来自包含环境,全局执行环境的变量对象始终是作用域链中的最后一个对象。
-
谈谈this对象的理解。
this表示当前对象,this的指向是根据调用的上下文来决定的,默认指向window对象,对象函数调用,哪个对象调用就指向哪个对象,使用 new 实例化对象,在构造函数中的this指向实例化对象
-
eval是做什么的?
把字符串参数解析成JS代码并运行,并返回执行的结果。
应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。
-
什么是window对象? 什么是document对象?
window是顶层对象,而不是另一个对象的属性,是浏览器的窗口。
document是window和frames对象的一个属性,是显示于窗口或框架内的一个文档。
-
["1", "2", "3"].map(parseInt) 为什么为[1,NaN,NaN]?
.map传值时,以parseInt(value,index,array)传入
parseInt('1',0,[1,2,3])=1,因为进制位为0时以十进制转换。
parseInt('2',2,[1,2,3])=NaN,因为进制位为低于数值。
parseInt('3',2,[1,2,3])=NaN,因为进制位为低于数值。
-
关于事件,IE与火狐的事件机制有什么区别? 如何阻止冒泡?
事件流是从页面中接受事件的顺序,分为冒泡流和捕获流。事件冒泡是从最具体的元素接收,逐级向上传播。事件捕获是从上级节点开始,逐步到最具体的节点。
IE是冒泡流,火狐同时支持冒泡流和捕获流。
组织事件冒泡:e.stopPropagation(),IE使用e.cancelBuddle = true
-
js正常模式和严格模式有什么不同?
正常模式中,变量没有声明就赋值会默认为全局变量,严格模式禁止。
严格模式this禁止指向全局,使用构造函数不加new会报错。
严格模式一般禁止删除变量,只有configurable设置为true才可删除。
严格模式对象不能有重名属性,正常模式可以。
严格模式不能有重名参数,正常模式可以。
-
new操作符具体干了什么呢?
创建一个空对象,设置原型链,让构造函数中的this指向创建的空对象,如果构造函数返回值类型,返回obj,如果构造函数返回引用类型,返回这个引用类型的对象。
-
Javascript中,有一个函数,执行时对象查找时,永远不会去查找原型,这个函数是?
hasOwnProperty
-
JSON
Json有对象和数组两种格式,对象调用key,数组调用通过索引值。json转字符串使用JSON.stringify,字符串转对象用JSON.parse
-
js延迟加载的方式有哪些?
defer属性、async属性、动态创建、jquery的getScript()
-
Ajax 是什么? 如何创建一个Ajax?
Ajax:请求数据的一种方式
var xml = new XMLHttpRequest() xml.open('post',url,false) xml.send() xml.onreadystatechange=function () { if(xml.readyState === 4 && xml.status == 200){ console.log(xml.responseText) } }
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
-
页面编码和被请求的资源编码如果不一致如何处理?
给请求的资源设置charset
-
服务器代理转发时,该如何处理cookie?
服务器代理转发时,可以根据set-cookie的path属性设置cookie有效路径实现是否发送cookie
-
模块化开发怎么做?
模块化开发是为了解决多人合作项目时,使用同一个变量名等造成的冲突,以及项目依赖文件等引用顺序。
模块化开发使代码耦合度降低,以最少的模块、零部件满足更多的个性需求,更方便地使用别人的代码。
模块化开发分为服务端规范和浏览器规范。
服务器端规范:CommonJS :nodejs
浏览器端规范:AMD:RequireJS,对于依赖提前执行,依赖前置,API一个当多个用,模块加载完成后马上执行,用户体验好
CMD:SeaJS,对于依赖延后执行,依赖就近,API严格区分,职责单一,模块加载完成后没有立即执行而是等到require再执行,性能好
使用模块式开发:页面A引入js1,调用js1中的方法。js1引入js2,调用js2中module.export的方法,以此类推
AMD和CMD需要使用export和import,但是浏览器没有完全支持,因此需要使用babel。实现这个转换到有browserify和webpack(gulp+browserify , node+webpack)
CommonJS规范:如果在a.js使用b.js,一定要在a.js中require('b.js'),在b.js中提供module.exports
CommonJS定义的模块分为:{模块引用(require)} {模块定义(exports)} {模块标识(module)}
浏览器不兼容CommonJS是因为缺少module 、exports、require、global四个变量
Browserify能够转换export、import是因为将所有模块放入一个数组,id为模块编号,source是模块的源码,deps是模块的依赖。
由于require是同步的,必须等上行代码加载完成后才能执行,服务器端不是问题,浏览器端需要使用异步,产生了AMD。因此,CommonJS主要是为了js再后端的表现制定的,AMD主要为前端js制定规范。
AMD的require需要两个参数,module和callback。require([module],callback)
RequireJS的诞生是为了实现js文件异步加载,避免网页失去响应,与管理模块间的依赖性。
CMD:define(function(require,exports,module){...});
-
requireJS的核心原理是什么?(如何动态加载的?如何避免多次加载的?如何 缓存的?)
核心是js的加载模块,通过正则匹配模块以及模块的依赖关系,保证文件加载的先后顺序,根据文件的路径对加载过的文件做了缓存
-
谈一谈你对ECMAScript6的了解?
ES6时js的下一代标准,规定js的使用规范
Let、const (暂时性死区)、变量解构、startsWith等函数、promise
-
.call() 和 .apply() 的作用和区别?
.call(func,data1,data2…)
.apply(func,[data1,data2…])
-
数组和对象有哪些原生方法,列举一下?
数组:concat、join、sort、push
对象:map、each、tostring
-
如何编写高性能的Javascript?
- 不要用for-in访问数组,可以用for-in访问对象
- 将耗费资源的DOM访问进行缓存(定义变量保存数组长度)
- 不要再函数内使用多个if嵌套
- 避免循环,防止内存泄漏
- 避免返回未声明
-
哪些操作会造成内存泄漏?
意外的全局变量(未声明便赋值的变量)、闭包、没有清理的DOM元素引用、被遗忘的setInterval、子元素存在引起内存泄漏
-
JQuery的实现原理?
采用构造函数进行开发,jquery是一个类,将常用方法定义在jquery.prototype上
-
jQuery 的属性拷贝(extend)的实现原理是什么,如何实现深拷贝?
实现原理:将后面的对象合并到前面的对象。
当第一个参数为true时实现深拷贝,会在第一个对象上进行递归的合并。
当第一个参数为false时实现浅拷贝,会用第二个对象相同的key值重写一个属性,值不会被合并。
浅拷贝:只拷贝对象数据的引用,新旧数据没有完全分离,还会互相影响。
function shallowCopy( target ){ if(typeof target !== 'object') return ; //判断目标类型,来创建返回值 var newObj = target instanceof Array ? [] : {}; for(var item in target){ //只复制元素自身的属性,不复制原型链上的 if(target.hasOwnProperty(item)){ newObj[item] = target[item] } } return newObj }
深拷贝:新旧数据完全分离,互不影响
function deepCopy( target ){ if(typeof target !== 'object') return ; //判断目标类型,来创建返回值 var newObj = target instanceof Array ? [] : {}; for(var item in target){ //只复制元素自身的属性,不复制原型链上的 if(target.hasOwnProperty(item)){ newObj[item] = typeof target[item] == 'object' ? deepCopy(target[item]) : target[item] //判断属性值类型 } } return newObj }
-
jquery.extend 与 jquery.fn.extend的区别?
jQuery.extend是拓展整个全局函数,$.ajax()这种,jQuery.fn.extend是给$的原型扩展函数,拓展选择器$('div').ajax()
-
谈一下Jquery中的bind(),live(),delegate(),on()的区别?
bind(event,data,function)直接绑定在元素上,对js添加的元素无效
live(event,data,function)通过冒泡的方式绑定到元素上,更适合列表类型,支持动态数据
delegate(childSelector,event,data,function)
on(event,childselector,data,function)
-
JQuery一个对象可以同时绑定多个事件,这是如何实现的?
有一个处理函数数组,监听到一个事件就往数组里放一个handle,然后触发事件的时候一次执行
-
是否知道自定义事件。jQuery里的fire函数是什么意思,什么时候用?
自定义事件就是我们按照浏览器对事件的机制来自定义的函数,通过new Event()创建
由我们自己执行的函数就是函数调用,不是由我们执行的函数就是事件触发。
callbacks.fire() 函数用于传入指定的参数调用所有的回调。
使用:传入相同的参数,调用一系列函数时使用。
-
jQuery 是通过哪个方法和 Sizzle 选择器结合的?
Sizzle是一个纯javascript CSS选择器引擎。一般js匹配css是从左往右,Sizzle从右往左,提升了性能。
jQuery.fn.find()进入Sizzle
-
针对 jQuery性能的优化方法?
jquery避免使用class选择器,尽量用id
缓存jquery对象
压缩js
事件委托(冒泡)
-
Jquery与jQuery UI有啥区别?
jqueryui是jquery的一个插件,jquery是对javascript的封装,而jqueryui是一个基于jquery的一个UI方面的框架。
(1) jQuery是一个js库,主要提供的功能是选择器,属性修改和事件绑定等等。
(2) jQueryUI则是在jQuery的基础上,利用jQuery的扩展性,设计的插件。提供了一些常用的界面元素,诸如对话框、拖动行为、改变大小行为等等。
-
jQuery和Zepto的区别?各自的使用场景?
Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api
Zepto对象没有addEventListener事件
Zepto选择器表达式中value值必须用单引号或双引号扩起来
Zepto根据标准浏览器,只有width(),height(),没有innerHeight,outerHeight等,返回值与jquery不同
Zepto each不能遍历对象
Zepto:移动端,jquery:web端
-
如何判断当前脚本运行在浏览器还是node环境中?
通过判断Global对象是否为window,如果不为window,当前脚本没有运行在浏览器中
-
移动端最小触控区域是多大?
44pt x 44pt
-
jQuery 的 slideUp动画 ,如果目标元素是被外部事件驱动, 当鼠标快速地连续触发外部元素事件, 动画会滞后的反复执行,该如何处理呢?
jQuery中slideUp 、slideDown、animate等动画运用时,如果目标元素是被外部事件驱动, 当鼠标快速地连续触发外部元素事件, 动画会滞后的反复执行,其表现不雅。
解决办法:
1、在触发元素上的事件设置为延迟处理, 即可避免滞后反复执行的问题(使用setTimeout)
2、在触发元素的事件时预先停止所有的动画,再执行相应的动画事件(使用stop)
-
把 Script 标签 放在页面的最底部的body封闭之前 和封闭之后有什么区别?浏览器会如何解析它们?
如果说放在body的封闭之前,将会阻塞其他资源的加载
如果放在body封闭之后,不会影响body内元素的加载
-
移动端的点击事件的有延迟,时间是多久,为什么会有? 怎么解决这个延时?
click 有 300ms 延迟,为了实现safari的双击事件的设计,浏览器要知道你是不是要双击操作。
-
什么是“前端路由”?什么时候适合使用“前端路由”? “前端路由”有哪些优点和缺点?
路由是根据不同的 url 地址展示不同的内容或页面,前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做,之前是通过服务端根据 url 的不同返回不同的页面实现的。
在单页面应用,大部分页面结构不变,只改变部分内容的使用前端路由
优点:用户体验好,不需要每次都从服务器全部获取,快速展现给用户
缺点:使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存,单页面无法记住之前滚动的位置,无法在前进,后退的时候记住滚动的位置
-
检测浏览器版本版本有哪些方式?
使用navigator.userAgent的值来判断
-
我们给一个dom同时绑定两个点击事件,一个用捕获,一个用冒泡。会执行几次事件,会先执行冒泡还是捕获?
绑定在被点击元素的事件是按照代码顺序发生,其他元素通过冒泡或者捕获“感知”的事件,按照W3C的标准,先发生捕获事件,后发生冒泡事件。所有事件的顺序是:其他元素捕获阶段事件 -> 本元素代码顺序事件 -> 其他元素冒泡阶段事件 。
-
Webpack热更新实现原理?
热更新:热更新就是动态下发代码,它可以使开发者在不发布新版本的情况下,修复 BUG 和发布功能。
浏览器的网页通过websocket协议与服务器建立起一个长连接,当服务器的css/js/html进行了修改的时候,服务器会向前端发送一个更新的消息,如果是css或者html发生了改变,网页执行js直接操作dom,局部刷新,如果是js发生了改变,只好刷新整个页面。
-
请介绍一下JS之事件节流?
在监听浏览器滚动条的scroll事件时该事件会触发很多次,这样当快速滚动时会有很差的性能,所以要限制事件触发的频率,可以防抖和节流
防抖:让在用户动作停止后延迟x ms再执行回调
截流:在用户动作时没隔一定时间(如200ms)执行一次回调。
-
Object.is() 与原来的比较操作符“ ===”、“ ==”的区别?
Object.is()类似于===,但在三等号判等的基础上特别处理了 NaN 、-0 和 +0 ,保证 -0 和 +0 不再相同,但 Object.is(NaN, NaN) 会返回 true。
-
css-loader的原理?
Css-loader:将js中的css加载进模块,处理css中路径引用等问题
里面的每一个对象都用正则表达式,对应着一种配对方案。loader加载器用于将不同的文件加载到js文件中
-
React 使用场景?
一些后台界面,或者是和后台数据比较多,又或者和用户交互比较多,dom操作频繁的都可以用react。
-
实现组件有哪些方式?
-
用js实现千位分隔符?
var str = '1234567890000000'; console.log(str.replace(/(?=(?:\d{3})+(?!\d))/g,','));