阅读 34

网易前端面试题

前端面试题总结 - 去土耳其啊的文章 - 知乎 https://zhuanlan.zhihu.com/p/83252221

1、浏览器本地存储?

2、web storage和cookie的区别

3.请描述一下 cookies、 sessionStorage和localstorage区别?

4、常见的HTTP状态码?(后面ajax请求会写到)

5、bootstrap响应式实现的原理?

百分比布局+媒体查询

6、Vue请求数据的方式:

Vue-resource,Axios,fetch三种方式.

Vue-resource方式:vue自身不带处理http请求,如果要使用http请求,必须先要引入vue-resource.js库,它可以通过XMLHttpRequest发起请求并处理响应.类似于jQuery

get类型语法:
    this.$http.get('url',{params:{key1:val1,key2:val2...}}).then((ok)=>{
        console.log(ok);
    },(err)=>{
        console.log(err);
    })
    
post类型语法:
    this.$http.post('url',{key1:val1,key2:val2…},{emulateJSON:true}).
	then((ok)=>{
         console.log(ok)
    },(err){
        console.log(err)
    })复制代码

Axios的方式:

Axios是第三方插件,不仅能在vue中使用,还能在其他第三方库中使用,例如react

get类型:
     axios.get("http://localhost:3000/get?uname=abc").then((ok) => {
                    console.log(ok);
                }).catch((err) => {
                    console.log(err);
     })//传值方式为在url后拼接 ? 加 key=val


post类型:
     var param = new URLSearchParams(); //改变发送数据的方式
                // 设置发送数据的内容
                param.append("uname", "szcszc");
                axios.post("http://localhost:3000/post", param).then((ok) => {
                    console.log(ok);
                }).catch((err) => {
                    console.log(err);
                })
   在post传值时,如果直接将值像get那样传递的话后端是无法收到的,因为ajax收到值的类型是form data格式,
   而Axios在发送数据的时候使用的方式是request payload格式
   所以后台无法正常接收,解决方法是使用URLSearchParams对象修改操作 URL传递参数的方法 


综合写法:
     // axios的综合写法
                // 既可以是get也可以是post
                axios({
                    url: "http://localhost:3000/get?uname=sss", //get发送数据方式1
                    // param:{uname:"zzz"}  get发送数据方式2
                    methods: "get"
                }).then((ok) => {
                    console.log(ok);
                })


                //post的写法
                var param = new URLSearchParams();
                param.append("uname", this.text);
                axios({
                    url: "http://localhost:3000/post",
                    method: "post",
                    // post发送数据的时候使用data属性
                    data: param
                }).then((ok) => {
                    console.log(ok);
                })          复制代码

7、如何优化页面,加快页面的加载速度(面五次有一次问到的概率)

(1)优化图片格式和大小;

(2)开启网络压缩;

(3)使用浏览器缓存;

(4)减少重定向请求;

(5)使用CDN存储静态资源;

(6)减少DNS查询次数;

(7)压缩css和js内容;

8、评测你写的前端代码性能和效率?(问到一次)

A: Chtome DevTools 的Timeline:排查应用性能的最佳工具。

B: Chtome DevTools 的Audits:对页面性能进行检测,根据测试结果进行优化。

C:第三方工具:Yslow。

9、iframe的优缺点?(问到一次)

1.<iframe>优点: *解决加载缓慢的第三方内容如图标和广告等的加载问题

*Security sandbox

*并行加载脚本

2.<iframe>的缺点: *iframe会阻塞主页面的Onload事件;

*即时内容为空,加载也需要时间

*没有语意

10、Http与Https的区别

  • HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
  • HTTP 是不安全的,而 HTTPS 是安全的
  • HTTP 标准端口是80 ,而 HTTPS 的标准端口是443
  • 在OSI 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
  • HTTP 无法加密,而HTTPS 对传输的数据进行加密
  • HTTP无需证书,而HTTPS 需要CA机构wosign的颁发的

11、vuex的属性

  1. state:声明定义数据
  2. getters:存放有依赖关系的数据,类似于computed计算属性
  3. mutation:同步的修改state中的数据
  4. actions:异步修改数据
  5. modules:让每一个模块都有自己的state,getters,mutation,actions

12、vue双向绑定的原理

Vue实现双向绑定的原理就是利用了Object.defineProperty()这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。

13、h5新标签

video 表示一段视频并提供播放的用户界面

audio 表示音频

canvas 表示位图区域

source 为video和audio提供数据源

track 为video和audio指定字母

svg 定义矢量图

code 代码段

figure 和文档有关的图例

figcaption 图例的说明

main www.w3school.com.cn/tags/tag_ma…

time 日期和时间值

mark 高亮的引用文字

