noah的前端面试题(三)|掘金技术征文

1,041 阅读5分钟

上一篇 前端面试题(二)

1.JavaScript对于cookie的读、写操作

写入 cookie

function setCookie(cName, cValue, days) {   
 var expires = new Date();    
 expires.setTime(expires.getTime() + parseInt(days) * 24 * 60 * 60 * 1000);    
 document.cookie = cName + "=" + escape(cValue) + ";expires=" +       expires.toGMTString()+";path=/;domain=xxx.cn"; 
 };
  • expires: cookie的过期时间,注意这里要使用格林威治时间
  • path: 这个参数表示cookie保存的路径,如果没有给出的话会保存为当前站点的,如果给出值”/“的话会保存到当前虚拟目录
  • domain: 这个参数有点类似于session的保存路径,默认情况下保存在当前客户端,也可以自定义到其他位置

读取cookie

function getCookie(name){     
 var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));   
 if(arr != null)   return decodeURI(arr[2]); 
 return null;  
}

分享一片关于cookie的文章  http://www.cnblogs.com/Darren_code/archive/2011/11/24/Cookie.html

2.setTimeout promise 和 await sync执行顺序

async function async1() {
console.log("async1 start");
await  async2();
 console.log("async1 end");
}
async  function async2() {
 console.log( 'async2');
}
console.log("script start");
setTimeout(function () {
 console.log("settimeout");
},0);
async1();
new Promise(function (resolve) {
 console.log("promise1");
 resolve();
}).then(function () {
 console.log("promise2");
});
console.log('script end'); 
结果是:

script start async1 start async2 promise1 script end async1 end promise2 settimeout  

这里涉及到同步异步 Microtasks Macrotasks Microtasks优先级别高于Macrotasks  其中Microtasks Macrotasks分别是

microtasks:

  • process.nextTick
  • promise
  • Object.observe
  • MutationObserver

macrotasks:

  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • UI渲染
  1. 一个事件循环(event loop)会有一个或多个任务队列(task queue)
  2. task queue 就是 macrotask queue
  3. 每一个 event loop 都有一个 microtask queue
  4. task queue == macrotask queue != microtask queue
  5. 一个任务 task 可以放入 macrotask queue 也可以放入 microtask queue 中
因此事件循环的顺序,决定了JavaScript代码的执行顺序。它从script(整体代码)开始第一次循环。之后全局上下文进入函数调用栈。直到调用栈清空(只剩全局),然后执行所有的micro-task。当所有可执行的micro-task执行完毕之后。循环再次从macro-task开始,找到其中一个任务队列执行完毕,然后再执行所有的micro-task,这样一直循环下去。

3. 关于Vue.nextTick()的正确使用 什么时候需要用的Vue.nextTick()

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

  1. 你在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中。原因是什么呢,原因是在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。

  2. 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。

4. 关于数组排序 任意数值相同的数组混乱排序但是每次排出的顺序都是一样的 比如是【1,3,5,6】或者 【6,5,3,1】排除顺序以后是 【3,6,1,5】

用数组sort方法

5. es5 和 es6 class 有什么区别 

用ES6定义class中的方法,定义在原型对象上的。与ES5不同的是,这些定义在原型对象的方法是不可枚举的。

ES6类和模块是严格模式下的;

不存在变量提升,保证子类父类的顺序;

子类必须在父类的构造函数中调用super(),这样才有this对象,因为this对象是从父类继承下来的。而要在子类中调用父类的方法,用super关键词可指代父类。

ES5中类继承的关系是相反的,先有子类的this,然后用父类的方法应用在this上。

ES6类继承子类的this是从父类继承下来的这个特性,使得在ES6中可以构造原生数据结构的子类,这是ES5无法做到的。

ES6也可以定义类的静态方法和静态属性,静态的意思是这些不会被实例继承,不需要实例化类,就可以直接拿来用。ES6中class内部只能定义方法,不能定义属性。在方法名前加上static就表示这个方式是静态方法,而属性还是按照ES5的方式来实现。

7. es6 class内部箭头函数写法和普通函数写法有什么不同

class Person { 
 Run() {    //传统形式的函数写法  this; } 
 eat = () => {    //es6中的箭头函数写法  this; }     
}   

编译之后的结果如下

var Person = (function () {
    function Person() {
        var _this = this;
        this.eat = function () {    //箭头写法直接挂到Person的this下
            _this;        
        };   
     }   
    Person.prototype.Run = function () {    //传统写法则挂到prototype中定义       
     this;
    };       
    return Person;
 }());  

这里不仅展示了在方法的定义,还比较了在ES6中传统函数和箭头函数的区别,传统函数的thises5函数的this指向完全一样,但箭头函数的this指向的是它外层对象的作用域,这里不细说,想了解请点击


7.vue.js中的事件修饰符.self的用法

.self可以理解为跳过冒泡事件和捕获事件,只有直接作用在该元素上的事件才可以执行。


8. pwa 缓存策略

Service Worker 是一段脚本,与 Web Worker 一样,也是在后台运行。作为一个独立的线程,运行环境与普通脚本不同,所以不能直接参与 Web 交互行为。Native App 可以做到离线使用、消息推送、后台自动更新,Service Worker 的出现是正是为了使得 Web App 也可以具有类似的能力。详情链接

9. 混合开发中如何native的token

10. Vue 中如何使用 MutationObserver 做批量处理?

现在 Vue 的 nextTick 实现移除了 MutationObserver 的方式(兼容性原因),取而代之的是使用 MessageChannel。至于 MutationObserver 如何模拟 nextTick 这点,直接看源码,其实就是创建一个 TextNode 并监听内容变化