前端面试进阶vue-es6-js

42次阅读

共计 4573 个字符,预计需要花费 12 分钟才能阅读完成。

以下内容仅为个人见解,如有错误欢迎指正~

vue

双向绑定

 原理:vue.js 则是采用数据劫持结合发布者 - 订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。延伸:*  Object.defineProperty() 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。*  Object.defineProperty(对象,属性,属性描述符) 用于在一个对象上定义一个新的属性,或者修改一个对象现有的属性,并返回这个对象
实现:通过 Obeject.defineProperty() 来监听数据属性变动,将数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter。详解:* 实现一个监听器 Observer:给对象的某个值赋值 ==> 触发 setter(监听到数据变化)==> 通知订阅者(notify(在调用订阅者的 update 方法))* 实现一个订阅者 Watcher:可以收到属性的变化通知并执行相应的函数,从而更新视图。(getter(const dep = new Dep(); 然后清空,减少性能浪费))* 实现一个解析器 Compile:可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。

watch | computer

 共同点:希望在数据发生改变的时候,数据根据预先定义好的函数,发生“自动”的变化。区别:watch 擅长处理的场景:一个数据影响多个数据
        computed 擅长处理的场景:一个数据受多个数据影响    

组件传值

 父改子:ref  $ref
  父传子:props
  子传父:$emit
  兄弟组件:$on
  通用:利用缓存(store locationstrage 后端....)

延伸:vue 监听子组件生命周期

    // Parent.vue
        <Child @mounted="doSomething"/>
    // Child.vue
        mounted() {this.$emit("mounted");
        }
    或者
    <Child @hook:mounted="doSomething"/>    

keep-alive

 原理:Vue 的缓存机制并不是直接存储 DOM 结构,而是将 DOM 节点抽象成了一个个 VNode 节点。因此,Vue 的 keep-alive 缓存也是基于 VNode 节点 而不是直接存储 DOM 节点。用法:<keep-alive> 是 Vue 的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染 DOM。include: 字符串或正则表达式。只有匹配的组件会被缓存。exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。max:最多几个(vue2 之前不生效)

v-if v-for 使用

    v-for 优先级高,因此不建议同时使用,可在上层 dom  使用 v-if 

路由(hash | history + 路由守卫)

hash:就是指 url 尾巴后的 # 号以及后面的字符,window.location.hash 获取 hash 值
history:window.history(可直接写成 history) 指向 History 对象,它表示当前窗口的浏览历史
    
