主要记录学习 ES6 笔记,内容包括 let&const、解构赋值(deconstruct)、模板字符串、箭头函数、展开运算符、数组的方法、对象、class、promise 等。
let&const
var
- 同一个变量用 var 可以生命多次
- var 有预解释 变量提升
- var 的作用域问题 全局作用域 函数作用域
- 声明的变量可以更改 没有常亮的概念
let
- 不能重复申明
let name = 'ls';
let name = 'lsls';
// let name = 'lsls' Identifier 'name' has already been declared
- 不存在变量提升
http://localhost:3000
console.log(a); // undefined
var a = 1;
console.log(a); // a is not defined
let a = 1;
块级作用域
不存在变量提升
http://localhost:3000
// var 会污染全局变量 全局作用域 函数作用域
var a = 1;
console.log(window.a); //1
let a = 1;
console.log(window.a); //undefined
// 当一个变量在一个作用域下声明过 这个变量就会绑定在这个作用域
let ls = 1;
if (true) {
console.log(ls); //ls is not defined
let ls = 1;
}
- for 循环
http://localhost:3000
for (var i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i);
}, 0);
} // 3 3 3 异步放入队列 最后执行
// 解决
for (var i = 0; i < 3; i++) {
(function (j) {
setTimeout(function () {
console.log(j);
}, 0);
})(i);
} // 0 1 2
// let 写法
for (let i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i);
}, 0);
} // 0 1 2
- const 不能更改
http://localhost:3000
const PI = 3.14;
PI = 4; // Assignment to constant variable.
// 不能更改引用地址
const OBJ = { ls: '哈哈哈' };
OBJ.ls = '嘿嘿嘿';
console.log(OBJ); // { ls: '嘿嘿嘿' }
解构赋值
解构 等号左边与右边类型
- 数组的解构
http://localhost:3000
let arr = [1, 2, 3];
let [one, two] = arr;
console.log(one, two); //1 2
- 对象的解构
解构变量名与对象 key 一一对应 别名通过“:”命名
http://localhost:3000
let obj = { name: 'ls', age: 20 };
let { name: ls, age, mood } = obj;
console.log(ls, age, mood); // ls 20 undefined
- 默认值
默认值用等号
http://localhost:3000
let obj = { name: 'ls', age: 20 };
let { name: ls, age, mood = 'happy' } = obj;
console.log(ls, age, mood); // ls 20 happy
// 复杂的解构 不想要省略解构
let arr = [{ name: 'zzz', age: 5 }, 'happy', { animal: 'dog' }];
// 想取第二个 第三个animal的值
let [, mood, { animal }] = arr;
console.log(mood, animal); // happy 'dog'
模板字符串
- 模板字符串
http://localhost:3000
let animal = 'dog';
let age = 2;
// let str = "这个动物是" + "\"" + animal + "'," + age + "岁了"
let str = `这个动物是${animal},已经${age}岁了`;
console.log(str); //这个动物是'dog',2岁了
- 拼接 dom 换行
http://localhost:3000
let animal = 'dog';
let age = 2;
let str = `<ul>
<li>${animal}</li>
<li>${age}</li>
</ul>`;
console.log(str);
/*
<ul>
<li>dog</li>
<li>2</li>
</ul>
*/
- 实现模板字符串
http://localhost:3000
let animal = 'dog';
let age = 2;
let str = '<ul><li>${animal}</li><li>${age}</li></ul>';
let newStr = str.replace(/\$\{([^}]+)\}/g, function () {
// return arguments[1] //<ul><li>animal</li><li>age</li></ul>
return eval(arguments[1]); //<ul><li>dog</li><li>2</li></ul>
});
console.log(newStr);
- 自定义标签
http://localhost:3000
// 输出结果英文全部大写
let animal = 'dog';
let age = 'two';
let str = `这个动物是${animal.toUpperCase()},已经${age.toUpperCase()}岁了`;
console.log(str); //这个动物是DOG,已经TWO岁了
// 统一处理
// tag 自定义函数名
let animal = 'dog';
let age = 'two';
function tag(params) {
// console.log(arguments); // { '0': [ '这个动物是', ',已经', '岁了' ], '1': 'dog', '2': 'two' }
let args = Array.prototype.slice.call(arguments, 1);
console.log(args, params);
let str = '';
for (var i = 0; i < args.length; i++) {
str += params[i] + args[i].toString().toUpperCase();
}
str += params[params.length - 1];
return str;
// return 1 // str 打印 1 str根据此函数返回结果
}
let str = tag`这个动物是${animal},已经${age}岁了`;
console.log(str); //这个动物是DOG,已经TWO岁了
- 字符串常用方法
查找字符串内容 includes
http://localhost:3000
let str = 'dsjfioalsjfoaj';
console.log(str.indexOf('ls')); // 7
console.log(str.includes('ls')); //true
判断开头结尾 startsWith
endsWith
http://localhost:3000
let url = 'https://www.baidu.com';
console.log(url.startsWith('https')); // true
console.log(url.endsWith('.com')); //true
字符串补全长度 padStart
和padEnd
http://localhost:3000
let date = new Date();
let h = date.getHours().toString();
let m = date.getMinutes().toString();
let s = date.getSeconds().toString();
let time = `${h.padEnd(3, 0)}:${m.padStart(3, 0)}:${s.padStart(3, 'oaao')}`;
console.log(time); //110:054:o23
http://localhost:3000
'x'.padStart(5, 'ab'); // 'ababx'
'x'.padStart(4, 'ab'); // 'abax'
'x'.padEnd(5, 'ab'); // 'xabab'
'x'.padEnd(4, 'ab'); // 'xaba'
上面代码中,padStart
和padEnd
一共接受两个参数,第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串。
函数 function
- 设置默认值
http://localhost:3000
function ajax(url,method = 'get) {
// 设置默认值
this.method = method || 'get'
}
ajax('/test', 'get')
- ... 运算符
将函数剩下的参数 变成数组 只能放到参数最后面
http://localhost:3000
function sum(one, ...arg) {
return one + eval(arg.join('+'));
}
sum('¥', 1, 3, 4, 6, 7);
- 箭头函数
http://localhost:3000
// 箭头函数 没有function 的关键字, 没有this执行 没有arguments
// 谁调用的this就是谁 箭头函数中没有this 就会向上找 找到后返回
let a = 1;
let obj = {
a: 2,
fn: function () {
setTimeout(() => {
console.log(this.a);
}, 0);
},
};
let fn = obj.fn();
// 对象不是作用域,作用域只有函数和 { } 全局
let a = 1;
let obj = {
a: 2,
fn: () => {
// this
console.log(this); //Window
},
fun() {
//this
console.log(this);
},
};
obj.fn();
obj.fun();
展开运算符
在对象或数组中 ... 展开运算符 扩展运算符
数组
http://localhost:3000
let arr = [1, 2, 3];
let arr1 = [4, 5, 6];
let arr3 = [...arr, ...arr1];
console.log(arr3); // [ 1, 2, 3, 4, 5, 6 ]
// es5 实现 [].concat(arr, arr1)
对象
http://localhost:3000
let obj1 = { animal: 'dog' };
let obj2 = { age: 00 };
let result = { ...obj1, ...obj2 };
console.log(result); //{ animal: 'dog', age: 0 }
// $.extend({}, obj1, obj2)
// Object.assign()
let obj3 = Object.assign({}, obj1, obj2);
console.log(obj3);
- 深拷贝和浅拷贝
- 对象拷贝 浅拷贝(对象里存的是地址空间,令一个对象改变了空间,也会导致当前对象更改)
浅拷贝
http://localhost:3000
let animal = { kind: { kind: 'dog' } };
let result = { ...animal }; // Object.assign({}, animal) 都是浅拷贝
console.log(result); //{ kind: { kind: 'dog' } }
console.log(animal === result); //false
animal.kind.kind = 'cat';
console.log(result); //{ kind: { kind: 'cat' } }
深拷贝
http://localhost:3000
// 使用 JSON方法 对象中有函数 不会被拷贝
let animal = { kind: { kind: 'dog' } };
let res = JSON.parse(JSON.stringify(animal));
animal.kind.kind = 'cat';
console.log(res); // { kind: { kind: 'dog' } } 没有改变
递归拷贝
http://localhost:3000
let animal = {
kind: { kind: 'dog' },
skill: ['run', 'fly'],
mouth: 1,
eye: 'two',
};
function deepClone(parent, c) {
// parent 要拷贝的对象
let child = c || {};
// console.log(parent, child)
for (let key in parent) {
if (parent.hasOwnProperty(key)) {
let val = parent[key];
// 判断value的值 是否引用类型
if (typeof val === 'object') {
// 新增key值 为 引用类型
child[key] =
Object.prototype.toString.call(val) === '[object Array]' ? [] : {};
// 再次调用 传入要拷贝的引用类型 ,及拷贝到哪儿
// console.log(val, child[key])
deepClone(val, child[key]); // { kind: 'dog' } {}
} else {
child[key] = parent[key];
}
}
}
return child;
}
var a = deepClone(animal);
console.log(a);
展开运算符
http://localhost:3000
function mapActions() {
return { name: 1, age: 2 };
}
let obj = {
...mapActions(),
};
Math.min(1, 2, 3, 4, 5);
let arr = [1, 2, 3, 4, 5];
Math.min.apply(Math, arr);
Math.min(...arr);
function add(a, b) {
return a + b;
}
let fn = (a, b, c, ...args) => {
console.log(add(...args));
};
fn(1, 2, 3, 4, 5);
数组方法
- Array.from()
将类数组转化数组 arguments dom 对象
http://localhost:3000
let arr = Array.from({ 0: 1, 1: 2, 2: 3, length: 3 });
console.log(arr);
function arr() {
console.log(arguments);
}
arr(1, 2, 3);
[...]
需要当前类数组有“迭代器”
什么是迭代器? 迭代器需要返回一个对象 上有一个 next 方法 每次调用 next 方法返回一个新对象,对象上有两个属性,分别是 value 和 done
http://localhost:3000
let obj = {
0: 1,
1: 2,
2: 3,
length: 3,
[Symbol.iterator]: function () {
let index = 0; // 当前迭代到了第几个
let self = this; //this指代当前对象
return {
next: function () {
//value 代表的是当前的内容 done是否迭代完成
return {
value: self[index],
done: index++ === self.length ? true : false,
};
},
};
},
};
let arr = [...obj];
console.log(arr);
// 迭代器就是next 方法 直到done为true就结束
- Array.of() 和 fill()
http://localhost:3000
Array(3); // [ <3 empty items> ] 长度为3
Array.of(3); // [ 3 ] 数组有一项叫3
Array(3).fill(1); // [1, 1, 1] 数组的填充
- copyWithin
http://localhost:3000
var a = [1, 2, 3, 4, 5, 6].copyWithin(0, 2, 4);
console.log(a); //[ 3, 4, 3, 4, 5, 6 ]
- reduce
http://localhost:3000
// prev 代表的是数组的第一项
// next 代表的是数组的第二项
// 当前迭代到了第几项
// current 当前数组
// reduce 会将执行后的结果回座位下次的 prev
// 参数可以多加一项
Array.prototype.myReduce = function (callback) {
let prev = this[0];
for (var i = 0; i < this.length; i++) {
prev = callback(prev, this[i], i, this); // 函数返回结果 会作为下一次的prev
}
return prev;
};
//
let res = [1, 2, 3, 4, 5].reduce((prev, next, currentIndex, current) => {
console.log(prev, next, currentIndex);
if (currentIndex === current.length - 1) {
// 求平均数
return (prev + next) / current.length;
}
return prev + next; // 求和
});
console.log(res);
- map
http://localhost:3000
Array.prototype.myMap = function (callback) {
let newArr = [];
for (var i = 0; i < this.length; i++) {
newArr.push(callback(this[i], i));
}
return newArr;
};
let res = [1, 2, 3].map((item, index) => {
return `<li>${item}</li>`;
});
console.log(res);
其他方法
http://localhost:3000
// find只会找一个 找到后停止 返回true表示找到, 会吧当前项返回
// 声明式 编程式
let i = [1, 2, 3, 4, 5].find((item, index) => {
return item > 3;
});
console.log(i);
// some
let i = [1, 2, 3, 4, 4, 4, 4, 4, 4].some((item, index) => {
console.log(index);
return item === 4;
});
console.log(i);
// every
let i = [1, 2, 3, 4, 4, 4, 4, 4, 4].every((item, index) => {
console.log(index);
return item === 4;
});
console.log(i);
// filter 过滤 返回一个过滤后的数组, 方法中返回true 表示留下 返回新数组
let i = [1, 2, 3, 4, 5].filter((item, index) => {
return item > 3;
});
console.log(i);
// for of 遍历数组 / for in 可以遍历对象和数组
let arr = [1, 2, 3, 4, 5];
// for (let a of arr) {
// console.log(a)
// }
// es 7
arr.includes(2);