datalist 提供给其他控件的预定义选项

keygen 秘钥对生成器控件

output 计算值

progress 进度条

embed 嵌入的外部资源

menuitem 用户可点击的菜单项

menu 菜单

section

nav <nav> 标签定义导航链接的部分。

aside :<aside> 的内容可用作文章的侧栏。

article 标签规定独立的自包含内容。

footer

14、vue全家桶:

  1. Vue-cli项目构建工具
  2. vue-router 路由
  3. vuex状态管理
  4. axios http 请求工具
  5. webpack

15、MVVM思想:Vue.js是一套构建用户界面的MVVM框架

MVVM分为三部分:分别是M(model,模型层),V(View,视图层),VM(ViewModel,V与M连接的桥梁,也可以看做为控制器MVC的C层)

  1. M:模型层,主要负责业务数据相关
  2. V:视图层,负责视图相关,主要是HTML+CSS
  3. VM:V与M沟通的桥梁,负责监听M或V的修改,是实现MVVM双向绑定的要点;因此开发者只需要关注业务逻辑,不需要手动操作DOM,不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM来统一管理.

MVP思想:MVP的全称为Model-View-Presenter,Model提供数据,View负责显示,Presenter负责逻辑的处理

MVP与MVC的最大的区别:在MVP中View并不直接使用Model,它们之间的通信数据是通过Presenter来进行的,而在MVc中View会直接从Model中读取数据而不是通过Controller

Vue数据驱动:通过控制数据的变化来显示Vue的数据驱动,是视图的内容随着数据的改变而改变


16、合并数组的方法

  • concat
var a = [1,2,3]
var b = [4,5,6]
var c = a.concat(b)  //c = [1,2,3,4,5,6]复制代码
  • apply
var a = [1,2,3]
var b = [4,5,6]
var c = a.push.apply(a,b)复制代码
  1. 数组合并去重
let arr1 = [1,2,3]
let arr2 = [2,3,4]
let arr = arr1.concat(arr2) //合并数组
let arrNew = new Set(arr)  //通过set集合去重
Array.from(arrNew)  //将set集合转化为数组//call的实现思路
Function.prototype.myCall = function (context){
  if (typeof this !== 'function') {
     throw new TypeError('Error')
  }
  var context = context || window
  //给context添加一个属性
  context.fn = this
  //通过参数伪数组将context后面的参数取出来
  var args = [...arguments].slice(1)
  var result = context.fn(...args)
  //删除 fn
  delete context.fn
  return result
}复制代码


17、垂直居中的方式

  • absolute+transform:绝对定位+转换
.parent {  
        position: relative;
}
.child {  
        position: absolute;  
        left: 50%;  
        rigth: 50%;  
        transfrom: translate(-50%,-50%) 
}复制代码
  • flex + justify-content + align-items
.parent {  
           display: flex;  
           justify-content: center; //水平居中  
           align-items: center; //垂直居中 
}复制代码


18、call,apply,bind的区别

  1. call和apply都是为了解决改变this的指向。作用都相同,只是传参的方式不同。除了第一个参数外,call可以接受一个参数的列表,apply只接受一个参数的数组

call的实现思路

Function.prototype.myCall = function (context){ 
if (typeof this !== 'function') { 
    throw new TypeError('Error') 
}
var context = context || window
//给context添加一个属性 
context.fn = this 
//通过参数伪数组将context后面的参数取出来 
var args = [...arguments].slice(1) 
var result = context.fn(...args) 
//删除 fn 
delete context.fn return result 
}复制代码

apply的实现思路

//apply的实现思路
Function.prototype.myApply = function (context) {
    if (typeof this !== 'function') {
     throw new TypeError('Error')
  }
    var context = context || window
    //为context添加一个属性
    context.fn = this
    var result 
    //判断是否存在第二个参数
    //如果存在就将第二个参数也展开
    if(arguments[1]) {
        result = context.fn(...arguments[1])
    } else {
        result = context.fn()
    }
    delete context.fn
    return result
}复制代码

bind的实现思路:bind返回了一个函数,对于函数来说有两种调用方式,一种是直接的调用,一种是通过new的方式

Function.prototype.myBind = function (context) {
    if (typeof this !== 'function') {
        throw new TypeError('Error')
    }
    const _this = this 
    const args = [...arguments].slice(1)
    //返回一个函数
    return function F () {
        if (this instanceof F) {
            return new _this(...args, ...arguments)
        }
        return _this.apply(context,args.concat(...arguments))
    }
}复制代码

19、使用axios?

vue是虚拟DOM操作的,JQuery.ajax和都需要操作DOM,axios本身就可以解决回调地狱的问题

20、new操作的过程

1. 新生成了一个对象

2. 链接到原型