路由守卫
    全局
        router.beforeEach((to, from, next) => {// ...})    
        router.afterEach((to, from) => {// ...})
    路由独享的守卫    
        const router = new VueRouter({
          routes: [ {
              path: '/foo',
              component: Foo,
              beforeEnter: (to, from, next) => {// ...}
            }  ]
        })
    组件内的守卫    
        beforeRouteEnter
        beforeRouteUpdate (2.2 新增)
        beforeRouteLeave

虚拟 dom 优缺点

 什么是虚拟 dom:用 js 模拟一颗 dom 树, 放在浏览器内存中. 当你要变更时, 虚拟 dom 使用 diff 算法进行新旧虚拟 dom 的比较, 将变更放到变更队列中,
        反应到实际的 dom 树, 减少了 dom 操作. 虚拟 DOM 将 DOM 树转换成一个 JS 对象树,
        diff 算法逐层比较, 删除, 添加操作, 但是, 如果有多个相同的元素, 可能会浪费性能, 所以,
        react 和 vue-for 引入 key 值进行区分.
优点:* 虚拟 DOM 具有批处理和高效的 Diff 算法, 最终表现在 DOM 上的修改只是变更的部分,可以保证非常高效的渲染, 优化性能.
缺点:* 性能差(虽然虚拟 DOM + 合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。)* 首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,会比 innerHTML 插入慢。

es6

promise

实现:

* 1. new Promise 时,需要传递一个 executor 执行器,执行器立刻执行
 * 2. executor 接受两个参数,分别是 resolve 和 reject
 * 3. promise 只能从 pending 到 rejected, 或者从 pending 到 fulfilled
 * 4. promise 的状态一旦确认,就不会再改变
 * 5. promise 都有 then 方法,then 接收两个参数,分别是 promise 成功的回调 onFulfilled, 
 *      和 promise 失败的回调 onRejected
 * 6. 如果调用 then 时,promise 已经成功,则执行 onFulfilled,并将 promise 的值作为参数传递进去。*      如果 promise 已经失败,那么执行 onRejected, 并将 promise 失败的原因作为参数传递进去。*      如果 promise 的状态是 pending,需要将 onFulfilled 和 onRejected 函数存放起来,等待状态确定后,再依次将对应的函数执行 (发布订阅)
 * 7. then 的参数 onFulfilled 和 onRejected 可以缺省
 * 8. promise 可以 then 多次,promise 的 then 方法返回一个 promise
 * 9. 如果 then 返回的是一个结果,那么就会把这个结果作为参数,传递给下一个 then 的成功的回调 (onFulfilled)
 * 10. 如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个 then 的失败的回调 (onRejected)
 * 11. 如果 then 返回的是一个 promise, 那么需要等这个 promise,那么会等这个 promise 执行完,promise 如果成功,*   就走下一个 then 的成功,如果失败,就走下一个 then 的失败 

使用:

先执行 getData1,在执行 getData2

let getData1=new Promise(function(resolve,reject){
    $.ajax({
        type:"get",
        url:".../getData1",
        success:function(data){if(data.state=="200"){resolve(data.data) // 在异步操作成功时调用
            }else{reject(data.msg); // 在异步操作失败时调用
            }
        }
    });
})
let getData2=new Promise(function(resolve,reject){
    $.ajax({
        type:"get",
        url:".../getData2",
        success:function(data){if(data.state=="200"){resolve(data.data) // 在异步操作成功时调用
            }else{reject(data.msg); // 在异步操作失败时调用
            }
        }
    });
})
getData1.then(function(res){return getData2(res)
}).then(function(res){console.log(res)
}).catch(function(err){console.log(err)
})

先执行 getData1 和 getData2,在执行 getData3

let getData3=new Promise(function(resolve,reject){
    $.ajax({
        type:"get",
        url:".../getData3",
        success:function(data){if(data.state=="200"){resolve(data.data) // 在异步操作成功时调用
            }else{reject(data.msg); // 在异步操作失败时调用
            }
        }
    });
})

Promise 的 all 方法,等数组中的所有 promise 对象都完成执行

Promise.all([getData1,getData2]).then(function([ResultJson1,ResultJson2]){
    // 这里写等这两个 ajax 都成功返回数据才执行的业务逻辑
  getData3()})

for in | for of

for in 循环的是 index
for of 循环的是 item

proxy

js

数组方法

1.splice(index,howmany,[item1,...]):从数组中添加 / 删除元素,返回被删除项,注意:这个操作会改变原始数组。2.slice(start,[end]):从已有数组中返回选定元素, 此操作不会修改原始数组。3.shift():删除数组第一个元素,返回删除项,改变原始数组,不产生新数组。4.unshift(newelement1,[...]): 在数组开头添加一或多个元素,并返回新的长度。改变原数组,不产生新数组。5.pop(): 删除数组最后一个元素,并返回删除的值,若是操作空数组,返回 undefined。改变原数组。6.push(element1,[......]): 向数组末尾添加一个或多个元素,返回数组长度。直接修改原数组。7.concat(arrayX,......): 连接两个或多个数组,返回被连接数组的副本,不会改变原始数组。8.reverse(): 颠倒数组元素顺序,改变原始数组,不会创建新数组。9.sort(): 对现有数组进行排序,改变原始数组。此方法会在排序之前首先对数组的每一项调用 toString() 方法,再进行排序
10.join([separator]): 对数组元素以指定的分隔符进行分隔,参数为空,默认以“,”进行分隔。返回值是分隔后形成的字符串 

数据类型

 基本数据类型包括 undefined、null、number、boolean、string;对象类型 Object,比如:Object、array、function、data 等;

从输入 URL 到页面展示的详细过程

1、输入网址
2、DNS 解析
3、建立 tcp 连接
4、客户端发送 HTPP 请求
5、服务器处理请求 
6、服务器响应请求
7、浏览器展示 HTML
8、浏览器发送请求获取其他在 HTML 中的资源。

闭包

 闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。通俗的来说就是:JavaScript 中所有的 function 都是一个闭包。不过一般来说,嵌套的 function 所产生的闭包更为强大,也是大部分时候我们所谓的“闭包”当函数 a 的内部函数 b 被函数 a 外的一个变量引用的时候,就创建了一个闭包。

正文完
 0