1 判断当前脚本运行在何种环境(browser / node)
// 通过判断 Global 对象是否为 window,如果不是则代表没有运行在浏览器中
this === window ? 'browser' : 'node'
2 什么是 Polyfill
Polyfill 指的是用于实现浏览器不支持的原生 API(写补丁)
3 使用 js 获取文件的扩展名
let fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1);
}
4 Object.is(), "==" 和 "==="
- '==':会在比较时进行类型转换
- '===':判断严格,不进行隐式类型转换,类型不同也会返回 false
- object.is(val1,val2):在三等号判断的基础上特别处理 NaN 和 NaN 相同, +0 和 -0 不相同
5 Unicode 和 UTF-8 的区别
Unicode 是一种字符集合,现在可容纳 100 多万个字符。每个字符对应一个不同的 Unicode 编码,它只规定了符号的二进制代码,却没有规定这个二进制代码在计算机中如何编码传输。
UTF-8 是一种对 Unicode 的编码方式,它是一种变长的编码方式,可以用 1~4 个字节来表示一个字符。
6 escape、encodeURI、encodeURIComponent
- encodeURI:对整个 URI 包括非法字符但不包括对 URI 有特殊意义的字符
- encodeURIComponent:对 URI 的组成部分包括特殊字符进行转义
- escape:与 encodeURI 作用相同,但是 escape 是直接在字符的 unicode 编码前加上 %u,而 encodeURI 首先会将字符转换为 UTF-8 的格式,再在每个字节前加上 %。
7 防抖和节流
- 函数防抖:在事件被触发的 n 秒后再执行回调。如果在 n 秒内,事件再次被触发,则重新计时。
function debounce (fn, wait) {
let timer = null;
return function () {
let context = this;
let args = arguments;
if(timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(function () {
fn.apply(context, args)
}, wait)
}
}
const fn = function () {
console.log('debounce...')
}
// 1500ms 后触发第一次,此后每 1000ms 触发一次
setInterval(debounce(fn, 500), 1000)
// 不会触发
setInterval(debounce(fn, 1000), 500)
- 函数节流:规定一个单位时间,在单位时间内只能有一次触发事件的回调函数。即使在单位时间内事件被触发多次也只有一次执行回调。
* 节流
* @param {function} func function
* @param {number} limit limit
* @returns {function} func
*/
const throttle = (func, limit) => {
let lastFunc;
let lastRan;
return function() {
const context = this;
const args = arguments;
if (!lastRan) {
// 记录第一次运行的时间
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function() {
if (Date.now() - lastRan >= limit) {
func.apply(context, args);
lastRan = Date.now()
}
}, limit - (Date.now() - lastRan))
}
}
};
8 手写深浅拷贝
function shallowCpoy(object) {
if(!object || typeOf object !== 'object') return;
let newObject = Array.isArray(object) ? [] : {};
for(let key in object) {
if(object.hasOwnProperty(key)) {
newObj[key] = object[key];
}
}
return newObject;
}
function deepCopy(object) {
if(!object || typeOf object !== 'object') return;
let newObject = Array.isArray(object) ? [] : {};
for(let key in object) {
if(object.hasOwnProperty(key)) {
if(typeOf object[key] === 'object') {
newObj[key] = deepCopy(object[key])
} else {
newObj[key] = object[key];
}
}
}
return newObject;
}
9 手写 call、apply 和 bind 函数
todo
10 toPrecision、toFixed、Math.round
- toPrecision(precision):四舍五入到指定的精度
- toFixed:对小数点后指定位数取整
- Math.round():四舍五入到一个整数
11 link 和 @import 的区别
- link 是 HTML 标签,@import 是 css 提供的
- link 引入的样式页面加载时同时加载,@import 引入的样式需等页面加载完成后再在家
- link 没有兼容性问题,@import 不兼容 ie5 以下
- link 可以通过 js 操作 DOM 动态引入样式表改变样式,而 @import 不可以
12 圣杯布局和双飞翼布局
作用:圣杯布局和双飞翼布局解决的问题是一样的,就是两边顶宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。
区别:圣杯布局,为了中间div内容不被遮挡,将中间div设置了左右padding-left和padding-right后,将左右两个div用相对布局position: relative并分别配合right和left属性,以便左右两栏div移动后不遮挡中间div。双飞翼布局,为了中间div内容不被遮挡,直接在中间div内部创建子div用于放置内容,在该子div里用margin-left和margin-right为左右两栏div留出位置。
// 圣杯布局
<body>
<div id="hd">header</div>
<div id="bd">
<div id="middle">middle</div>
<div id="left">left</div>
<div id="right">right</div>
</div>
<div id="footer">footer</div>
</body>
<style>
#hd{
height:50px;
background: #666;
text-align: center;
}
#bd{
/*左右栏通过添加负的margin放到正确的位置了,此段代码是为了摆正中间栏的位置*/
padding:0 200px 0 180px;
height:100px;
}
#middle{
float:left;
width:100%;/*左栏上去到第一行*/
height:100px;
background:blue;
}
#left{
float:left;
width:180px;
height:100px;
margin-left:-100%;
background:#0c9;
/*中间栏的位置摆正之后,左栏的位置也相应右移,通过相对定位的left恢复到正确位置*/
position:relative;
left:-180px;
}
#right{
float:left;
width:200px;
height:100px;
margin-left:-200px;
background:#0c9;
/*中间栏的位置摆正之后,右栏的位置也相应左移,通过相对定位的right恢复到正确位置*/
position:relative;
right:-200px;
}
#footer{
height:50px;
background: #666;
text-align: center;
}
</style>
// 双飞翼布局
<body>
<div id="hd">header</div>
<div id="middle">
<div id="inside">middle</div>
</div>
<div id="left">left</div>
<div id="right">right</div>
<div id="footer">footer</div>
</body>
<style>
#hd{
height:50px;
background: #666;
text-align: center;
}
#middle{
float:left;
width:100%;/*左栏上去到第一行*/
height:100px;
background:blue;
}
#left{
float:left;
width:180px;
height:100px;
margin-left:-100%;
background:#0c9;
}
#right{
float:left;
width:200px;
height:100px;
margin-left:-200px;
background:#0c9;
}
/*给内部 div 添加 margin,把内容放到中间栏,其实整个背景还是100%*/
#inside{
margin:0 200px 0 180px;
height:100px;
}
#footer{
clear:both; /*清除浮动*/
height:50px;
background: #666;
text-align: center;
}
</style>
负 margin 可参考:segmentfault.com/a/119000001…
13 js 生成随机数
- ceil:向上取整
- floor、parseInt:向下取整
- round:四舍五入
- random:返回0~1之间的随机数,包含0不包含1
生成随机整数:
Math.floor(Math.random() * (max-min)) + min