3. 绑定this

4. 返回新对象 其实我们完全可以自己实现一个new的过程

function createNew() {
  let obj  = {}
  let Sunday  = [].shift.call(arguments)
  obj.__proto__ = Sunday.prototype
  let result = Sunday.apply(obj,arguments)
  return result instanceof Object ? result : obj
}复制代码


21、vuex原理

vuex的原理其实非常简单,它为什么能实现所有的组件共享同一份数据?

因为vuex生成了一个store实例,并且把这个实例挂在了所有的组件上,所有的组件引用的都是同一个store实例。

store实例上有数据,有方法,方法改变的都是store实例上的数据。由于其他组件引用的是同样的实例,所以一个组件改变了store上的数据,

导致另一个组件上的数据也会改变,就像是一个对象的引用。

22、vue怎么实现页面的权限控制

利用 vue-routerbeforeEach 事件,可以在跳转页面前判断用户的权限(利用 cookie 或 token),是否能够进入此页面,如果不能则提示错误或重定向到其他页面,在后台管理系统中这种场景经常能遇到。

23、真实DOM和虚拟DOM的区别

虚拟DOM不会进行排版与重绘操作

真实DOM频繁排版与重绘的效率是相当低

虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分,最后并在真实DOM中进行排版与重绘,减少过多DOM节点排版与重绘损耗

虚拟DOM有效降低的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部


24、跨域(概率90%,此问题想到一位奇葩的面试官,记忆犹新!)

  1. JSONP

// jsonp的原理很简单,就是利用 <script> 标签没有跨域的限制的漏洞。当需要通讯时,通过 <script> 标签指向一个需要访问的地址,并提供一个回调函数来接收数据。

// JSONP使用简单并且兼容性不错,但是只限于get请求

核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。

①原生实现:

<script src="http://test.com/data.php?callback=dosomething"></script>
// 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字
 
// 处理服务器返回回调函数的数据
<script type="text/javascript">
    function dosomething(res){
        // 处理获得的数据
        console.log(res.data)
    }
</script>复制代码

② jQuery ajax:

$.ajax({
    url: 'http://www.test.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 请求方式为jsonp
    jsonpCallback: "handleCallback",    // 自定义回调函数名
    data: {}
});复制代码

③ Vue.js

this.$http.jsonp('http://www.domain2.com:8080/login', {
    params: {},
    jsonp: 'handleCallback'
}).then((res) => {
    console.log(res); 
})复制代码

2、CORS

CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。

1、普通跨域请求:只需服务器端设置Access-Control-Allow-Origin

2、带cookie跨域请求:前后端都需要进行设置

【前端设置】根据xhr.withCredentials字段判断是否带有cookie

①原生ajax

var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
 
// 前端设置是否带cookie
xhr.withCredentials = true;
 
xhr.open('post', 'http://www.domain2.com:8080/login', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=admin');
 
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
        alert(xhr.responseText);
    }
};
 复制代码

② jQuery ajax

$.ajax({
   url: 'http://www.test.com:8080/login',
   type: 'get',
   data: {},
   xhrFields: {
       withCredentials: true    // 前端设置是否带cookie
   },
   crossDomain: true,   // 会让请求头中包含跨域的额外信息,但不会含cookie
});
 复制代码

③vue-resource

Vue.http.options.credentials = true复制代码

④ axios

axios.defaults.withCredentials = true复制代码

3、设置document.domain解决无法读取非同源网页的 Cookie问题

浏览器是通过document.domain属性来检查两个页面是否同源,因此只要通过设置相同的document.domain,两个页面就可以共享Cookie(此方案仅限主域相同,子域不同的跨域应用场景。)

// 两个页面都设置
document.domain = 'test.com';复制代码

4、跨文档通信 API:window.postMessage()

调用postMessage方法实现父窗口test1.com向子窗口test2.com发消息(子窗口同样可以通过该方法发送消息给父窗口)

它可用于解决以下方面的问题:

  • 页面和其打开的新窗口的数据传递
  • 多窗口之间消息传递
  • 页面与嵌套的iframe消息传递

上面三个场景的跨域数据传递

// 父窗口打开一个子窗口
var openWindow = window.open('http://test2.com', 'title');
 
// 父窗口向子窗口发消息(第一个参数代表发送的内容,第二个参数代表接收消息窗口的url)
openWindow.postMessage('Nice to meet you!', 'http://test2.com');复制代码

调用message事件,监听对方发送的消息

// 监听 message 消息
window.addEventListener('message', function (e) {
  console.log(e.source); // e.source 发送消息的窗口
  console.log(e.origin); // e.origin 消息发向的网址
  console.log(e.data);   // e.data   发送的消息
},false);复制代码

