奇怪的代码
总结一下曾经遇到的"奇怪"的代码
变量提升
var b
function b(){}
console.log(b)
// function b(){}
NC 问题
console.log(typeof undefined == typeof NULL) // true
console.log(typeof function () {} == typeof class {}) // true
加法问题
1 + '1' = 11
1 + undefined = NaN
1 + NaN = NaN
1 + null = 1
1 + [] = 1
1 + {} = 1[object Object]
[] + {} = [object Object]
1 + true = 2
1 + false = 1
for 循环的异步
async function sleepNext () {
for(let x = 0; x < 5; x++) {
await new Promise((resolve) => {
setTimeout(() => {
console.log(x)
resolve(true)
}, 1000)
})
}
}
sleepNext()
// 0
// 1
// 2
// 3
// 4
a变量赋值问题
console.log(a); // undefined
var a = 0;
console.log(a) // 0
if (true) {
console.log(a) // function a() {return '123'}
function a() {return '123'}
console.log(a) // function a() {return '123'}
a = 1;
console.log(a) // 1
a = 21;
console.log(a) // 21
}
console.log(a); // function a() {return '123'}
// 据说每个浏览器不同的版本返回的不一样 这是 chrome
var x = [typeof x, typeof y]
var x = [typeof x, typeof y]
// ['undefined', 'undefined']
async await 中 await 在等什么?
function simpleEvent() {
return "simple";
}
async function asyncEvent() {
return Promise.resolve("async event");
}
async function test() {
const v1 = await simpleEvent();
const v2 = await asyncEvent();
console.log(v1);
console.log(v2)
}
test();
// simple
// async event
当返回值不是Promise的话async会阻止同层之后的代码运行,如果不是的话就相当于没有。
indexOf、includes、map、find、forEach
const l = [1, NaN,,];
l.indexOf(1); // 0
l.indexOf(NaN); // -1
l.indexOf(void 0); // -1
l.includes(1); // true
l.includes(NaN); // true
l.includes(void 0); // true
l.find((item, index) => { console.log(index)}) // 0 1 2
l.map((item, index) => { console.log(index) }) // 0 1
l.forEach((item, index) => { console.log(index) }) // 0 1
可以停不下的循环
function createForLoop() {
var list = [1];
var _index = 1;
for (let index = 0; index < list.length; index++) {
console.log(list[index])
_index++;
if (_index < 100) {
list.push(_index)
}
}
}
// 可以 (do while 也可以)
function create() {
var list = [1];
var _index = 1;
for (let item in list) {
console.log(item)
_index++;
if (_index < 100) {
list.push(_index)
}
}
}
// 不可以
function createForEachLoop() {
var list = [1];
var _index = 1;
list.forEach((item, index) => {
console.log(list[index])
_index++;
if (_index < 100) {
list.push(_index)
}
})
}
// 不可以
function createMapLoop() {
var list = [1];
var _index = 1;
list.map((item, index) => {
console.log(list[index])
_index++;
if (_index < 100) {
list.push(_index)
}
})
}
由此可知那些方法会有数组塌陷的风险,针对塌陷倒着触发也是一种好方法。
try...catch不能异步捕获代码错误?
try catch 可以捕获到同步代码的错误但是针对异步代码😮💨。
try {
setTimeout(() => {
// 异步操作中的代码
throw new Error('异步错误');
}, 1000);
} catch (error) {
console.error('捕获到错误:', error.message);
}
// 捕获失败
const asyncErrorFunction = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('异步错误'));
}, 1000);
});
};
asyncErrorFunction()
.catch(error => {
console.log('捕获到错误:', error.message);
});
// 捕获成功
try {
Promise.resolve().then(() => {
throw new Error('err')
})
} catch (err) {
console.log(err);
}
// 捕获失败
try {
await Promise.resolve().then(() => {
throw new Error('err');
});
} catch (err) {
console.log(err.message);
}
// 捕获成功
Symbol.key(1) 和 Symbol(1)
const mp = new WeakMap();
mp.set(Symbol(1), 1); // 可以
mp.set(Symbol.key(1), 1); // 不可以
// 对于WeakSet同样
// WeakMap key(弱键)只能为对象, Symbol.for(1) 其实是注册在全局下的Symbol对应的一个原始值
(,)和=号情况下的this问题
var out = 25
var inner = {
out: 20,
func: function () {
var out = 30
return this.out
}
};
console.log((inner.func, inner.func)())
console.log(inner.func())
console.log((inner.func)())
console.log((inner.func = inner.func)())
// ,赋值会取最后一个的值本身,“值”在全局变量下this指向window
// (inner.func)() 和 inner.func() 一样本身函数调用指向自己
// 赋值表达式和逗号表达式相似,都是返回的值本身,所以也相对于在全局环境下调用函数
赋值
// 第一种
let obj = { num1: 111 };
obj.child = obj = { num2: 222 };
console.log(obj.child); // 输出? undefined
// 第二种
let obj = { num1: 111 }, ref = obj;
obj.child = obj = { num2: 222 };
console.log(obj.child); // 输出? { num1: 111 }
var [ a, b ] = { a:1, b:2 }; (负责人发飙代码)
const a = {a:1,b:2};
Object.prototype[Symbol.iterator] = function() {
// 简单写法
return Object.values(this)[Symbol.iterator]();
// 麻烦写法但是很直观 😓
// let index = 0;
// const keys = Object.keys(this);
// return {
// next() {
// if (index < keys.length)
// {
// return {done: false, value: obj[keys[index++]]}
// }
// return { done:true,value:undefined}
// }
// }
}
const [c, d] = a;
事件循环-空不下来的宏队列(😳)
var a = true;
setTimeout(function(){
a = false;
}, 100)
while(a){
console.log('while执行了')
}
// 请勿尝试 😳
自执行代码(太多了看不过来),搞这么多花样也没啥用原理都一样。
(function(){;}());
(function(){;})();
[function(){;}()];
~function(){;}();
!function(){;}();
+function(){;}();
-function(){;}();
delete function(){;}();
typeof function(){;}();
void function(){;}();
new function(){;}();
new function(){;};
var f=function(){;}();
1,function(){;}();
1^function(){;}();
1>function(){;}();
[] == ![]?
[] == ![] // true
++[[]][+[]]+[+[]] == '10'
// Number([].valueOf()) 为 0
// [[]][+[]] --> ++[[]][0] ---> ++[] ---> 1
// [+[]] --> [0]
// 1 + [0] = '10'
计算无限或判断+0和-0
1/0 = Infinity
1/-0 = -Infinity
取整数
const a = 123.567;
a >> 0;
~~a;
x|0;
Math.floor(x);
a == 1 && a == 2 && a == 3 (脑残代码)
// 第一种
var a = Object.create(null);
a['value'] = 1;
a.toString = function() {
return this.value++;
}
a == 1 && a == 2 && a == 3;
// 第二种
var b = Object.create(null);
b['value'] = 1;
b[Symbol.toPrimitive] = function() {
return this.value++;
}
b == 1 && b == 2 && b == 3;
加法
0.1 + 0.2 = ? // 0.0.30000000000000004
// 二进制的精度问题
赋值
var name = 1;
function name() {
name = 2;
console.log(name);
}
name();
console.log(name);
// 变量提升 1
// 函数提升 2
// name --> void 0
// name --> Function 赋值
// name --> 1 赋值
// 执行name() 报错 name 是 1 不是函数
创建一个函数生成器
// bind处理
function createGenerate() {
const callBack = {
a: 1,
end: false
}
const b = (function* fn() {
while (!this.end) {
this.a++;
console.log(this.a);
yield;
}
}).bind(callBack)()
callBack['b'] = b
return callBack
}
const B = createGenerate();
B.n.next();
// 对象处理
function createGenerate() {
const callBack = {
a: 1,
end: false
}
callBack['#b'] =function* () {
while (!this.end) {
this.a++;
console.log(this.a);
yield this.a;
}
}
callBack['b'] = callBack['#b']()
return callBack
}