前言
作为前端,虽然我们开发没问题,但是遇到理论性的东西有时候需要一些专业的语言来描述,以此来达到面试官的要求。下面是我整理的一些面试题,有一些是特别基础的,有一些是理论性的,还有一些是我在面试中答的不是很好的,在此整理,希望能帮助到更多的人.
面试题
-
js有哪些数据类型
string、number、boolean、array、object、null、undefined -
js创建数组的方式
var arrayObj = new Array()
var arrayObj = new Array(3)
var arrayObj = new Array(1,2,3)
var arrayObj = [1,2,3] -
{}与new Object()的区别是什么?
这两种创建对象方式,从测试效果来看,{}会快一点。
{} 这个叫做对象字面量
如果new Object()中没有传入参数,与{}是一样的。
但是如果传入不同的参数,会有不同的效果。
传入String 返回String,类似new String()
传入Number 返回Number,类似new Number()
传入Object 返回Object,其实没啥用
速度上{}会比new Object()快一点 -
instantof和typeof的区别
instanceof运算符:此运算符可以判断一个变量是否是某个对象(类)的实例,返回值是布尔类型
typeof运算符:此运算符可以返回一个字符串(number、boolean、string、function、object、undefined),用于说明元算数的类型 -
阻止事件冒泡和捕获以及阻止默认行为
e.stopPropagation() // 阻止冒泡和捕获
e.preventDefault() // 阻止默认行为 -
字符串相关操作
数组转字符串(join)
字符串转数组(split)
字符串合并(concat)
检索字符串(indexOf)
返回指定位置字符(charAt)
截取字符串(substr,substring,slice)区别:一个截取到第几位,一个截取多少位
替换字符串(replace)
转小写字符(toLowerCase)
转大写字符(toUpperCase)
正则匹配(match)空
正则查找(search)-1 -
对象相关操作
删除字段(delete)
转json字符串(JSON.stringfy)
转json对象(JSON.parse) -
数组操作
删除数组元素(delete)长度不变
删除/替换元素(splice)长度改变
添加元素(push)
删除最后一个元素(pop)
头部添加元素(unshift)
合并数组(concat)
排序(sort)
翻转(reverse)
转字符串(join,toString)
截取(slice) -
什么是自执行函数?自执行函数的作用?
自执行函数就是创建一个匿名函数并执行
作用就是创建独立作用域,避免变量污染 -
this的指向
全局环境下,this就代表window对象。
对象环境指向对象。
构造函数中的this 会指向创建出来的实例对象
在 DOM 事件中使用 this,this 指向了触发事件的 DOM 元素本身 -
如何修改this的指向
可以使用局部变量来代替this指针
使用call 或 apply 方法
call中的第一个参数就是要更改this指向的对象,为必选参数;
apply的作用和call一样,不同的是传参的形式。apply需要以数组的形式传递参数 -
Ajax实现步骤(5步)
a) 创建XMLHttpRequest对象
b) 设置回调函数
c) 使用OPEN方法与服务器建立连接(如果是post方式,设置请求头信息)
d) 向服务端发送数据(如果是post方式,数据不为空)
e) 在回调函数中针对不同的响应状态进行处理 -
js垃圾回收机制
JS的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。
javascript权威指南中的定义:
由于字符串、对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JavaScript程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够被再用,否则,JavaScript的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。 -
垃圾回收方式
1) 标记清除
这是javascript中最常用的垃圾回收方式。当变量进入执行环境是,就标记这个变量为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到他们。当变量离开环境时,则将其标记为“离开环境”。
垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后。垃圾收集器完成内存清除工作,销毁那些带标记的值,并回收他们所占用的内存空间。
2) 引用计数
另一种不太常见的垃圾回收策略是引用计数。引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型赋值给该变量时,则这个值的引用次数就是1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数就减1。当这个引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其所占的内存空间给收回来。这样,垃圾收集器下次再运行时,它就会释放那些引用次数为0的值所占的内存。 -
变量的生命周期
当一个变量的生命周期结束之后它所指向的内存就应该被释放。JS有两种变量,全局变量和在函数中产生的局部变量。局部变量的生命周期在函数执行过后就结束了,此时便可将它引用的内存释放(即垃圾回收),但全局变量生命周期会持续到浏览器关闭页面。 -
js堆栈
堆和栈都是运行时内存中分配的一个数据区,因此也被称为堆区和栈区;
二者存储的数据类型和处理速度不同;
堆(heap) 用于复杂数据类型(引用类型)分配空间,例如数组对象、object对象;它是运行时动态分配内存的,因此存取速度较慢。
栈(stack) 中主要存放一些基本类型的变量和对象的引用,其优势是存取速度比堆要快,并且栈内的数据可以共享,但缺点是存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。 -
宏任务和微任务
宏任务(task):就是的 JS 内部(任务队列里)的任务,严格按照时间顺序压栈和执行。如 setTimeOut、setInverter、setImmediate 、 MessageChannel等
微任务(Microtask ):通常来说就是需要在当前 task 执行结束后立即执行的任务,例如需要对一系列的任务做出回应,或者是需要异步的执行任务而又不需要分配一个新的 task,这样便可以减小一点性能的开销。microtask 任务队列是一个与 task 任务队列相互独立的队列,microtask 任务将会在每一个 task 任务执行结束之后执行。每一个 task 中产生的 microtask 都将会添加到 microtask 队列中,microtask 中产生的 microtask 将会添加至当前队列的尾部,并且 microtask 会按序的处理完队列中的所有任务。microtask 类型的任务目前包括了 MutationObserver 以及 Promise 的回调函数。 -
渐进增强和优雅降级的区别
优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作。由于IE独特的盒模型布局问题,针对不同版本的IE的hack实践过优雅降级了,为那些无法支持功能的浏览器增加候选方案,使之在旧式浏览器上以某种形式降级体验却不至于完全失效.
渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,向页面增加无害于基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用。
-
标签语义化的理解
1) 去掉或样式丢失的时候能让页面呈现清晰的结构:html本身是没有表现的,我们看到例如<h1>是粗体,字体大小2em,加粗;<strong>是加粗的,不要认为这是html的表现,这些其实html默认的css样式在起作用,所以去掉或样式丢失的时候能让页面呈现清晰的结构不是语义化的HTML结构的优点,但是浏览器都有有默认样式,默认样式的目的也是为了更好的表达html的语义,可以说浏览器的默认样式和语义化的HTML结构是不可分割的。
2) 屏幕阅读器(如果访客有视障)会完全根据你的标记来“读”你的网页。
3) PDA、手机等设备可能无法像普通电脑的浏览器一样来渲染网页(通常是因为这些设备对CSS的支持较弱)
4) 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重。
5) 便于团队开发和维护,语义化更具可读性,是下一步吧网页的重要动向,遵循W3C标准的团队都遵循这个标准,可以减少差异化。 -
对网站文件和资源优化
1) 文件合并文件最小化
2) 文件压缩使用
3) CDN托管缓存的使用(多个域名来提供缓存) -
减少页面加载时间的方法
1) 优化图片
2) 图像格式的选择(GIF:提供的颜色较少,可用在一些对颜色要求不高的地方)
3) 优化CSS(压缩合并css,如margin-top,margin-left…)
4) 网址后加斜杠(如www.campr.com/目录,会判断这个“目录是什么文件类型,或者是目录。)
5) 标明高度和宽度(如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,如果图片很多,浏览器需要不断地调整页面。这不但影响速度,也影响浏览体验。当浏览器知道了高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容。从而加载时间快了,浏览体验也更好了。)
6) 减少http请求(合并文件,合并图片) -
js面向对象的理解
ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。但是,ECMAScript 没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。
js(如果没有作特殊说明,本文中的js仅包含ES5以内的内容)本身是没有class类型的,但是每个函数都有一个prototype属性。prototype指向一个对象,当函数作为构造函数时,prototype则起到类似class的作用。
创建方法:
1) 创建对象方法。
创建一个对象,然后给这个对象新建属性和方法。
2) 构造函数方法
函数名和实例化构造名相同且大写,(PS:非强制,但这么写有助于区分构造函数和普通函数);
通过构造函数创建对象,必须使用new 运算符 -
原型的理解
创建每一个函数都有一个prototype属性,这个属性其实是一个指针,这个指针总指向一个对象。这个对象的用途就是将特定的属性和方法都包含在内,起到一个实例对象共享的作用。 -
原型链的理解
因为每个对象和原型都有原型,对象的原型指向原型对象,而父的原型又指向父级的父级,这种原型层层连接起来的就构成了原型链。 -
什么是闭包
闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。 -
闭包的优缺点
(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。 -
常见的浏览器返回状态吗
200:请求成功
301/302: 重定向
401:未授权
403:无权限访问
404:未找到页面
500:服务器错误