面试常见问题(js)

1)get和post请求的区别

get的参数通过URL传递,post的参数是放在Request Body中。

get的参数通过URL是有长度限制的,post没有。

get请求更危险,因为它直接暴露在URL上。

get参数请求会完整的记录在浏览器历史记录里面,而post请求参数不会被保留。

get请求只能进行url编码,而post请求支持多种编码方式。

get请求浏览器会主动cache,post不会,除非手动设置。

总的来说,get和post本质上就是TCP链接,但是由于HTTP的规定和浏览器/服务器的限制,导致它们在应用过程中体现出一些不同。对于get方式的请求,浏览器会把http header和data一并发送出去,服务器响应200,即返回数据,而对于post,浏览器先发送header,服务器响应100,continue,浏览器在发送data,服务器响应200,即返回数据。在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本没有,而在网络环境差的情况下,两次包的TCP在验证数据包完整性下,有非常大的优点。

2)http method有哪些

安全方法

HTTP定义了一组被称为安全方法的方法。get方法和head方法都被认为是安全的,这就意味着使用ge或head方法的HTTP请求都不会产生动作。安全方法并不一定什么动作都不执行(由开发者决定),使用安全方法的目的是当使用可能引发某一动作的不安全方法时,运行HTTP应用程序开发者通知用户。

get方法

通常用于请求服务器发送某个资源。

head方法

head方法与get方法的行为类似,但服务器在响应中只返回首部。不会反回实体的主体部分。使用head,可以在不获取资源的情况下,了解资源的情况,通过查看响应中的状态码,看看某个对象是否存在,通过查看首部,测试是否被修改,服务器开发者必须确保返回的首部与get请求返回的首部完全相同

put方法

与get方法从服务器读取文档相反,put方法会向服务器写入文档。有些发布系统允许用户创建web页面,并用PUT直接将其安装到web服务器上。

post方法

post方法起初是用来向服务器写入数据的。实际通常会用它来支持HTML的表单。表单中填好的数据通常会被发送给服务器,然后服务器将其发送到他要去的地方。

trace方法

trace方法只要用于诊断,允许客户端在最终将请求发送给服务器时,看看他变成什么样子。trance请求最终会在目的服务器发起一个回环诊断,行程最后一战的服务器会回弹一条trance响应,并在响应主题中携带它收到的原始请求报文。这样客户端就可以查看在所有中间HTTP程序组成的响应链上,原始报文是否以及如何被毁坏或修改过。中间应用程序会自行决定对trance请求的处理方式,trance请求不能带有实体的主题部分。trance响应的实体主体部分包含了响应服务器收到的请求精确副本。

option方法

option方法请求web服务器告知其支持的各种功能。可以询问服务器通常支持那些方法,或者对某些特殊资源支持哪些方法。使用option方法的请求和响应示例:

请求报文

OPTIONS http://www.cnivi.com.cn/ HTTP/1.1

Accept-Encoding: gzip,deflate

Host: www.cnivi.com.cn

Connection: Keep-Alive

User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

响应报文

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH

Content-Length: 0

Date: Thu, 09 Oct 2014 04:20:09 GMT

delete方法

delete方法所做的事情就是请服务器删除请求URL所指定的资源。但是客户端应用程序无法保证删除操作一定会执行。因为HTTP规范允许服务器在不通知客户端的情况下撤销请求。

lock方法

允许用户锁定资源,比如可以再编辑某个资源时将其锁定,以防别人同时对其进行编辑。

mkcol方法

允许用户创建资源

copy方法

便于用户在服务器上复制资源

move方法

在服务器上移动资源

3)es6变量的解构赋值

按照一定的模式,从数组和对象中提取值,对变量进行赋值,这就是解构。

数组的解构赋值

let[foo,[[bar],baz]]=[1,[[2],3]];foo // 1bar // 2baz // 3

注意,如果等号的右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错。

// 报错let[foo]=1;let[foo]=false;let[foo]=NaN;let[foo]=undefined;let[foo]=null;let[foo]={};

注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

let[x=1]=[undefined];x // 1let[x=1]=[null];x // null

对象的解构赋值

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

let{bar,foo}={foo:"aaa",bar:"bbb"};foo // "aaa"bar // "bbb"let{baz}={foo:"aaa",bar:"bbb"};baz // undefined

字符串解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

const [a, b, c, d, e]='hello';a // "h"b // "e"c // "l"d // "l"e // "o"

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

let {length: len}='hello';len // 5

数值和布尔型解构赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

let {toString: s}=123;s===Number.prototype.toString // truelet{toString:s}=true;s===Boolean.prototype.toString // true

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

let{prop:x}=undefined; // TypeErrorlet{prop:y}=null; // TypeError

函数参数的解构赋值

函数的参数也可以使用解构赋值。

[[1,2],[3,4]].map(([a,b])=>a+b);// [ 3, 7 ]

function add([x, y]){  return x + y;}add([1, 2]); // 3

4)什么是闭包,闭包的作用是什么?

闭包就是能够读取其他函数内部变量的函数,另一个就是让变量的值始终保持在内存当中,不会因为被调用后自动清除。

var f1 = function(){

        var a=1;

        return function f2(){

            a++;

            console.log(a);

        }

    }

    var b = f1();

    b();            // 2

    b();            // 3


5)客户端存储localstorage和sessionstorage的区别

