- Object map
const data = {};
const element = document.getElementsByClassName('App');
data[element] = 'metadata';
console.log(data['[object HTMLCollection]']) // "metadata"
Object: 字符串-值
Map: 值-值
- Object 与 Set
1 Set的值不重复
2 add delete has方法
ES5/ES6的继承除了写法以外还有什么区别
- calss声名不会提升,类似于let const
const bar = new Bar(); // it's ok
function Bar() {
this.bar = 42;
}
const foo = new Foo(); // ReferenceError: Foo is not defined
class Foo {
constructor() {
this.foo = 42;
}
}
- 内部采用严格模式
// 引用一个未声明的变量
function Bar() {
baz = 42; // it's ok
}
const bar = new Bar();
class Foo {
constructor() {
fol = 42; // ReferenceError: fol is not defined
}
}
const foo = new Foo();
- 方法不可遍历
// 引用一个未声明的变量
function Bar() {
this.bar = 42;
}
Bar.answer = function() {
return 42;
};
Bar.prototype.print = function() {
console.log(this.bar);
};
const barKeys = Object.keys(Bar); // ['answer']
const barProtoKeys = Object.keys(Bar.prototype); // ['print']
class Foo {
constructor() {
this.foo = 42;
}
static answer() {
return 42;
}
print() {
console.log(this.foo);
}
}
const fooKeys = Object.keys(Foo); // []
const fooProtoKeys = Object.keys(Foo.prototype); // []
class定义的方法其实就是定义在prototype上面
class Point {
constructor() {
// ...
}
toString() {
// ...
}
toValue() {
// ...
}
}
// 等同于
Point.prototype = {
constructor() {},
toString() {},
toValue() {},
};
- 异步题目
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
- 实现去重复,升序
var arr = [1,88,[2,3,[4,5]],6,7]
function myFlat(arr){
return arr.reduce((pre,cur) => Array.isArray(cur) ? pre.concat(myFlat(cur)) : pre.concat(cur),[])
}
var res = myFlat(arr).sort((a,b) => a - b)
console.log(res);// [ 1, 2, 3, 4, 5, 6, 7, 88 ]
js异步发展史
- 回调地狱
ajax('xxx',(a) => {
ajax('xxx/a',(b) => {
ajax('xxx/a/b', () => {
})
})
})
可读性差
- Promise
ajax('XXX1')
.then(res => {
// 操作逻辑
return ajax('XXX2')
}).then(res => {
// 操作逻辑
return ajax('XXX3')
}).then(res => {
// 操作逻辑
})
解决回调地狱
无法取消 Promise ,错误需要通过回调函数来捕获
- async await
async function test() {
// 以下代码没有依赖性的话,完全可以使用 Promise.all 的方式
// 如果有依赖性的话,其实就是解决回调地狱的例子了
await fetch('XXX1')
await fetch('XXX2')
await fetch('XXX3')
}
代码清晰,已读,异步终极解决方案
使用注意:
几个请求彼此没有依赖,降低性能
Promise.all([promise1,promise2])
- Promise是同步执行还是异步执行
Promise是同步执行,New Promise 会立即执行立马的函数
then才是异步
Promise只有resolve()后才会执行then
const promise = new Promise((resolve, reject) => {
console.log(1)
resolve()
console.log(2)
})
promise.then(() => {
console.log(3)
})
console.log(4)
// 1 2 4 3
const promise = new Promise((resolve, reject) => {
console.log(1)
<!-- resolve() -->
console.log(2)
})
promise.then(() => {
console.log(3)
})
console.log(4)
// 1 2 4
- 经典作用域提
for (let i = 0; i< 10; i++){
setTimeout(() => {
console.log(i);
}, 10)
}
for (var i = 0; i< 10; i++){
((i) => {
setTimeout(() => {
console.log(i);
}, 10)
})(i)
}
- 常量无法重新赋值,IIFE是函数表达式
var b = 10;
(function b() {
b = 20;
console.log(b) // funtion b
})()
1 IIFE是函数表达式
2 函数表达式变量会提升,但是不会赋予初始值
3 这里的b函数相当于const定义的常量,无法重新赋值(严格报错,非严格赋值失败)
4 所以console的b就是函数b
- 变量提升和函数提升
函数提升优先级高于变量提升
var b = 10;
function b(){
b = 20;
console.log(b);
};
console.log(b); // 10
console.log(a) // f a() { console.log(a) }
console.log(b) //undefined
function a() {
console.log(a)
}
var b = function(){
console.log(b)
}
- == 会隐士转换问题
var a = ?;
if(a == 1 && a == 2 && a == 3){
conso.log(1);
}
var a = {
i: 1,
toString() {
return a.i++;
}
}
if( a == 1 && a == 2 && a == 3 ) {
console.log(1);
}
- 变量提升,IIFE独立作用域
var a = 10;
(function () {
console.log(a)
a = 5
console.log(window.a)
var a = 20; //
console.log(a)
})()
// undefined 10 20
等价于下面:
var a = 10;
(function () {
var a;
console.log(a)
a = 5
console.log(window.a)
a = 20;
console.log(a)
})()
如果换一种
var a = 10;
(function () {
console.log(a)
a = 5
console.log(window.a)
console.log(a)
})()
// 10 5 5
- sleep
const sleep = (time) => {
return new Promise(resolve => setTimeout(resolve, time))
}
sleep(1000).then(() => {
// xx
})