25、请简述JavaScript中的this。

函数的调用方式决定了this的值。

this取值符合以下规则:

1、在调用函数时使用new关键字,函数内的this是一个全新的对象。

2、如果apply、call或bind方法用于调用、创建一个函数,函数内的 this 就是作为参数传入这些方法的对象。

3、当函数作为对象里的方法被调用时,函数内的this是调用该函数的对象。比如当obj.method()被调用时,函数内的 this 将绑定到obj对象。

4、如果调用函数不符合上述规则,那么this的值指向全局对象(global object)。浏览器环境下this的值指向window对象,但是在严格模式下('use strict'),this的值为undefined。

5、如果符合上述多个规则,则较高的规则(1 号最高,4 号最低)将决定this的值。

6、如果该函数是 ES2015 中的箭头函数,将忽略上面的所有规则,this被设置为它被创建时的上下文。


26、JS哪些操作会造成内存泄露

1)意外的全局变量引起的内存泄露

function leak(){  

  leak="xxx";//leak成为一个全局变量,不会被回收  

}复制代码

2)闭包引起的内存泄露

3)没有清理的DOM元素引用

4)被遗忘的定时器或者回调

5)子元素存在引起的内存泄露

27、如何确定this指向

如果要判断一个运行中函数的 this 绑定,就需要找到这个函数的直接调用位置。找到之后就可以顺序应用下面这四条规则来判断 this 的绑定对象。

1、由 new 调用?绑定到新创建的对象。

2、由 call 或者 apply (或者 bind )调用?绑定到指定的对象。

3、由上下文对象调用?绑定到那个上下文对象。

4、默认:在严格模式下绑定到 undefined ,否则绑定到全局对象。

一定要注意,有些调用可能在无意中使用默认绑定规则。如果想“更安全”地忽略 this 绑定,你可以使用一个 DMZ 对象,比如 ø = Object.create(null) ,以保护全局对象。


ES6 中的箭头函数并不会使用四条标准的绑定规则,而是根据当前的词法作用域来决定this ,具体来说,箭头函数会继承外层函数调用的 this 绑定(无论 this 绑定到什么)。这其实和 ES6 之前代码中的 self = this 机制一样


28、箭头函数和普通函数有什么区别

  • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象,用call applybind也不能改变this指向
  • 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
  • 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
  • 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
  • 箭头函数没有原型对象prototype


29、闭包

闭包是指有权访问另外一个函数作用域中的变量的函数.可以理解为(能够读取其他函数内部变量的函数)

闭包的作用: 正常函数执行完毕后,里面声明的变量被垃圾回收处理掉,但是闭包可以让作用域里的变量,在函数执行完之后依旧保持没有被垃圾回收处理掉


.闭包的缺陷

闭包会导致内存占用过高,因为变量都没有释放内存

闭包的用途:

1.读取函数内部的变量

2.让变量始终保持在内存中,延长变量的生命周期

闭包形成原因?

30、如何实现原型继承?

先更改子类的原型prototype指向一个New父类()对象。

子类.prototype = new 父类()

再给子类的原型设置一个constructor指向子类

子类.prototype.constructor = 子类

// 人类 → 父类
 function Person() {
   this.name = '名字';
   this.age = 10;
   this.gender = '男';
 }
 Person.prototype.sayHi = function () { console.log('你好'); };
 Person.prototype.eat = function () { console.log('我会吃。。。'); };
 Person.prototype.play = function () { console.log('我会玩'); };


 // 学生类 → 子类
 function Student() {
   this.stuId = 1000;
 }
 // 子类的原型prototyp指向父类的一个实例对象
 Student.prototype = new Person();
 // 添加一个constructor成员
 Student.prototype.constructor = Student;

 // 如何实现原型继承:
 // 给子类的原型prototype重新赋值为父类的一个实例对象。
 // 利用了原型链上属性或方法的查找规则。


 // 创建一个学生对象
 var stu1 = new Student();
 console.log(stu1.constructor)复制代码

class继承

  • 在es6中可以使用class去实现继承,并且实现起来很简单
class Parent {
  constructor(value) {
    this.val = value
  }
  getValue() {
    console.log(this.val)
  }
}
class Child extends Parent {
  constructor(value) {
    super(value)
    this.val = value
  }
}
let child = new Child(1)
child.getValue() // 1
child instanceof Parent // true复制代码
  • class 实现继承的核心在于使用 extends 表明继承自哪个父类,并且在子类构造函数中必须调用 super,因为这段代码可以看成 Parent.call(this, value)。

31.讲讲输入完网址按下回车,到看到网页这个过程中发生了什么

a. 域名解析

b. 发起TCP的3次握手

c. 建立TCP连接后发起http请求