localstorage的生命周期是永久,sessionstorage生命周期为当前窗口或者标签页,一旦窗口或者标签页被关闭了,那么通过sessionstorage存储的数据也会被清空。

6)JavaScript有哪几种方法定义函数

函数有三种定义方法,函数定义语句,函数直接量表达式和function()构造函数。

函数定义语句

function sum(a, b){

  return a+b;

}

函数直接量表达式

//求阶乘的函数

var factorial = function fact(x){  //将函数赋值给一个变量

    if(x<0) {return NaN;}

    else if(x===0) {return 1;}

    else

    return x*fact(x-1);    //递归函数

};

console.log(factorial(3));

function()构造函数

var f =new Function("x","y","return x+y");//Function()构造函数

var f =function(x, y){return x+y};

7)如何判断一个对象是否为函数

调用object原声方法不存在兼容问题,可以用typeof,但是存在浏览器兼容问题。

Object.propotype.toString.call(object) === "[object Function]"

8)编写JavaScript深度克隆函数

function clone(obj) {

  var o = obj instanceof Array ? [] : {};

  for(var k in obj)

    o[k] = typeof obj[k] === Object ? clone(obj[k]) : obj[k];

  return o;

}

var a = [[1, 2, 3], [4, 5, 6, 7]];

var b = clone(a);

console.log(b);

9)什么是虚拟dom,为什么使用虚拟dom?

  可以看作使用JavaScript模拟了DOM结构的树形结构,这个树结构包含整个DOM结构的信息。VDOM将DOM的对比放在js层,通过对比不同之处来选择新渲染的DOM节点,从而提高渲染效率。

10)jsonp的优缺点

优点:

jsonp可以跨越同源策略,兼容性很好,请求完毕后可以通过调用callback的方式回传结果。

缺点:

支持get请求,只支持跨域http请求,在调用失败的时候不会返回各种http状态码,不够安全,存在页面注入漏洞。

11)React组件的生命周期函数

一.初始化阶段:

getDefaultProps:获取实例的默认属性

getInitialState:获取每个实例的初始状态

componentWillMount:组件即将被装载,渲染到页面上

render:组件在这里生成虚拟dom节点

componentDidMount:组件在被装载之后

二.运行中:

componentWillReceiveProps:组件将要接收到属性的时候调用

shouldComponentUpdate:组件在接收到新属性或者新状态的时候

componentWillUpdate:组件即将更新不能修改属性和状态

render:组件重新描绘

componentDidUpdate:组件已经更新

三.销毁阶段:

componentWillUnmount:组件即将销毁

12)es6数据类型

Number,String, Null, Undefined, Symbol, Boolean

13)什么是事件委托,有什么作用?

  事件委托也叫事件代理,事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。在js中,添加到页面上的事件处理程序数量将直接关系到页面整体运行性能,因为需要不断与dom节点进行交互,访问dom的次数越多,引起浏览器重回与重排的次数也就越多,就会延长整个页面的交互就绪时间。,使用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需一次,这样就能大大的减少与dom的交互次数,提高性能。

14)什么是事件冒泡?如何阻止事件冒泡?

事件冒泡就是从目标对象到外层的顺序触发。

    阻止事件的传播:在W3C中,使用stopPropagation()方法,在IE下设置cancelBubble = true;

阻止事件的默认行为:在W3C中,使用preventDefault()方法,在IE下设置window.event.returnValue = false;

15)什么是async函数,有什么作用?

async函数是Generator函数的语法糖。async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

16)HTML5的离线存储怎么使用,工作原理能不能解释一下?

原理:HTML5的离线存储是基于一个新建的.appcache文件的缓存机制,通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样存储下来。之后当网络处于离线状态下时,浏览器会通过离线存储的数据进行页面展示。

使用:在页面头像加入一个manifest的属性,在cache.manifest文件的编写离线存储资源,在离线状态时,操作window.applicationCache进行需求实现

16)你是如何划分react组件

通常是根据组件的指责来划分为UI组件和容器组件,UI组件复杂UI的呈现,容器组件负责管理数据和逻辑的。

17)react性能优化是哪个周期函数,react性能优化方案?

shouldComponentUpdate这个方法用来判断是否需要调用render方法重新描绘dom。因为dom的描绘非常消耗性能,如果我们能在shouldComponentUpdate方法中能够写出更优化的dom diff算法,可以极大的提高性能。

优化方案:重写shouldComponentUpdate来避免不必要的dom操作,使用production版本的react.js,使用key来帮助react识别列表中所有子组件的最小变化。

18)说说前端中的事件流

HTML中的javascript交互是通过事件驱动来实现,事件流描述的是从页面中接受事件的顺序,dom级事件流包括下面几个阶段。

事件捕获阶段

处于目标阶段

事件冒泡阶段

19)js的new操作符的作用

new操作符新建了一个控对象,这个对象原型指向构造函数的prototype,执行构造函数后返回这个对象。

20)bind,apply,call改变函数内部this的指向的区别。

1>通过apply和call改变函数的this指向,他们两个函数的第一个参数都是一样的,表示要改变指向的那个对象,第二个参数,apply是数组,而call则是arg1,arg2...这种形式

2>通过bind改变this作用域会返回一个新的函数,这个函数不会马上执行。



后续会继续更新

你可能感兴趣的:(面试常见问题(js))