一、let 关键字
(1)不允许重复声明
let name = '黑崎一护'
let name = '佐助'
console.log(name);
// SyntaxError
let num = 1;
num = 2;
console.log(num);//2
// 可以重复赋值
(2)不存在预解析
(3)不影响作用域链
(4)拥有块级作用域
具有暂时性死区特性
与当前作用域进行绑定,与外部变量无关。
var num=10;
if(true){
console.log(num);//not defined
let num=20;
//使用let声明的变量,会与当前作用域进行绑定,与外部变量无关。
}
// 防止循环变量变成全局变量
for(let i=0;i<2;i++){
}
console.log(i);//i is not defined
let arr =[];
for(let i=0;i<2;i++){
// 每次循环产生一个新的块级作用域,每个块级作用域的变量是不同的,
// 函数输出的是自己的上一级(循环产生的块级作用域)作用域下i的值
arr[i]=function(){
console.log(i);
}
}
arr[0]();//0
arr[1]();//1
二、const 关键字
声明一个变量,但变量的值不能无法改变,必须要有初始值。
(1)不允许重名
(2)不存在预解析
(3)不影响作用域链
(4)拥有有块级作用域
(5)可以修改数组和对象元素
// 定义数组
const product = [
{
name:'背心',
price:100,
},
{
name:'吊带',
price:50,
}
]
// 向数组中添加新的商品
product.push({
name:'拖鞋',
price:100
})
console.log(product)
三、解构赋值(重)
1、定义
从数组或对对象中提取数据,并赋值给变量。
方便获取数组中的数据,获取对象中属性和方法。
2、数组解构赋值
let arr=[1,2,3];
// 定义变量并接收
let [s1,s2,s3]=arr;// 完全解构
let [s1,,s3]=arr; // 不完全解构
console.log(s1);// 1
3、对象的解构赋值
// 对象的解构赋值
const obj = {
name: '张三',
age,
sayHi: function () {
console.log('你好')
}
}
// 定义变量,对应属性,想要什么属性就写什么属性
const { name, sayHi } = obj
console.log(name);// 张三
sayHi();// 你好
//为属性取别名
const {name:defaultName,sayhi} = obj;
console.log(defaultName);
//设置属性默认值
const {age=20} = obj;
console.log(age);//20
4、复杂的结构赋值
// 复杂的解构赋值
const person = {
name: '张三',
cars: [
'奔驰',
'宝马',
'奥迪',
],
dogs: {
dogname: '大黄',
age: 2
}
};
// 从person对象中结构出name和age,还有cars中的三个数据
const { name, cars: [car1, car2], dogs: { dogname } } = person;
// 打印时直接打印最内层数据
console.log(car1);//宝马
console.log(car2);//奥迪
console.log(dogname);//大黄
四、简化对象的写法
1、省略同名的属性值
const name = '小明'
const age = 20
const eat = function () {
console.log('吃了吗您')
}
var obj = {
name,
age,
eat
}
console.log(obj.name)//小明
console.log(obj.age)//20
obj.eat()
//与解构赋值一起使用
var obj={
name:'张三',
age:15,
play:function(){
console.log('玩泥巴');
}
}
const{name,age,play}=obj;
var obj={
name,
age,
play
}
console.log(obj.name);//张三
obj.play();//玩泥巴
2、省略方法的function
var obj2 ={
age:100,
eat(){
console.log('吃了啊')
}
}
五、模版字符串
1、作用
简化字符串的拼接
(2)语法
用 `` 表示,变量使用${xxx}表示
const age = 100
const text = `今年过年,小明的年龄已经是:${age}`;
console.log(text)
document.write(`
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
`)
六、箭头函数
用来定义匿名函数,简化了function的写法
this.handleChange=name=>{
return e=>{
this.state({
[name]:e.target.value
})
}
}
// 第一个函数的参数name 第二个函数的参数e
handleChange = name => e => {
this.setState({
[name]: e.target.value
})
}
handleChange=name=>e=>{
this.setState({
[name]:e.target.value
})
}
1、 基本语法
let add = (a, b, c) => {
return a + b + c
};
console.log(add(10,20,30))
2、一个参数
// 可以省略前边的小括号
const f2 = a => {
console.log(a)
};
f2(10);
3、有返回结果
// 省略大括号
const f4 = (a, b) => a + b
console.log(f4(100, 200));
4、使用场景: (定时器,数组中常用方法)
// 需求:点击按钮,1秒后变大
document.getElementById('btn').addEventListener('click', function () {
var that = this
setTimeout(() => {
that.style.width = '200px'
that.style.height = '300px'
}, 1000);
}, false)
//需求2 获取数组的偶数数据
var arr = [10, 20, 30, 40, 1, 2];
var newArr = arr.filter((item, index) => {
//凡是能执行item都能放到新数组中
if (item % 2 == 0) {
return true;
} else {
return false;
}
});
console.log(newArr);
//更简单的方式
var newArr1 = [1, 2, 3, 4, 5].filter(item => item % 2 === 0);
console.log(newArr1);
6、箭头函数的this是不能改变
- 箭头函数没有自己的this
- 箭头函数的this始终指向函数定义时候的this
- 包裹箭头函数的第一个普通函数
7、不能作为构造函数使用
8、arguments不能使用
七、形参默认值
function f1(a, b = 20, c = 10) {
console.log(a + b + c)
}
f1(10, 40)//60
function request({ host, port='5000', user, password }) {
console.log(host)
console.log(port)
console.log(user)
console.log(password)
}
request({ host: 'localhost', port: '8080', user: 'admin', password: '123' })
//localhost 8080 admin 123
八、延展运算符
拆包和打包数组、对象
function f2(...args) {
console.log(args)
}
f2(1, 2, 3, 4, 5);
// // [1, 2, 3, 4, 5]
function f3(...args) {
console.log(...args)
}
f3(1, 2, 3, 4, 5);
//1 2 3 4 5
1、数组合并
var arr1=[10,20,30];
var arr2=[40,50,60];
var arr=[...arr1,...arr2];
console.log(arr);
// [10, 20, 30, 40, 50, 60]
2、对象合并
字面量复制对象 let obj={ } {…obj}
var obj1={
name:'自来也',
age:45
}
var obj2={
gender:'男',
hobby(){
console.log(console.log('吃饭'))
}
}
var obj={
name:'菲儿',
...obj1,
...obj2
}
console.log(obj);
// {name: "自来也", age: 45, gender: "男", hobby: ƒ}
3、数组的克隆
const arr3 = [10, 20, 30]
const arr4 = [...arr3]
console.log(arr4)
// [10, 20, 30]
4、伪数组转真数组
const arr5 = document.getElementsByTagName('button');
console.log(arr5);
//[button, button, button]
console.log(arr5 instanceof Array);//false;
console.log([...arr5] instanceof Array);//true
console.log(arr5);
九、剩余参数
// ...args代替arguments 获取函数调用时传递的参数,返回值真数组
// 利用args打印数据
function f2(...args) {
console.log(args);
// 真数组 --[1,2,3]
}
f2(1, 2, 3)
// 形参较多,放在最后位置
function f3(a, b, ...args) {
console.log(a,b);//1,2
console.log(args);// [3,4,5]
//
}
f3(1, 2, 3, 4, 5)
// 结合结构赋值
let arry=['张三','李四','王五'];
let[s1,...s2]=arry;
console.log(s1);//张三
console.log(s2);//[李四,王五]
十、Symbol
1、特点
ES6中的添加了一种原始数据类型Symbol
- Symbol 属性对应的值是唯一的,解决命名冲突问题
- Symbol 值不能与其他数据进行计算,包括同字符串拼串
- for in , for of 遍历时不会遍历symbol 属性
2、使用
// - 调用Symbol 函数得到symbol 值
let symbol1 =Symbol(); //Symbol()
let symbol2 =Symbol(); //Symbol()
consoele.log(symbol1===symbol2);//false
// - 传参标识
let symbol = Symbol('one')
let symbol2 = Symbol('two')
console.log(symbol) // Symbol(one)
console.log(symbol2) // Symbol(two)
// - 定义常量,就是标识
- const person_key = Symbol('person_key')
- console.log(person_key)
3、内置Symbol值
// - 对象的Symbol.iterator属性,指向该对象的默认遍历器方法
// 通过Symbol向对象中添加方法
const person={
eat(){
console.log('我爱吃')
},
run(){
console.log('跑着吃')
}
}
//在对象中添加方法 唯一的
const obj={
eat:Symbol('eat'),
run:Symbol('run')
}
//相当于 [Obj.eat] = Symbol('eat')
person[obj.eat]=function(){
console.log('新的吃的方法');
};
person[obj.run]=function(){
console.log('新的跑的方法')
}
//调用方法
person.eat();
person.run();
person[obj.eat]();//新的吃的方法
十一、set集合
(1)是一个构造函数,用来存储任意数据类型的唯一值;
(2)可以存储数组、字符串,返回值是一个对象。
1、定义Set 集合
// 定义set集合
const s1 = new Set()
console.log(s1)
// { }
//打印长度
console.log(s1.size);// 0
2、传入数据
const s = new Set([10,20,30,40,40]);
console.log(s);
// {10, 20, 30, 40}
// 打印出来是一个集合 需要拆包
console.log(...s);
// 10 20 30 40
3、set方法
(1) 添加数据
const s = new Set();
// 向Set集合中添加一个数据
s.add('a').add('b');
console.log(...s);
// a b
(2) 移除数据
r1 = s.delete('a');
console.log(r1);
// 返回结果是ture值,代表删除成功
(3) 是否存在这个数据
r2 = s.has(9);
console.log(r2);//false
(4) 清空数据
r3 = s.clear()
console.log(r2);// undefined
4、应用
(1)数组去重
let arr1=[1,2,3,4,4,5,1];
// {1, 2, 3, 4, 5} 1,2,3,4,5 []
let arr2=[...new Set(arr1)];
console.log(arr2);
// [1, 2, 3, 4, 5]
(2)交集操作
const arr3 = [1, 2, 3, 4, 5, 6, 7];
const arr4 = [1, 2, 3, 10, 11];
//对数组进行拆包 过滤 判断4里面是否存在item
const result = [...new Set(arr3)].filter(item => new Set(arr4).has(item));
console.log(result);
(3)并集操作
const arr5 = [1, 2, 3, 4, 5];
const arr6 = [1, 2, 3, 6, 7, 8];
const result = [...new Set([...arr5,...arr6])]
console.log(result);
(4)差集操作
我有的你没有,或者你有的我没有
const arr7 = [1, 2, 3, 4, 5];
const arr8 = [1, 2, 3, 8, 9];
// 判断arr8中是否含有数组中每一项数据
const result=[...new Set(arr7)].filter(!(item=>new Set(arr8).has(item)));
const result=[...new Set(arr8)].filter()
十二、map集合
类似于对象,存放键值对,键和值可以使任何数据类型。
1、键值的方式添加数据
var m = new Map();
map.set('name', '强哥')
map.set(obj, function(){console.log('真好')})
2、读取 删除 判断 清空
// 根据键获取值
console.log(map.get(obj))
// 根据键进行删除
map.delete('name')
// 根据键进行判断
console.log(map.has('name'))
// 清空map
map.clear()
十三、class实例化对象
- class是es6中的语法糖,最终还是转化成构造函数去执行
- 在类中通过 构造器方法初始化实例化对象属性
//constructor方法是类的构造方法,传递参数,返回实例对象,如果没有显示定义,类内部会自动给我们 - 会将方法自动加到原型上
class Person{
// 构造函数 -- 初始化实例化对象属性
constructor(name,age){
this.name=name;
this.age= age;
}
// 添加方法 不需要添加,
eat(){
console.log('哈哈')
}
}
const per = new Person('小明',20);
console.log(per.name);
per.eat();
十四、静态成员
1、es5实现静态成员
静态属性、静态方法----》静态成员
属于构造函数,实例不继承
function Person(age){
// 实例属性
this.age=age;
// 实例方法
this.eat=function(){
console.log('下雨了,还要吃')
}
}
// 静态属性
Person.age=100;
// 静态方法
Person.run=function(){
console.log('哈哈')
}
var per =new Person(10);
// 通过Person来调用的
console.log(per.age);
console.log(Person.age);
2、es6中实现静态成员
把静态属性和静态方法 添加到类上 最终类来调用
class Person{
constructor(age){
this.age=age;
}
//添加静态成员
static name="人类";
//添加静态属性
static eat(){
console.log('人都要吃饭')
}
}
//使用静态成员
console.log(Person.name);
//调用静态方法
Person.eat();
十五、继承
1、构造函数+原型对象
fn.call(o);
// 1、父构造函数
function Father(uname,age){
this.uname=uname;
this.age=age;
}
// 2、子构造函数
function Son(uname,age){
// 父构造函数的this指向子构造函数
// 子构造函数可以使用父类方法
Father.call(this,uname,age);
}
var son=new Son('刘德华',18);
console.log(son)
// 函数都是Function的实例
2、extends实现继承
如果子类没有写constructor,那么底层会自动调用父类的constructor
如果写了constructor,底层代码会被覆盖,必写super,目的调用父类的constructor。
class Person {
constructor(name, color) {
this.name = name;
this.color = color;
}
eat() {
console.log('哈哈');
}
}
class Student extends Person {
// 继承属性
constructor(name, color, age) {!!!!!
// 让子类调用父类的构造器
super(name, color);!!!!!!!!!!!!!
// 新增属性
this.age = age
}
run() {
console.log('跑起来');
}
// 重写父级的方法
eat(){
console.log('我要吃鸡腿');
}
}
const stu = new Student('强哥','黄色',20)
console.log(stu)
stu.eat();
stu.run();
十六、getter和setter方法
在获取属性时,做自定义判断。
// getter和setter的设置
class Person{
// 实例对象的属性的 设置和获取 操作
get name(){
return this.n
}
set name(val){
this.n = val
}
// 静态属性的设置 和 获取 操作
static get color(){
return '黄色'
}
static set color(val){
console.log(val)
}
}
const p = new Person()
p.name = '小明';
console.log(p.name);
console.log(Person.color)
十七、对象扩展
1、Object.is(,)
判断两个值是否相等
NaN=NaN
console.log(Object.is(1, '1'));//fasle
console.log(Object.is(1, 1));//true
console.log(Object.is({}, {}));//false
console.log(Object.is(NaN, NaN));//true
2、Object.assign(新对象,合并对象)
对象的合并
const obj1 = {
name: 'atguigu'
};
const obj2 = {
age: 8,
name: '尚硅谷'
}
// 相同属性会覆盖
Object.assign(obj1, obj2);
console.log(obj1);
// {name: "尚硅谷", age: 8}
3、直接修改 proto 设置原型对象
const obj = {
name: 'atguigu'
};
const obj2 = {
age: 8
};
obj2.__proto__ = obj;
console.log(obj2);