let const 解构赋值 模板字符串 箭头函数 rest 扩展运算符 Symbol
1. var let const的区别
(1)const定义的变量不可以修改,而且必须初始化。
const b = 2;//正确 // const b;//错误,必须初始化 console.log('函数外const定义b:' + b);//有输出值 // b = 5; // console.log('函数外修改const定义b:' + b);//无法输出
(2)var定义的变量可以修改,如果不初始化会输出undefined,不会报错。
var a = 1; // var a;//不会报错 console.log('函数外var定义a:' + a);//可以输出a=1 function change(){ a = 4; console.log('函数内var定义a:' + a);//可以输出a=4 } change(); console.log('函数调用后var定义a为函数内部修改值:' + a);//可以输出a=4
(3)let是块级作用域,函数内部使用let定义后,对函数外部无影响。
let c = 3; console.log('函数外let定义c:' + c);//输出c=3 function change(){ let c = 6; console.log('函数内let定义c:' + c);//输出c=6 } change(); console.log('函数调用后let定义c不受函数内部定义影响:' + c);//输出c=3
var 和 let 第一点不同就是 let 是块作用域,即其在整个大括号 {} 之内可见。如果使用 let 来重写上面的 for 循环的话,会报错
var:只有全局作用域和函数作用域概念,没有块级作用域的概念。但是会把{}内也假称为块作用域。
let:只有块级作用域的概念 ,由 { } 包括起来,if语句和for语句里面的{ }也属于块级作用域。
1.1. let
1.1.1. 特性
(1)变量不能重复声明
(2)块级作用域(if else while for…)全局、函数、eval(严格模式)
(3)不存在变量提示
(4)不影响作用域链
{
let name = 'wufeng';
const fn = () => {
console.log(name); // wufeng
};
fn();
}
1.1.2. 案例
点击方块变色(var let)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.item {
width: 50px;
height: 30px;
border: 1px solid red;
margin-right: 10px;
float: left;
}
</style>
</head>
<body>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<script>
let items = document.querySelectorAll('.item');
//使用var,循环结束此时i为3,items[3] undefined 报错
// for (var i = 0; i < items.length; i++) {
// items[i].onclick = () => {
// items[i].style.background = 'pink';
// };
// }
//使用let 块级作用域互不影响
for (let i = 0; i < items.length; i++) {
items[i].onclick = () => {
items[i].style.background = 'pink';
};
}
</script>
</body>
</html>
使用var 声明,报错
1.2. const 常量
1.2.1. 特性
(1)一定要赋初始值
(2)值不能修改
(3)变量名尽量使用大写
(4)块级作用域
(5)对对象、数组的元素修改,不算对常量的修改,不会报错(指向的地址没有变化)
const ITEM = ['wufeng', 'wujie', 'sharp', 'jack'];
ITEM[2] = 'Sharp';
ITEM[3] = 'Jack';
console.log(ITEM);
如果直接改变数组、对象常量的类型,则会报错
ITEM = 100;
变量解构赋值
允许一定模式从数组、对象中提取值,对变量进行赋值,称之为解构赋值。
1.2.2. 数组
const WORD = ['a', 'b', 'c'];
let [a, b, c] = WORD;
console.log(a, b, c); // a b c
也可使用扩展运算符 …
const WORD = ['a', 'b', 'c'];
console.log(...WORD); // a b c
1.2.3. 对象
变量的名称必须与对象的key保持一致
const OBJ = {
a: 'a',
b: 'b',
c: 'c'
};
let {
a, b, c } = OBJ;
console.log(a, b, c); // a b c
也可对key进行重新命名
const OBJ = {
a: 'a',
b: 'b',
c: 'c'
};
let {
a: d, b: e, c: f } = OBJ;
console.log(d, e, f);
console.log(a, b, c);
2. 模板字符串
2.1. 反引号 ``
模板字符串可以换行书写,无需 \n 换行符
可以在模板字符串中直接使用变量,无需使用: + 变量 +,用法:${变量}
const e = 'wufeng';
let str = `
a
b
c
d
${
e}
`;
console.log(str);
2.2. 对象简化写法
属性名与value变量名一样时,可以简写,name:name —> name
const name = 'wufeng';
const eat = () => {
console.log('吃饭');
};
const people = {
name,
// name: name
eat,
// eat: eat
speak() {
console.log('hello');
}
// speak: function () {
// console.log('hello');
// }
};
console.log(people);
3. 箭头函数
箭头函数适合与this无关的函数回调,定时器、数组方法的回调等
不适合与this有关的函数回调,DOM元素的事件回调、对象方法的回调等
3.1. 特性
this是静态的,始终指向函数声明时所在作用域下this的值(call、apply等方法无法改变this)
function getName() {
console.log(this.name);
}
const getName2 = () => {
console.log(this.name);
};
window.name = 'wufeng';
const obj = {
name: 'obj'
};
getName(); // wufeng
getName2();// wufeng
getName.call(obj); // obj 改变this指向为obj
getName2.call(obj);// wufeng 依然指向window(声明时所在的作用域)
不能作为构造函数实例化对象
const People = (name, age) => {
this.name = name;
this.age = age;
};
const p1 = new People('wufeng', 18);
console.log(p1);
不能使用arguments变量
const fn = () => {
console.log(arguments);
};
fn(1, 2, 3);
普通函数使用arguments 变量
function fn() {
console.log(arguments);
}
fn(1, 2, 3);
3.2. 简写
当只用一个形参时,可以省略()
const fn = name => {
console.log(name);
};
fn('wufeng');
当函数体只有一条语句时,可以省略{},return 也必须省略,语句的执行结果就是返回值
const fn = () => console.log('wufeng');
fn();
3.2. 案例
点击div,2s后变色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.ad {
width: 200px;
height: 200px;
background-color: blue;
}
</style>
</head>
<body>
<div class="ad"></div>
<script>
const ad = document.querySelector('.ad');
// ad.addEventListener('click', function () {
// let _this = this;
// setTimeout(function () { // 定时器function this指向windows
// _this.style.background = 'pink';
// }, 2000);
// });
ad.addEventListener('click', function () {
setTimeout(() => {
// 箭头函数this指向声明时所在作用域的this
this.style.background = 'pink';
}, 2000);
});
</script>
</body>
</html>
返回数组中的偶数
const arr = [1, 3, 4, 56, 456, 434, 3432, 2345, 565, 4623, 42, 4, 2, 3, 3, 5634];
// const result = arr.filter(function (item) {
// return item % 2 === 0;
// });
const result = arr.filter(item => item % 2 === 0);
console.log(result);
4. rest参数
ES5 arguments为对象,ES6 rest参数为数组
const sum = (a, b, ...args) => {
let total = 0;
// args = [3, 4]
args.forEach(item => (total += item));
return total;
};
console.log(sum(1, 2, 3, 4));
扩展运算符 …
扩展运算符… 可以将数组转换为以 , 分割的参数序列
const num = [1, 2, 3];
function fn() {
console.log(arguments);
}
fn(num);
fn(...num);
fn(num) 返回一个参数,fn(…num)返回三个参数
4.1. 应用
1、数组的合并
const num = [1, 2, 3];
const str = ['a', 'b', 'c'];
// const arr = num.concat(str);
const arr = [...num, ...str];
console.log(arr); // [1, 2, 3, "a", "b", "c"]
2、数组克隆(浅拷贝)
const num = [1, 2, 3];
const num1 = [...num];
3、将伪数组转变为数组
const divs = document.querySelectorAll('div'); // 伪数组
const divArr = [...divs];
4.2. Symbol数据类型
ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。
ES6 数据类型除了 Number 、 String 、 Boolean 、 Objec t、 null 和 undefined ,还新增了 Symbol 。
Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的 Symbol 提供描述,用来显示在控制台或者作为字符串的时候使用,便于区分。
let s = Symbol();
let s1 = Symbol('w'); // 'w' 仅是描述
let s2 = Symbol('w');
console.log(s1 === s2); // false
let s3 = Symbol.for('w');
let s4 = Symbol.for('w');
console.log(s3 === s4); // true
不能与其他数据类型进行运算 (+,-,*,<,>,拼接等)
值是唯一的,用来解决命名冲突的问题
定义的对象属性不能使用for in 遍历,使用Reflect.ownKeys获取所有键名
作用:为对象添加属性、方法
为对象添加一个独一无二的属性或方法
const obj = {
name: 'gg',
[Symbol('say')]: () => {
console.log('say');
},
[Symbol('eat')]: () => {
console.log('eat');
}
};
console.log(obj);
5. 内置属性
除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法
1、Symbol.haslnstance
一个在执行instanceof时调用的内部方法,用于检测对象的继承信息
2、Symbol.isConcatSpreadable
一个布尔值,用于表示当传递一个集合作为Array.prototype.concat()方法的参数时,是否应该将集合内的元素规整到同一层级
3、Symbol.iterator
一个返回迭代器的方法
4、Symbol.match
一个在调用String.prototype.match()方法时调用的方法,用于比较字符串
5、Symbol.replace
一个在调用String.prototype.replace()方法时调用的方法,用于替换字符串的子串
6、Symbol.search
一个在调用String.prototype.search()方法时调用的方法,用于在字符串中定位子串
7、Symbol.species
用于创建派生类的构造函数
8、Symbol.split
一个在调用String.prototype.split()方法时调用的方法,用于分割字符串
9、Symbol.toprimitive
一个返回对象原始值的方法
10、Symbol.ToStringTag
一个在调用Object.prototype.toString()方法时使用的字符串,用于创建对象描述
11、Symbol.unscopables
一个定义了一些不可被with语句引用的对象属性名称的对象集合