1.如何理解前端模块化
前端模块化:就是将复杂的文件解构成一个个独立文件,比如js和css文件,这么做的目的是提高代码的复用概率,和更好的维护
2.说一下Commonjs、AMD和CMD
这三个都被称之为规范
CommonJS:
是JS在后端应用的一个同步规范
没有模块系统、标准库较少、没有标准接口、缺乏包管理系统等等一系列问题
因此有了这个规范
它的实现主要包括:webpack、nodejs、npm
AMD:
JS在前端应用的一个异步规范
AMD将依赖模块的语句放在一个回调中,回调在加载完成之后才会执行,这样就可以通过异步的方式来加载模块
实现:RequireJS
CMD:
和AMD相似,也是一个异步规范,解决了AMD存在的一些问题,CMD规范有更强的包容性和人性化!并且在应用上也更加地简单方便
实现:seajs
3.对象深度克隆的简单实现
deepclone
JSON.Stringly JSON.prase
4.将原生的ajax封装成promise
function ajax(url) {
return new Promise(function (resolve, reject) {
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState === 4) {
if (xhttp.status === 200) resolve(xhttp.responseText);
else reject(xhttp.responseText);
}
};
xhttp.open("GET", url);
xhttp.send();
});
}
5.js监听对象属性的改变
ES5
Object.defineProperty(user,'name',{
set:function(key,value){
}
})
ES6
var user = new Proxy({},{
set:function(target,key,value,receiver){
}
})
6.如何实现一个私有变量,用getName方法可以访问,不能直接访问
function product(){
var name='yuxiaoliang';
this.getName=function(){
return name;
}
}
var obj=new product();
7.==和===、以及Object.is的区别
==:等同,比较运算符,两边值类型不同的时候,先进行类型转换,再比较。强制转换成number,null==undefined
===:恒等,严格比较运算符,不做类型转换,类型不同就是不等。
Object .is()是ES6新增的用来比较两个值是否严格相等的方法。主要的区别就是+0!=-0 而NaN==NaN。
8.setTimeout、setInterval和requestAnimationFrame之间的区别
requestAnimationFrame用于浏览器重绘,最好的间隔时间时16.6ms
requestAnimationFrame采用系统时间间隔,保持最佳绘制效率
settimeout:延时函数,用于在延时一段时间后执行相应的代码
setInterval:用于每隔一段时间就进行执行一次相应的代码
setTimeout和setInterval的问题是,它们都不精确。它们的内在运行机制决定了时间间隔参数实际上只是指定了把动画代码添加到浏览器UI线程队列中以等待执行的时间。如果队列前面已经加入了其他任务,那动画代码就要等前面的任务完成后再执行
9.实现一个两列等高布局,讲讲思路
子元素一个指定高度,一个不指定,父元素使用display:flex,align-item:stretch
10.setTimeout模拟setInterval
setTimeout(function () {
// 任务
setTimeout(arguments.callee, interval);
}, interval)
在前一个定时器执行完前,不会向队列插入新的定时器(解决缺点一)
保证定时器间隔(解决缺点二)
11. js怎么控制一次加载一张图片,加载完后再加载下一张
方法一是借助对象的onload事件,该事件可以判断该对象是否加载完成
方法二同理,在readyState="complate"时,就可以表示图片加载完成
12. 如何实现sleep的效果(es5或者es6)
while循环的方式
function sleep(ms){
var start=Date.now(),expire=start+ms;
while(Date.now()<expire);
console.log('1111');
return;
}
通过promise来实现
function sleep(ms){
var temple=new Promise(
(resolve)=>{
console.log(111);setTimeout(resolve,ms)
});
return temple
}
sleep(500).then(function(){
//console.log(222)
})
13. 简单的实现一个promise
then方法的第一个参数就是resolve;第二个参数就是reject。
<script>
console.log(1111);
var p1=new Promise(function(resolve,reject){
console.log(222);
// resolve('hello world');
reject('失败')
});
p1.then(function(res){
console.log(res); //resolve,请求成功
},function(err){
console.log((err));//reject 请求失败
})
console.log(333);
// 111 222 333 失败/成功
</script>
14. 简单实现Node的Events模块
var events=require('events');
var eventEmitter=new events.EventEmitter();
eventEmitter.on('say',function(name){
console.log('Hello',name);
})
eventEmitter.emit('say','Jony yu');
15. 简单实现Node的Events模块
var events=require('events');
var eventEmitter=new events.EventEmitter();
eventEmitter.on('say',function(name){
console.log('Hello',name);
})
eventEmitter.emit('say','Jony yu');
16.代码的执行顺序
setTimeout(function(){console.log(1)},0);
new Promise(function(resolve,reject){
console.log(2);
resolve();
}).then(function(){
console.log(3)
}).then(function(){
console.log(4)
});
process.nextTick(function(){console.log(5)});
console.log(6);
script(主程序代码)——>process.nextTick——>promise——>setTimeout
定义promise的时候,promise构造部分是同步执行的。
-
主体部分
定义promise的构造部分是同步的,因此先输出2,主体部分再输出6(同步情况下,就是严格按照定义的先后顺序) -
process.nextTick
输出5 -
promise
严格的说是promise.then部分,输出的是3和4 -
setTimeout
最后输出1
17.彻底理解js中this的指向
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象。
-
情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题,你想了解可以自行上网查找。-
-
情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
-
情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象,例子3可以证明,如果不相信,那么接下来我们继续看几个例子。
18.js判断类型
判断方法:typeof(),instanceof,Object.prototype.toString.call()等
19.数组常用方法
push(),pop(),shift(),unshift(),splice(),sort(),reverse(),map() filter()
20.数组去重
法一:indexOf循环去重
法二:ES6 Set去重;Array.from(new Set(array))
法三:Object 键值对去重;把数组的值存成 Object 的 key 值,比如 Object[value1] = true,在判断另一个值的时候,如果 Object[value2]存在的话,就说明该值是重复的。
21.去除字符串首尾空格
trim()方法可以去除字符串前后的空格
22.JS实现跨域
JSONP:通过动态创建script,再请求一个带参网址实现跨域通信。document.domain + iframe跨域:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。
23.Js基本数据类型
基本数据类型:undefined、null、number、boolean、string、symbol
24.重排和重绘,讲讲看
简单的说,重排负责元素的几何属性更新,重绘负责元素的样式更新。而且,重排必然带来重绘,但是重绘未必带来重排。比如,改变某个元素的背景,这个就不涉及元素的几何属性,所以只发生重绘。
25.跨域的原理
跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制,那么只要协议、域名、端口有任何一个不同,都被当作是不同的域。跨域原理,即是通过各种方式,避开浏览器的安全限制。
26.不同数据类型的值的比较,是怎么转换的,有什么规则
27.null == undefined为什么?
ECMAScript 规范认为,既然 null 和 undefined 的行为很相似,并且都表示 一个无效的值,那么它们所表示的内容也具有相似性,即有undefined ==null。
两个字:龟腚!
28.暂停死区
在代码块内,使用let、const命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”
29.说一下什么是virtual dom
用JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异 把所记录的差异应用到所构建的真正的DOM树上,视图就更新了。Virtual DOM 本质上就是在 JS 和 DOM 之间做了一个缓存。
30.webpack用来干什么的
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。