- 1 + 2 + '3' + 4 // '334'
- 0 == null
/**
使用 == 比较中的5条规则:
1. `NaN`和其他任何类型比较永远返回`false`(包括和他自己)
2. Boolean 和其他任何类型比较,Boolean 首先被转换为 Number 类型
3. `String`和`Number`比较,先将`String`转换为`Number`类型
4. `null == undefined`比较结果是`true`,除此之外,`null`、`undefined`和其他任何结果的比较值都为`false`
5. `原始类型`和`引用类型`做比较时,引用类型会依照`ToPrimitive`规则转换为原始类型
`ToPrimitive`规则,是引用类型向原始类型转变的规则,它遵循先`valueOf`后`toString`的模式期望得到一个原始类型
如果还是没法得到一个原始类型,就会抛出 `TypeError`
**/
null == null //true
undefined == undefined //true
null == undefined //true
null == 0 //false
null == false //false
undefined == 0 //false
undefined == false //false
null == [] //false
null == {} //false
undefined == [] //false
undefined == {} //false
undefined === null //false
- [] == []
[] == [] //false
[] == ![] //true```
// 第一步,![] 会变成 false
// 第二步,应用 规则2 ,题目变成: [] == 0
// 第三步,应用 规则5 ,[]的valueOf是0,题目变成: 0 == 0
// 所以, 答案是 true
{} == !{} //false
{} == {} //false
参照表:
- typeof null // Object
- typeof NaN // number
- [] == 0 // true
[].valueOf().toString() // ''
Number('') // 0
- for in 和 for of 的区别?谁用来遍历对象,谁用来遍历数组?
- promise 干啥的?里面有什么方法?
待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
已兑现(fulfilled): 意味着操作成功完成。
已拒绝(rejected): 意味着操作失败。
Promise.resolve()
Promise.reject()
Promise.all([promise1, promise2, promise3]).then(()=>{})
// 按参数顺序输出
// 如果有一个立即执行错误,其他延迟执行但正确,结果将立即变为失败
const promises = [promise1, promise2];
Promise.allsettled(promises)
// [{ status: "fulfilled", value: 3 }, { status: "rejected", reason: "foo" }]
// 输出所有的结果
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
});
// 输出最快的结果
Promise.any()
//只要有一个成功的就返回那个已经成功的 `promise`,否则就返回失败的promise 和一个AggregateError类型的实例
Promise.prototype.catch()
p.catch(function(reason) {
// 拒绝
});
Promise.prototype.finally()
p.finally(function() {
// 返回状态为(resolved 或 rejected)都会调用回调
}
Promise.prototype.then()
p.then(onFulfilled[, onRejected]);
p.then(value => {
// fulfillment
}, reason => {
// rejection
});
如果 `then` 中的回调函数
1. 返回了一个值,那么 `then` 返回的 Promise 将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。
2. 没有返回任何值,那么 `then` 返回的 Promise 将会成为接受状态,并且该接受状态的回调函数的参数值为 `undefined`。
3. 抛出一个错误,那么 `then` 返回的 Promise 将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。
4. 返回一个已经是接受状态的 Promise,那么 `then` 返回的 Promise 也会成为接受状态,并且将那个 Promise 的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
5. 返回一个已经是拒绝状态的 Promise,那么 `then` 返回的 Promise 也会成为拒绝状态,并且将那个 Promise 的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
6. 返回一个未定状态(`pending`)的 Promise,那么 `then` 返回 Promise 的状态也是未定的,并且它的终态与那个 Promise 的终态相同;同时,它变为终态时调用的回调函数参数与那个 Promise 变为终态时的回调函数的参数是相同的。
// 输出什么?
const promise = new Promise((resolve, reject) => {
console.log(6)
resolve(1)
reject(2)
resolve(3)
console.log(5)
})
const promise1 = promise.then((res) => {
console.log(res)
return 4
}).then((res) => {
console.log(res)
})
promise.catch((err) => {
console.log(err)
})
promise1.then((res) => {
console.log(res)
})
// 6 5 1 4 undefined
- classlist 的api
div.classList.add("foo");
div.classList.remove("foo");
div.classList.toggle("foo");
div.classList.contains("foo");
div.classList.replace("foo", "bar");
- set map特点 ? api? weakmap weakset 的特点?
- 实现 arr = [1, 2, [6, 2, [...[,,]]], [], 0] 扁平化,然后去重,然后升序排列/降序
let arr = [1, 2, [6, 2, [...[,,]]], [], 0]
let newArr = arr.flat()
let setList = [...new Set(newArr)]
setList.sort((a, b) => {return a - b})
//扁平化
function flatten(arr){
var res = [];
for(var i=0;i<arr.length;i++){
if(Array.isArray(arr[i])){
res = res.concat(flatten(arr[i]));
}else{
res.push(arr[i]);
}
}
return res;
}
- 类数组转数组的方法
[...arr]
循环+利用新数组
Array.from()
Array.prototype.slice.call()
- 迭代器咋实现?里面有啥?
- 判断是不是数组
Array.isArray()
Object.prototype.toString.call()
arr instanceof Array
- filter find 返回值是啥
- 数组反转?reserve 会不会改变原数组?
reserve
数组循环
会改变原数组的:
reserve
sort
- vue的父子生命周期顺序
创建:
父 beforcreated -> 父 created -> 父 beforemounted -> 子 beforcreated -> 子 created -> 子 beforemounted -> 子 mounted
-
vue2/3的响应式实现原理?3有啥好处? vue2: Object.defineProperty vue3: proxy
-
防抖节流
// 节流,n秒执行一次,如果重复触发,只有一次能生效
function throttle(func, time) {
let timer = null
return function (){
if(!timer) {
timer = setTimeout(() => {
func.apply(this, [...arguments]);
timer = null;
}, time)
}
}
}
// 防抖,n秒执行一次,如果重复处罚,重新开始计时
function debounce(func, time) {
let timer = null
return function () {
console.log(this)
clearTimeout(timer)
timer = setTimeout(() => {
func.apply(this, [...arguments])
}, time)
}
}
- 模块化的发展,commonjs 有啥优缺点?es6的默认导出导入,和export的导入 es6模块化
为啥要用模块化?
作用域隔离
es6模块化
import 名称 from 模块 // 默认导入
import {xx,xx,xx} from 模块 // 按需导入
import 名称,{xx,xx,xx} from 模块 // 默认和按需同时导入\
CommonJs (典型代表:node.js早期)
所有代码都运行在模块作用域,不会污染全局作用域
模块是同步加载的,即只有加载完成,才能执行后面的操作
模块在首次执行后就会缓存,再次加载只返回缓存结果,如果想要再次执行,可清除缓存
`require`返回的值是被输出的值的拷贝,模块内部的变化也不会影响这个值
AMD (典型代表:require.js) 所有依赖模块的语句,都定义在一个回调函数中,等到模块加载完成之后,这个回调函数才会运行
CMD (典型代表:sea.js)
UMD
用来处理commonjs、amd、cmd的兼容性差异
typescript module
提供了一个tsconfig.json 的编译器, 比如可配置module 为 AMD等
默认编译成 commonjs
- display:none visibile:hidden opacity:0的区别?父组件visibile:hidden 子组件 visibile: visible 子组件会不会显示?
display:none 会隐藏切不占位置
visibile:hidden 隐藏但位置不变,不能触发事件
opacity:0 透明度为0 可触发监听事件
父组件visibile:hidden 子组件 visibile: visible 子组件会显示
- 如何获取当前时间戳
const s0 = Date.now();
const s1 = new Date().getTime()
const s2 = new Date().valueOf()
const s3 = Date.parse(new Date())
console.log(s0, s1, s2, s3)
`> 1642234229168 1642234229168 1642234229168 1642234229000`
- 获取时分秒的办法
//js获取当前的时分秒
let myDate = new Date();
let h = myDate.getHours(); // 获取当前小时数(0-23)
let m = myDate.getMinutes(); // 获取当前分钟数(0-59)
let s = myDate.getSeconds();// 获取当前秒数(0-59)
let timeStr = h + ':' + 'm' + 's';
- 性能优化?
- 首屏加载速度指的是什么?
解析url到首屏资源加载完毕
- performance?
performance.timing
- requestanimation 是怎么工作的?如何将不同刷新率的变成一样的?
/*
* 已知动画总时间和总动画距离,根据刷新率,计算每次动画的距离?
* 节流?
*/
- 为什么不用setTimeout做动画?
- opacity的兼容问题?
IE以及更早的版本支持替代的filter属性:例如 filter: Alpha(opacity = 50)
- 如何做浏览器降级处理的?
- 宽度全屏,高度为宽度的1/2,高度随着宽自适应?
- 不同单位的区别?
- 怎么做响应式?
- 为什么代码库大不拆分?
- 动态规划:零钱兑换
- 平方数:按灯
- 二分查找:实现一个Math.sqrt()
输出什么?
var name = 'window'
var p = {
name: "Peter",
getName: function () {
var self = this;
return function() {
return self.name;
}
}
}
var getName = p.getName();
var _name = getName();
console.log(_name)
参考文章链接: