JavaScript基础
1.null,undefined的区别?
- Undefined类型只有一个值,即undefined。当声明的变量还未被初始化时,变量的默认值为undefined。
- Null类型也只有一个值,即null。
- javascript高级程序设计:在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined。null值则是表示空对象指针。
2.“==”和“===”的不同
答案:前者会自动转换类型,再判断是否相等
后者不会自动类型转换,直接去比较数据类型。如果不等结果就为false
3.请说出你熟悉的数组的操作方法并说出如何使用?
//改变原数组方法:
var arr = []
arr.push() //数组末尾添加
arr.pop() //数组末尾删除
arr.unshift() //数组头部添加
arr.shift() //数组头部删除
arr.splice() //方法向/从数组中添加/删除项目,然后返回被删除的项目。
arr.reverse() //方法用于颠倒数组中元素的顺序。
arr.sort() //方法用于对数组的元素进行排序。
//不改变原数组方法:
var arr = []
arr.includes(); // 方法用于判断字符串是否包含指定的子字符串。如果找到匹配的字符串则返回 true,否则返回 false。
arr.indexOf(); //方法可返回某个指定的字符串值在字符串中首次出现的位置。
arr.lastIndexOf(); //方法可返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。
arr.slice(); //方法可从已有的数组中返回选定的元素。
arr.join(); //方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。
arr.toString();
arr.concat(); //方法用于连接两个或多个数组。
4.总结String 对象操作方法
方法 | 描述 |
charAt() | 返回在指定位置的字符。 |
charCodeAt() | 返回在指定的位置的字符的 Unicode 编码。 |
concat() | 连接两个或更多字符串,并返回新的字符串。 |
fromCharCode() | 将 Unicode 编码转为字符。 |
indexOf() | 返回某个指定的字符串值在字符串中首次出现的位置。 |
includes() | 查找字符串中是否包含指定的子字符串。 |
lastIndexOf() | 从后向前搜索字符串,并从起始位置(0)开始计算返回字符串最后出现的位置。 |
search() | 查找与正则表达式相匹配的值。 |
replace() | 用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。 |
slice() | 提取字符串的片断,并在新的字符串中返回被提取的部分。不包含结束的索引 |
split() | 把字符串分割为字符串数组。 |
substr() | 从起始索引号提取字符串中指定数目的字符。 |
substring() | 提取字符串中两个指定的索引号之间的字符。 |
toLowerCase() | 把字符串转换为小写。 |
toUpperCase() | 把字符串转换为大写。 |
trim() | 去除字符串两边的空白 |
toString() | 返回一个字符串。 |
5.javascript的typeof返回哪些数据类型.
答案:string,boolean,number,undefined,function,object
注意:
- typeof null得到的是object
- typeeof NaN 得到的是number
6.什么是作用域和作用域链,js有几种作用域分别是?
作用域(scope)
作用域是指程序源代码中定义变量的区域,简单来说,一段程序代码中所用到的变量并不总是有效的,而限定这个变量的可用性的代码范围就是这个变量的作用域。
js有三种:
- 全局作用域
全局作用域是最外围的一个作用域。根据 ECMAScript 实现所在的宿主环境不同,表示全局作用域的对象也不一样。在浏览器中,全局作用域就是window对象,node则是global对象。 - 局部作用域
和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的是函数内部。 - 块级作用域
ES5本身是没有块级作用域,ES6 引入了块级作用域,让变量的生命周期更加可控,使用let和const声明的变量在指定块(简单理解就是一对花括号)的作用域外无法被访问。
作用域链(scope chain)
一般情况下,变量取值到创建这个变量的函数的作用域中取值。但是如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。
7.简单数据类型和复杂数据类型
简单类型(基本数据类型、值类型):在存储时变量中存储的是值本身,包括String ,Number,Boolean,Undefined,Null
复杂数据类型(引用类型):在存储时变量中存储的仅仅是地址(引用),通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等;
8.new操作符具体干了什么呢?
在JavaScript中,new操作符用于创建一个给定构造函数的实例对象
- 创建一个新对象;
- 把函数中上下文(作用域)对象this指向该对象;
- 执行代码,通过this给新对象添加属性或方法;
- 返回对象;
9.讲几个常见的js内置对象?
Object 是 JavaScript 中所有对象的父对象
数据封装类对象:Object、Array、Boolean、Number 和 String
其他对象:Function、Arguments、Math、Date、RegExp
10.eval是做什么的?
它的功能是把对应的字符串解析成JS代码并运行;
应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。
11.请说出至少三种减低页面加载时间的方法?
- 压缩css、js文件
- 合并js、css文件,减少http请求
- 外部js、css文件放在最底下
- 减少dom操作,尽可能用变量替代不必要的dom操作
12.添加/删除/替换/插入到某个接点的方法?
1.创建新节点
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
2.添加、移除、替换、插入
appendChild() //添加
removeChild() //移除
replaceChild() //替换
insertBefore() //插入
remove()//删除所有的子元素
3.查找
getElementsByTagName() //通过标签名称
getElementsByClassName() //通过元素的class属性的值
getElementById() //通过元素Id,唯一性
13.Javascript的事件流模型都有什么?
事件流:从页面中接收事件的顺序。也就是说当一个事件产生时,这个事件的传播过程,就是事件流。 事件流包括三个阶段:事件捕获、目标阶段、事件冒泡。
JS事件流最早IE提出的是冒泡流,而网景提出的是捕获流,后来在W3C组织的统一之下,JS支持了冒泡流和捕获流。
但对于事件本身来说,目前大多数事件支持冒泡流
14.什么是事件委托?说一说事件代理,优缺点是什么?
事件委托又叫事件代理,利用事件冒泡的原理,原本绑定在子元素身上的事件,现在绑定在父元素身上,由父元素监听事件的行为。
优点:
1.可以减少事件注册,节省大量内存占用
2.可以将事件应用于动态添加的子元素上
缺点:
使用不当会造成事件在不应该触发时触发
应用场景:
如果我们有⼀个列表,列表之中有⼤量的列表项,我们需要在点击列表项的时候响应⼀个事件;
如果给每个列表项⼀⼀都绑定⼀个函数,那对于内存消耗是⾮常⼤的;
这时候就可以事件委托,把点击事件绑定在⽗级元素 ul 上⾯,然后执⾏事件的时候再去匹配⽬标元素
15.说一下你对this的理解?
this 的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this 的指向不同
- 普通函数this在非严格模式下指向window,严格模式下指向undefined
- 构造函数this指向实例对象,原型对象里面的方法也指向实例对象
- 对象方法中的this指向该方法所属的对象
- 事件绑定方法中的this指向绑定该事件的对象
- 定时器函数的this指向window
- 立即执行函数中的this指向window
16.BOM 和 DOM 的关系
BOM全称Browser Object Model,即浏览器对象模型,主要处理浏览器窗口和框架。
DOM全称Document Object Model,即文档对象模型,是 HTML 和XML 的应用程序接口(API),遵循W3C 的标准,所有浏览器公共遵守的标准。
可以说,BOM包含了DOM(对象),浏览器提供出来给予访问的是BOM对象,从BOM对象再访问到DOM对象,从而js可以操作浏览器以及浏览器读取到的文档。
17.什么是window对象? 什么是document对象?
window对象代表浏览器中打开的一个窗口。
document对象代表整个html文档。
注意:实际上,document对象是window对象的一个属性。
18.如何编写高性能的JavaScript,(前端如何优化)
- 将js脚本放在页面底部,加快渲染页面;
- 将js脚本成组打包,减少请求;
- 使用非阻塞方式下载js脚本;
- 尽量使用局部变量来保存全局变量;
- 尽量减少使用闭包;
- 使用window对象属性方法时省略window;
- 尽量减少对象成员嵌套;
- 缓存DOM节点的访问;
- 通过避免使用eval和function()构造器;
- 给setTimeout()和setInterval()传递函数而不是字符作为参数;
- 尽量使用直接量创建对象和数组;
- 最小化重绘(repaint)和回流(reflow);
19.setTimeout 和 setInterval 区别
- setTimeout(fn,t),超时定时器,超过时间t,就执行fn。
- setInterval(fn,t),间歇定时器,调用周期t,执行fn。
二者调用后,均返回一个数值ID,此ID是计划执行代码的唯一标识符,可以通过它来取消尚未执行的调用。
clearTimeout(id)和clearInterval(id)。
常问的点,前者是在一定时间过后将函数添加至执行队列,执行时间=延迟时间+之前函数代码执行时间+执行函数时间。
后者是不管前一次是否执行完毕,每隔一定时间重复执行,用于精准执行互相没有影响的重复操作。
JavaScript高阶
1.什么是原型,什么是原型链?
原型:
每一个构造函数,都会有一个 prototype
属性。该属性指向一个对象,该对象称之为 原型对象
,即原型。
原型链:
当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__
上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__
中查找(即上一层构造函数的prototype),这样一层一层向上查找直到Object的prototype结束,这样就会形成一个链式结构,我们称为原型链。我们可以说:它们是继承关系
2.call / apply / bind 有啥区别
call:
call(thisObj, arg1, arg2...)
要求传入函数的参数是参数列表
apply:
apply(thisObj, [argArray])
要求传入函数的参数必须放入数组中整体传入
bind:
bind(thisObj,arg1,arg2,...)
- 共同点 : 都可以改变this指向
- 不同点:
- call 和 apply会立即调用函数.bind不会立即调用函数, 需要手动调用.
- call及bind 和 apply传递的参数不一样,call及bind传递参数使用逗号隔开,apply使用数组传递.
- 应用场景
- call 经常做继承.
- apply 经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值
- bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向.
3.JS四种检测数据类型的方式
- typeOf :只能检测基本数据类型
- instanceOf :检测当前实例是否属于某个类的方法
- constructor: 检测当前实例的构造函数
- Object.prototype.toString.call( ) : 最准确的方式;
4.说说继承
- 构造函数继承(在子类的构造函数中执行父类的构造函数,并为其绑定子类的this,让父类的构造函数把成员属性和方法都挂到子类的this上)
缺点:无法访问原型上的方法 - 原型链继承(将子构造函数的原型对象指向父构造函数的实例,让constructor 重新指向子构造函数)
缺点:无法为不同的实例初始化继承来的属性 - 组合式继承(将原型链继承和构造函数继承组合到一起, 综合了原型链继承和构造函数继承的优点)
缺点:调用了两次父类构造函数 - 原型式继承(Object.create():这个方法接收两个参数:一是用作新对象原型的对象、二是为新对象定义额外属性的对象(可选参数),核心思想:使用一个中间函数,连接父类与子类的关系。借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。)
- extends继承(class和extends是es6新增的,class创建一个类,extends实现继承)
5.for..in和for..of和forEach的区别
for ..in:
可以循环数组也能循环对象,循环遍历的值是数据结构的键值;
可以使用return、break、continue中断循环;
在有些情况下会以随机顺序遍历数组,所以最好用来遍历对象;
for ..of:
可以循环可迭代对象(如数组、字符串等),循环遍历的值是数据结构的值;
可以使用return、break、continue中断循环;
forEach:
在回调函数内部有三个参数:item、index、arr分别表示当前项、当前项的索引下标、数组本身;
会对数组的每一个元素执行一次提供的函数,不改变原数组、没有返回值(undefined);
6.forEach和map方法的区别
相同点
- 都是循环遍历数组中的每一项
- forEach和map方法里每次执行匿名函数都支持3个参数,参数分别是value(当前每一项)、index(索引值)、array(原数组)
- 匿名函数中的this都是指向window
- 只能遍历数组
区别
- forEach()返回值是undefined,
- map()返回一个新数组
7. js高阶中数组的常用的操作方法
● arr.forEach(function(){}):遍历数组
● arr.map(function(){}):对数组遍历并操作数组元素,返回操作后元素组成的新数组
● arr.filter(function({}));对数组元素进行过滤,返回符合元素组成的新数组
● arr.find(function(){}):查找数组中符合的元素
● arr.some(function){}):对数组的元素进行判断是否有符合的元素
● arr.every(function){}):对数组的元素进行判断是否全部符合
● arr.find(function){})方法返回符合查找条件的第一个数组元素的值。
● arr.reduce(function(total,value,index,array){},initialValue):方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
8.什么是严格模式
JavaScript 除了提供正常模式外,还提供了严格模式(strict mode)。ES5 的严格模式是采用具有限制性 JavaScript变体的一种方式,即在严格的条件下运行 JS 代码。
严格模式在 IE10 以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。
设立严格模式的原因:
- 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的Javascript做好铺垫。
严格模式下的语法变化:
- 不能不声明变量直接使用
- 函数的this指向,指向undefined
- 函数的参数,不可以重名
- 构造函数如果不使用new实例化,会报错
9.什么是高阶函数?
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
只需满足以下任意一个条件,即是高阶函数:
1. 接受一个或多个函数作为输入
2. return 返回另外一个函数
10.闭包是什么,有什么特性,对页面有什么影响
概念:内部函数访问其所在的外部函数中声明的参数和变量,形成的词法环境叫闭包.
闭包有三个特性:
- 1、函数嵌套函数
- 2、函数内部访问外部函数的参数或变量
- 3、可以使函数中的变量可以长期驻扎在内存
使用闭包的好处:
- 1、变量长期驻扎在内存中
- 2、避免全局变量的污染(多人定义同样名字的全部变量冲突)
- 3、私有成员的存在
使用闭包的坏处:
- 1、常驻内存
- 2、会增大内存的使用量
- 3、使用不当会造成内存泄露
注意:内存泄露:指的是应用程序不再用到的内存,由于某些原因,没有及时释放,就叫做内存泄漏。
- 会造成内存泄漏的js操作:
- 意外的全局变量
- 未清理的DOM元素的引用
- 被遗忘的定时器或者回调函数
- 闭包
- 过多的console.log语句
11.浅拷贝与深拷贝
深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。
浅拷贝: 只复制指向某个对象的指针而不复制对象本身,新旧对象还是共享同一块内存。
Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。但是 Object.assign()进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。
深拷贝:会另外创建一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
深拷贝的实现方式
1.JSON.parse(JSON.stringify())
原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。
2.手写递归方法
递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝;
12.赋值(地址传递)和浅拷贝的区别
- 当我们把一个对象赋值给一个新的变量时,赋的其实是该对象的在栈中的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的。
- 浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。即:默认拷贝构造函数只是对对象进行浅拷贝复制(逐个成员依次拷贝),即只复制对象空间而不复制资源。
13.构造函数 和 class的区别
构造函数:
- 在 JavaScript 中,用 new 关键字来调用的函数,称为构造函数。构造函数首字母一般大写
- 功能类似对象模板,一个构造函数可以生成任意多个实例,实例对象具有相同的属性、行为特征,但不相等。
- 函数体内使用 this,引用将要生成的实例对象。
- 必需使用 new 命令调用函数,生成实例对象。
class类:
- 类不存在变量提升(hoist),
- 类的方法内部如果含有this,它默认指向类的实例,
- 类使用extends来继承,
- 类的数据类型就是函数,类本身就指向构造函数;使用的时候,也是直接对类使用new命令,跟构造函数的用法完全一致;
14.栈内存和堆内存的区别?
栈(stack):由编译器自动分配释放,存放函数的参数值,局部变量等;
堆(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由操作系统释放。
了解以下内容-不背诵
1、栈:基础变量的值是存储在栈中,而引用变量存储在栈中的是指向堆中的数组或者对象的地址,这就是为何修改引用类型总会影响到其他指向这个地址的引用变量。
优点:相比于堆来说存取速度会快,并且栈内存中的数据是可以共享的,例如同时声明了var a = 1和var b = 1,会先处理a,然后在栈中查找有没有值为1的地址,如果没有就开辟一个值为1的地址,然后a指向这个地址,当处理b时,因为值为1的地址已经开辟好了,所以b也会同样指向同一个地址。
缺点:相比于堆来说的缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
2、堆:堆内存中的对象不会随方法的结束而销毁,就算方法结束了,这个对象也可能会被其他引用变量所引用(参数传递)。创建对象是为了反复利用(因为对象的创建成本通常较大),这个对象将被保存到运行时数据区(也就是堆内存)。只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。
Ajax方面面试题
1.说一下网络模型
注:各层含义按自己理解即可
2.在浏览器地址栏键入URL,按下回车之后会经历以下流程:
1、浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
2、解析出 IP 地址后,根据该 IP 地址和默认端口80,和服务器建立TCP连接;
3、浏览器发出读取文件(URL中域名后面部分对应的文件)的HTTP请求,
该请求消息作为 TCP三次握手的第三个报文的数据发送给服务器;
4、服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器
5、释放TCP连接;
6、浏览器加载该 html 文本并显示内容;
3.什么是三次握手和四次挥手?
在网络数据传输中,传输层协议TCP(传输控制协议)是建立连接的可靠传输,TCP建立连接的过程,我们称为三次握手。
第一次,客户端向服务器发送SYN同步报文段,请求建立连接
第二次,服务器确认收到客户端的连接请求,并向客户端发送SYN同步报文,表示要向客户端建立连接
第三次,客户端收到服务器端的确认请求后,处于建立连接状态,向服务器发送确认报文
注意:
客户端是在收到确认请求后,先建立连接
服务器是在收到最后客户端的确认后,建立连接
发起连接请求的一定是客户端
在网络数据传输中,传输层协议断开连接的过程我们称为四次挥手。
第一次,A端像B端发送FIN结束报文段,准备关闭连接
第二次,B端确认A端的FIN,表示自己已经收到对方关闭连接的请求
(中间这段时间,A端停止向B端发送数据,但是B端可以向A端发送数据,要将自己未处理完任务处理完)
第三次,B端向A端发送FIN结束报文段,准备关闭连接
第四次,A端确认B端的FIN,进入TIME_WAIT状态,此时A端进程已经退出,但是连接还在
注意:
当B端收到A端的ACK之后,先断开连接
当A端等待2 MSL之后,确认的B端接收到ACK后,再断开连接
发起断开连接请求的一端最后要进入有一个TIME_WAIT状态
发起连接请求的可以是客户端也可以是服务器端
4.http协议和https协议的区别
一、传输信息安全性不同
1、http协议:是超文本传输协议,信息是明文传输。如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息。
2、https协议:是具有安全性的ssl加密传输协议,为浏览器和服务器之间的通信加密,确保数据传输的安全。
二、连接方式不同
1、http协议:http的连接很简单,是无状态的。
2、https协议:是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议。
三、端口不同
1、http协议:使用的端口是80。2、https协议:使用的端口是443.
四、证书申请方式不同
1、http协议:免费申请。2、https协议:需要到ca申请证书,一般免费证书很少,需要交费。
5.http常见状态码有哪些?
注意
1XX :信息状态码 2XX :成功状态码 3XX :重定向 4XX :客户端错误 5XX: 服务器错误
100 信息服务器收到请求,需要请求者继续执行操作
200 (成功) 服务器已成功处理了请求。
301 表示永久性重定向。
302 表示临时性重定向。
303 临时性重定向,且总是使⽤ GET 请求新的 URI
304 (未修改) 自从上次请求后,请求的网页未修改过。
400 (错误请求) 服务器不理解请求的语法。
403 (禁止) 服务器拒绝请求。
404 (未找到) 服务器找不到请求的网页。
405 (not allowed)请求不允许
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
503 表示服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
6.GET和POST的区别,何时使用POST?
- 代码上的区别
1:get通过url传递参数。
2:post参数在请求体中,发送ajax请求时post设置请求头 ,规定请求数据类型。 - 使用上的区别
1:post比get安全
(因为post参数在请求体中。get参数在url上面)
2:get传输速度比post快 根据传参决定的。
(post通过请求体传参,后台通过数据流接收。速度稍微慢一些。而get通过url传参可以直接获取)。
3:post传输文件大,理论上是没有限制 ;get传输文件小,一般不大于2k。
4:get一般用于获取数据,post上传数据(上传的数据比较多, 而且上传数据都是重要数据。所以不论在安全性还是数据量级post是最好的选择)。
5.get请求可以被缓存,post不可以被缓存。
7.JSON是什么?JSON和JavaScript普通对象有什么区别?如何把JS对象转化为JSON字符串,又如何把JSON字符串转化为JavaScript对象?
- JSON (JavaScript Object Notation)一种简单的数据格式,比xml更轻巧。JSON的规则很简单: 对象是一个无序的“名称/值”对集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“名称/值”对之间使用“,”(逗号)分隔。 它是一种严格的js对象的格式,JSON的属性名必须有双引号,如果值是字符串,也必须是双引号;
- Javascript 普通对象:一种javascript的引用类型, 可允许加单引号,双引号
- JSON.stringify() 和 JSON.parse()相互转换.
8.什么是ajax?ajax作用是什么?
AJAX 是异步 JavaScript 和 XML, 向服务器发送数据请求,AJAX可以无需重新页面,异步的使网页实现局部的更新。
9.为什么要用ajax?
ajax应用程序的优势在于:
- 通过异步模式,提升了用户体验。
- 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用。
- Ajax引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载。
ajax的缺点:
- ajax干掉了back按钮,即对浏览器后退机制的破坏。
- 开发者在不经意间会暴露比以前更多的数据和服务器逻辑。
- 对搜索引擎的支持比较弱。
- 破坏了程序的异常机制。
10.ajax最大的特点是什么?
Ajax可以实现动态不刷新(局部刷新) 就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变过的信息。
11.请介绍一下XMLHttprequest对象。
Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer 5中首次引入,它是一种支持异步请求的技术。简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不阻塞用户。通过XMLHttpRequest对象,Web开发人员可以在页面加载以后进行页面的局部更新。
12.原生js ajax请求有几个步骤?分别是什么?
//创建 XMLHttpRequest 对象
var ajax = new XMLHttpRequest();
//规定请求的类型、URL 以及是否异步处理请求。
ajax.open('GET',url,true);
//发送信息至服务器时内容编码类型
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//发送请求
ajax.send(null);
//接受服务器响应数据
ajax.onreadystatechange = function () {
if (obj.readyState == 4 && (obj.status == 200 || obj.status == 304)) {
// 代码块
}
}
13.什么是跨域? 如何解决跨域?
跨域是违背同源策略就会产生跨域。
要说跨域,首先得说同源策略
同源策略 :是浏览器的安全策略,协议名、域名、端口号必须完全一致。
解决跨域的方法:
vue代理配置 nginx代理配置 后端设置 jsonp(前后端配合)
14.什么是JSONP?原理是什么,缺点是什么?
JSONP(JSON with Padding) ,利用script标签本来就具备的跨域请求功能,请求后台接口地址,来完成数据请求的,这种跨域的通讯方式称为JSONP。
JSONP的原理 : 利用script标签可以获取不同源资源的特点,来达到跨域访问某个资源的目的。
缺点:
1、JSONP只支持GET请求,不支持POST等其它类型的HTTP请求
2、JSONP只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
3、JSONP在调用失败的时候不会返回各种HTTP状态码。
4、JSONP本质上是加载了其他网站的脚本,这种方式存在安全风险。
15.XML与JSON的区别?
1、JSON是JavaScript Object Notation;XML是可扩展标记语言。
2、JSON是一种表示对象的方式;XML是一种标记语言,使用标记结构来表示数据项。
3、JSON仅支持UTF-8编码;XML支持各种编码。
4、JSON支持数组;XML不支持数组。
5、JSON不支持注释;XML支持注释。
ES6新特性
1.var,let,const的区别
- 使用 var 声明的变量,其作用域为全局作用域或者为所在的函数内局部作用域,且存在变量提升现象
- 使用 let 声明的变量,其作用域为该语句所在的代码块内{},不存在变量提升
- 使用 const 声明的是常量,在后面出现的代码中不能再修改该常量的值
2.说说你对数组的解构和对象的解构的理解?
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
具体自己举例说明
3.ES6的新语法
- let和const
- 解构赋值,数组和对象的解构
- 剩余及扩展运算符...
- Symbol基本数据类型
- Map和Set对象
- proxy代理和reflect映射
- 模板字符串
- 箭头函数
- 迭代器iterator
- Promise async await
- ES6模块化-export-import
4.Map对象和Set对象的区别
- Map是键值对,当然键和值可以是任何的值;Set是值的集合,
- Map可以通过get方法获取值,而Set不能因为它只有值;
- Map由于没有格式限制,可以做数据存储,Set的值是唯一的可以做数组去重,
5.Set实现数组去重
第一种数组去重方法(使用Array.from):
let arr = [12,43,23,43,68,12];
let item = new Set(arr);
console.log(item);//结果输出的是一个对象
//使用Array.from转成数组
let arr = [12,43,23,43,68,12];
let item = Array.from(new Set(arr));
console.log(item);// [12, 43, 23, 68]
第二种数组去重方法(使用...扩展运算符):
let arr = [12,43,23,43,68,12];
let item = [...new Set(arr)];
console.log(item);//[12, 43, 23, 68]
6.使用箭头函数应注意什么?
- 箭头函数本身没有this,它的this指向父级上下文
- 箭头函数内部没有arguments对象,可以使用rest参数代替
- 不能用作构造函数,这就是说不能够使用new命令,否则会抛出一个错误
- 没有propotype原型属性
7.什么是Promise?
什么是Promise?
- promise是异步编程的一种解决方法。
- 所谓promise,简单说是一个容器,里面保存着一个异步操作的结果,从语法上说,promise是一个对象,从它可以获取异步操作的消息,promise提供了统一的API,各种异步操作都可以用同样的方法进行处理。
- 比传统的解决方案——回调函数和事件——更合理且更强大。
Promise的用途?
- 主要用于异步计算
- 可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果,所以promise链式调用解决回调地狱。
8.理解 async/await以及对Generator的优势
- async await 是用来解决异步的,async函数是Generator函数的语法糖
- 使用关键字async来表示,在函数内部使用 await 来表示异步
- async函数返回一个 Promise 对象,可以使用then方法添加回调函数
- 当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句
9.Promise 和 async/await的区别
promise和 async/await都是解决异步编程的一种方式,但是async/await使得异步代码看起来像同步代码。
函数前面多了一个async关键字。await关键字只能用于async定于的函数内。async函数会隐式地返回一个Promise,该promise的resolve值就是return的值。
10.说说js的异步编程的解决方案
- JS 异步编程进化史:callback -> promise -> generator -> async + await
- async/await 函数的实现,就是将 Generator 函数和自动执行器,包装在一个函数里。
- async/await可以说是异步终极解决方案了。
11.前端性能优化相关理解
- 减少http请求,合理浏览器缓存。
- 启用压缩:HTML、CSS、javascript文件启用GZip压缩可达到较好的效果。
- CSS Sprites:合并 CSS图片,减少请求数的又一个好办法。
- LazyLoad Images:在页面刚加载的时候可以只加载第一屏,当用户继续往后滚屏的时候才加载后续的图片。
- CSS放在页面最上部,javascript放在页面最下面:让浏览器尽快下载CSS渲染页面。
- 异步请求Callback(就是将一些行为样式提取出来,慢慢的加载信息的内容)。
- Javascript代码优化。
12.什么是事件循环loop?什么是宏观任务和微观任务(宏队列和微队列)
1.事件循环 Event Loop
既然js是单线程,那么js任务就要一个一个顺序执行。如果一个任务耗时过长,那么后一个任务也必须等着。那么问题来了,假如我们想浏览新闻,但是新闻包含的超清图片加载很慢,难道我们的网页要一直卡着直到图片完全显示出来?当然不需要,js任务分为两类:
同步任务
异步任务
当我们打开网站时,网页的渲染过程就是一大堆同步任务,比如页面骨架和页面元素的渲染。而像加载图片视频之类占用资源大耗时久的任务,就是异步任务。
上述图片包含了几个知识点:
同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
当指定的事情完成时,Event Table会将这个函数移入Event Queue (事件队列)。
主线程执行栈的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
上述过程会不断重复,也就是常说的Event Loop(事件循环)。
2.能发起宏观任务的方法有:
script(同步代码)、setTimeout、setInterval、I/O、UI交互事件
3.微观任务的方法有:
- Promise.then,
- process.nextTick(Node.js 环境),
- async/await(实际上是promise+generator的语法糖,也就是promise,也就是微观任务);
4.执行顺序
<script>整体代码可看作宏任务
JS是单线程,碰见同步执行同步直到执行完毕,遇到异步放到执行队列中去,异步包括宏任务和微任务,在异步中微任务是优于宏任务执行的。
13.web安全及防护
1.XSS攻击原理(跨站脚本攻击):
攻击者往Web页面里插入恶意 html标签或者javascript代码。
用来窃取cookie中的用户信息
解决:对一些输入的字符进行过滤,尽量采用post表单提交的方式。
2.CSRF攻击(跨站请求伪造):
登录受信任的网站A,并在本地生成Cookie,在不登出A的情况下,携带cookie去访问危险网站B
解决:通过验证码的方式解决
3.SQL注入攻击
就是通过吧SQL命令插入到Web表单递交或输入域名,最终达到欺骗服务器执行恶意的SQL命令。
解决:表单输入时通过正则表达式将一些特殊字符进行转换
14.如何理解HTTP协议是无状态的,如何让其有状态
http协议呢,是一种超文本传输协议,而为什么说http协议是无状态的呢,是因为当浏览器第一次发送数据给服务器时,服务器响应了;如果同一浏览器,向服务器第二次发送请求时,它还是会响应,但服务器并不知道你就是刚才那个浏览器。简而言之,服务器是不会记住你是谁的,所以是无状态的。
而如果要使http协议有状态,就可以使浏览器访问服务器时,加入cookie,session或者token这样解决方案,帮助服务器记录,服务器就能够通过记录知道,你就是之前那个浏览器,这样的话,http协议就有状态了。