d. 服务器端响应http请求,浏览器得到html代码

e. 浏览器解析html代码,并请求html代码中的资源

f. 浏览器对页面进行渲染呈现给用户

32.谈谈你对前端性能优化的理解

a. 请求数量:合并脚本和样式表,CSS Sprites,拆分初始化负载,划分主域

b. 请求带宽:开启GZip,精简JavaScript,移除重复脚本,图像优化,将icon做成字体

c. 缓存利用:使用CDN,使用外部JavaScript和CSS,添加Expires头,减少DNS查找,配置ETag,使AjaX可缓存

d. 页面结构:将样式表放在顶部,将脚本放在底部,尽早刷新文档的输出

e. 代码校验:避免CSS表达式,避免重定向

33.es6新语法

声明与表达式: let与const

let命令: 代码块内有效;

不能重复声明;

迭代计数使用;

无变量提升;


const命令:暂时性死区;

声明一个只读的常量,一旦声明,常量的值就不能改变;

*let是更完美的var,不是全局变量,具有块级函数作用域,大多数情况不会发生变量提升。

const定义常量值,不能够重新赋值,如果值是一个对象,可以改变对象里边的属性值。


var 和 let的区别: var 是在全局范围内有效、let代码块内有效

var 可以声明多次、 let只能声明一次;

let 不存在变量提升,var 会变量提升;


示例:

console.log(a);  //ReferenceError: a is not defined
let a = "apple";
 
console.log(b);  //undefined
var b = "banana";复制代码

变量 b 用 var 声明存在变量提升,所以当脚本开始运行的时候,b 已经存在了,但是还没有赋值,所以会输出 undefined。

变量 a 用 let 声明不存在变量提升,在声明变量 a 之前,a 不存在,所以会报错。


const 命令

暂时性死区:

var PI = "a";
if(true){
  console.log(PI);  // ReferenceError: PI is not defined
  const PI = "3.1415926";
}复制代码


ES6 明确规定,代码块内如果存在 let 或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量 PI 之前使用它会报错。

34、Promise 对象

是异步编程的一种解决方案。

从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。

状态的特点

Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。

Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 resolved(已定型)。


状态的缺点

无法取消 Promise ,一旦新建它就会立即执行,无法中途取消。

如不设置回调函数,Promise 内部会抛出的错误,不会反应到外部。

当处于 pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。


then 方法

then 方法接收两个函数作为参数,第一个参数是 Promise 执行成功时的回调,第二个参数是 Promise 执行失败时的回调,两个函数只会有一个被调用。


then 方法的特点

在 JavaScript 事件队列的当前运行完成之前,回调函数永远不会被调用。


35.请你谈谈Cookie的弊端

a. 每个特定的域名下最多生成的cookie个数有限制

b. IE和Opera 会清理近期最少使用的cookie,Firefox会随机清理cookie

c. cookie的最大大约为4096字节,为了兼容性,一般不能超过4095字节

d. 安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。


36.对BFC规范的理解

BFC的一个最重要的效果是,让处于BFC内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。

利用BFC可以闭合浮动,防止与浮动元素重叠。

37.项目中遇到过的难题?

38.你常使用的库有哪些?常用的前端开发工具?开发过什么应用或组件?

39.列举IE与其他浏览器不一样的特性?

a. IE的排版引擎是Trident

b. Trident内核曾经几乎与W3C标准脱节

c. Trident内核的大量 Bug等安全性问题没有得到及时解决

d. JS方面,有很多独立的方法,例如绑定事件的attachEvent、创建事件的createEventObject等

e. CSS方面,也有自己独有的处理方式,例如设置透明,低版本IE中使用滤镜的方式

40.什么叫优雅降级和渐进增强?

渐进增强 progressive enhancement:

针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

优雅降级 graceful degradation:

一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

41.WEB应用从服务器主动推送Data到客户端有那些方式?

a. html5 websoket

b. WebSocket 通过 Flash

c. XHR长时间连接

d. XHR Multipart Streaming

e. 不可见的Iframe(一个没有前端的公司,java面我,问我iframe的缺点!!不会,然后他说这是后端写的……)

f. 标签的长时间连接(可跨域)

42.请解释一下 JavaScript 的同源策略

同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。

指一段脚本只能读取来自同一来源的窗口和文档的属性。

43、.ajax的步骤

什么是ajax?

ajax(异步javascript xml) 能够刷新局部网页数据而不是重新加载整个网页。

如何使用ajax?


第一步,创建xmlhttprequest对象,var xmlhttp =new XMLHttpRequest();XMLHttpRequest对象用来和服务器交换数据。

var xhttp;

if (window.XMLHttpRequest) {

//现代主流浏览器

xhttp = new XMLHttpRequest();

} else {

// 针对浏览器,比如IE5或IE6

xhttp = new ActiveXObject("Microsoft.XMLHTTP");

}复制代码

第二步,使用xmlhttprequest对象的open()和send()方法发送资源请求给服务器。


第三步,使用xmlhttprequest对象的responseText或responseXML属性获得服务器的响应。


第四步,onreadystatechange函数,当发送请求到服务器,我们想要服务器响应执行一些功能就需要使用onreadystatechange函数,每次xmlhttprequest对象的readyState发生改变都会触发onreadystatechange函数


44.一次js请求一般情况下有哪些地方会有缓存处理?

a. 浏览器端存储

b. 浏览器端文件缓存

c. HTTP缓存304

d. 服务器端文件类型缓存

e. 表现层&DOM缓存


45.一个页面上有大量的图片,加载很慢,你有哪些方法优化这些图片的加载?

a. 图片懒加载,滚动到相应位置才加载图片。

b. 图片预加载,如果为幻灯片、相册等,将当前展示图片的前一张和后一张优先下载。

c. 使用CSSsprite,SVGsprite,Iconfont、Base64等技术,如果图片为css图片的话。

d. 如果图片过大,可以使用特殊编码的图片


46、.谈谈以前端角度出发做好SEO需要考虑什么?

a. 了解搜索引擎如何抓取网页和如何索引网页

b. meta标签优化

c. 关键词分析

d. 付费给搜索引擎

e. 链接交换和链接广泛度(Link Popularity)

f. 合理的标签使用


47、get、 post的区别

get获取数据;post提交数据

get 用于获取信息,是无副作用的,是幂等的,且可缓存

post 用于修改服务器上的数据,有副作用,非幂等,不可缓存

get 传参方式是通过地址栏URL传递,能直接看到get传递的参数,post传参方式参数URL不可见,

get 把请求的数据在URL后通过?连接,通过&进行参数分割。

post 将从参数存放在HTTP的包体内

get 对传递的数据长度受URL的限制,URL最大长度是2048个字符。

post 没有长度限制

get后退不会有影响,post后退会重新进行提交

get请求可以被缓存,post不可以被缓存

get请求只支持URL编码,post支持多种编码方式

get请求的记录会留在历史记录中,post请求不会留在历史记录

get只支持ASCII字符,post没有字符类型限制


48、var a;

console.log(a) 求结果?原因?

输出:undefind, a只声明,没有赋值

49、transform和transition的区别?

50、mounted中常用的方法?

51、钩子函数(问了无数次)

52、1.清除浮动的方法?(多次出现在面试题)


1.父级div定义 height


原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。

2,结尾处加空div标签 clear:both

原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度

3,父级div定义 伪类:after 和 zoom


原理:IE8以上和非IE浏览器才支持:after,原理和方法2有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题

4,父级div定义 overflow:hidden

原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度

53、position有哪些属性?

54、隐藏一个div有几种方法?

55、登陆注册怎么做?


56、计算属性和监听器有什么区别?computed、watch

当需要在数据变化时执行异步或开销较大的操作时,用侦听。

模板中显示内容,不做任何复杂的计算(或者逻辑),这个时候就可以用到计算属性


57、v-for渲染列表是key是用来做什么的?

为了高效的更新虚拟DOM

58、数据请求在生命周期哪一个阶段?

一般在 created(或beforeRouter)里面就可以,如果需要页面加载完成之后的话就用

mounted。


在created的时候,视图中的html并没有渲染出来,所以此时如果直接去操作html的dom节点,一定找不到相关的元素

而在mounted中,由于此时html已经渲染出来了,所以可以直接操作dom节点

59、给DOM元素绑定事件有哪些方法?

a、在DOM元素中直接绑定;

b、在JavaScript代码中绑定;

c、绑定事件监听函数。


60、数组里面有哪些遍历方法?es6

for(){} 遍历

forEach 遍历

for-in 遍历

for-of 遍历

every()、some()、filter()、map()、reduce()、reduceRight()


61、用js可以实现的动画 为什么要用css?

css渲染的动画不占用js主线程

62、ajax请求数据重新处理和拦截器?

解决拦截器对ajax请求的的拦截

public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object obj) throws Exception {
        
        //获取判定登陆的session是否存在
        String token = (String) request.getSession().getAttribute("token");
        String postId = (String) request.getSession().getAttribute("postId");
        if(token == null || token == ""){
            String XRequested =request.getHeader("X-Requested-With");
            if("XMLHttpRequest".equals(XRequested)){
                response.getWriter().write("IsAjax");
            }else{
                response.sendRedirect("/m-web/user/toLogin");
            }
            return false;
        }
        if(postId == null || postId == ""){
            String XRequested =request.getHeader("X-Requested-With");
            if("XMLHttpRequest".equals(XRequested)){
                response.getWriter().write("IsAjax");
            }else{
                response.sendRedirect("/m-web/user/toLogin");
            }
            return false;
        }
        return true;
    }复制代码

1、判断 String XRequested =request.getHeader("X-Requested-With") 的值,目的是判断是否是ajax请求。

2、response.getWriter().write("IsAjax");写出一个响应的数据给ajax,这样就可以在ajax里面做判断

  判断的方式存在两种方式:

  1)直接在ajax里面做判断(不建议)

success:function(data){
    if(data == "IsAjax"){
        window.location.href="m-web/user/toLogin"
        return;
    }
}复制代码

2)改jQuery源码然后在做压缩,是针对全局的方式来修改的(建议)

if ( isSuccess ) {// if no content
                if ( status === 204 || s.type === "HEAD" ) {
                    statusText = "nocontent";

                // if not modified
                } else if ( status === 304 ) {
                    statusText = "notmodified";

                // If we have data, let's convert it
                } else {
                    statusText = response.state;
                    success = response.data;
                    error = response.error;
                    isSuccess = !error;
                    //解决ajax拦截问题
                    var result = responses.text;
                    if(result.indexOf("IsAjax")>=0){
                        window.location.href="m-web/user/toLogin";
                        return;
                    }
                }
            }复制代码

63、bootstrap中栏栅的24个是怎么做的?24个col不加数字就可以

64、轮播图是怎么考虑的 什么逻辑?


65、git的常用操作?

命令操作、远程Git和local的同步实现流程:

1、把git上的代码clone到本地

$ git clone http:xxxx(地址,可以http也可以ssh)

2、clone到本地以后、使用branch -a 查看远程所有分支

$ git branch -a

3、如若你有分支:master branch1 branch2 ,使用checkout用来切换分支。还可以用第2条指令去创建本地分支目录和远程的保持一致,并且切换远程分支到本地分支目录

$ git checkout branch1

$ git checkout -b branch1 origin/branch1

4、在本地修改完代码后、保存所有的项目

$ git add .

5、保存完成后可以提交到本地

$ git commit -m '提交说明'

6、最后提交git服务器,要加上分支的名字,默认master目录不加。

$ git push origin branch1


66、const定义对象能否改变?

可以的 。 定义的对象还是存储在堆当中


67、vue-router的原理

说简单点,vue-router的原理就是通过对URL地址变化的监听,继而对不同的组件进行渲染。

每当URL地址改变时,就对相应的组件进行渲染。原理是很简单,实现方式可能有点复杂,主要有hash模式和history模式


68、生命周期?

实例在被创建前经过的一系列初始化过程叫生命周期

生命周期钩子:在生命周期中被自动调用的函数叫做生命周期钩子


69、前台发送数据到后端,并且后端给前端返回数据

后台 server.js

var express = require("express");
var app = express();
// 通过post的方法获取页面的信息
// 1.npm下载bodyParser  2.引用
var bodyParser = require("body-parser");
// 3.设置
var uE = bodyParser.urlencoded({ extended: false });

// 中间件解决跨域问题
app.use(function(req, res, next) {
    // 解决跨域
    res.header('Access-Control-Allow-Origin', '*');

    res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');

    res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE,OPTIONS');
    next();
})

app.get("/", function(req, res) {
    // 接收前台发过来的数据
    //用get的方式获取前台的数据使用req.query.xxx
    console.log(req.query.num);
    res.send("我是get的接口");
})


// 4.把解析功能传入
app.post("/post", uE, function(req, res) {
    //用post的方式获取前台数据使用req.body.xxx
    console.log(req.body.num);
    res.send({
        status: 200,
        content: "我是post的接口"
    });
})

app.listen(3001);
 
 复制代码

前台index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="../node_modules/jquery/dist/jquery.min.js"></script>
</head>

<body>
    <button>点我进行数据请求</button>

    <script>
        $("button").eq(0).on("click", function() {
            $.ajax({
                url: "http://localhost:3001/post",
                type: "post",
                data: {
                    num: 123
                },
                success(data) {
                    console.log(data);
                }
            })
        })
    </script>

</body>

</html>复制代码

70、express

express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性和丰富的 HTTP 工具

功能: 1、扩展了web所需要的基本功能

2、丰富了HTTP工具

3、可以快速搭建一个网站

var express=require("express");
// 初始化express
var app=express();



// 定义中间件(每一次接收到请求后都会先经过中间件)
app.use(function(req,res,next){

    console.log("你好")


    next()//下一步
})



// 创建服务
app.get("/",function(req,res){
    res.send("aaaaaaa");
})


// 路由的使用
app.get("/index",function(req,res){
  
    res.send("我是index")
})

app.get("/home",function(req,res){
   
    res.send("我是home")
})

app.get("/post",function(req,res){
 
    res.send("我是get的post")
})

app.get("/a*",function(req,res){
   
    res.send("我是路径通配符选择的")
})

// 接受一个post请求
app.post("/post",function(req,res){
    res.send("我是一个post请求")
})


app.listen(3000)复制代码

71、路由登录注册

登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>登陆页面</title>
</head>
<body>
    
    <form action="http://localhost:3001/login">
        <input type="text" name="uname"/>
        <input type="text" name="upwd"/>
        <input type="submit" value="登陆">
    </form>

</body>
</html>复制代码


注册页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>注册页面</title>
</head>
<body>
    
    <form action="http://localhost:3001/zhuce">
        <input type="text" name="uname"/>
        <input type="text" name="upwd"/>
        <input type="submit" value="注册">
    </form>

</body>
</html>复制代码

server.js

在浏览器输入localhost:/端口号/zhuce 或者(login)

var http=require("http");
var url=require("url");
http.createServer(function(req,res){
    res.writeHead(200,{"Content-type":"text/html;charset=utf-8"});
    // 解决二次请求

    var pathurl=url.parse(req.url);
    if(pathurl.pathname=="/favicon.ico"){
        return;
    }


// 路由
    if(pathurl.pathname=="/login"){
        res.end("您执行了登陆的后台功能");
    }else if(pathurl.pathname=="/zhuce"){
        res.end("您执行了注册的后台功能");
    }else{
        res.end("您的请求有误  请核实后在进行请求");
    }
}).listen(3001)复制代码

72、AJAX

Async javascript and XML 异步的js和xml 局部刷新

如果没有局部刷新整个HTML页面都会刷新,这样比较占网速(浪费流量),页面比较慢。

console.log(1);
var timer = window.setTimeout(function(){console.log(2)},0);
console.log(3);复制代码


服务器端返回给客户端一般都是JSON格式的字符串或者xml格式的数据

xml:可扩展的标记语言

 <production>
        <price>100元</price>
        <name>洗衣机</name>
 </production> 复制代码

创建ajax

//1.创建ajax的实例
      let xhr = new XMLHTTPRequest();//后边的()可写可不写
      let xhr = new XMLHTTPRequest;

//2.请求配置项
    xhr.open([请求方式],[请求路径],[ASYNC,默认是true],[USERNAME],[USERPASS]);
    //请求方式    下边所有的请求方式都能够给服务器发送请求,也可以从服务器获取内容
    //get/delete/head/options..
    
    //post/put
    
    //get/post
    //一般来讲get用来从服务器获取内容   获取的多,给的少
    //post:获取的少给的多
    //delete:从服务器删除一些内容
    //head:只获取服务器响应头信息
    //options:客户端对服务器的测试请求
    
    //当前给服务器发送请求的时候如果用的get一般给服务器传递阐述用?传参
    https://hellojoy.jd.com:443/?itemid=12560&babelChannel=1500725&activityId=2wbhW341AywcD3Xyv9sR5MhCPFAL&linkIds=4713019,2828306,3986352&source=02
    

//3.发送请求
    xhr.send([请求主体]);//发送给服务器的内容放到请求主体中

//4.监听通讯的内容


//readySate:ajax请求状态
UNSENT: 0   ajax实例还没有创建
OPENED: 1   参数开始配置
HEADERS_RECEIVED: 2   客户端已经开始接收服务器端响应头信息 (返回状态码,日期....)
LOADING: 3  正在准备加载服务器端响主体内容
DONE: 4   响应主体的内容已经获取完毕了



//status:HTTP网络状态码

200:ok请求状态成功(虽然请求成功了,但是拿到的内容不一定是你想要的)
301:永久从定向(永久转移)
307 Internal Redirect:临时重定向   把http转为htts
304 Not Modified :从缓存当中获取
302 Move Temporarily  临时转移(负载均衡) 当服务器的并发数不能承受的时候,把部分访问转移其它服务及集群
404:not Found  找不到
400:请求参数错误
500 Internal Server Error 未知错误
503 Service Unavailable 服务器超负荷




//onreadystatechanage监听状态改变
xhr.onreadystatechanage = ()=>{
    if(!/^(2|3)\d{2}$/.test(xhr.sataus))return;
    if(xhr.readyState ==2){
    }
    
    if(xhr.satus ==200 &&xhr.readyState == 4){
    
    }
}复制代码
作者:去土耳其啊
链接:https://zhuanlan.zhihu.com/p/83252221
来源:知乎


关注下面的标签,发现更多相似文章
评论