文章目录
- 一、let 关键字
- 特性
- let创建变量代码示例:
- 不允许重复声明:
- 块儿级作用域(局部变量):
- 不存在变量提升:
- 不影响作用域链:
- 应用场景:
- 二、const 关键字
- 特性
- const创建变量代码示例:
- 应用场景:
- 三、变量和对象的解构赋值
- 什么是解构赋值
- 应用场景:
- 四、模板字符串
- 概述:
- 应用场景:
- 五、简化对象和函数写法
- 概述:
- 六、箭头函数
- 概述:
- 箭头函数的注意点:
- 特性:
- 应用场景:
- 七、ES6中函数参数的默认值
- 概述:
- 八、rest参数
- 概述:
- 九、扩展运算符
- 介绍:
- 应用:
- 十、Symbol
- 概述
- 特点
- 基本使用:
- Symbol创建对象属性:
- Symbol内置值:
- 概述:
- 方法:
一、let 关键字
特性
let 关键字用来声明变量,使用 let 声明的变量有几个特点:
- 不允许重复声明;
- 块儿级作用域(局部变量);
- 不存在变量提升;
- 不影响作用域链;
let创建变量代码示例:
// let关键字使用示例:
let a; // 单个声明
let b,c,d; // 批量声明
let e = 100 ; // 单个声明并赋值
let f = 521 , g = 'iloveyou', h = []; // 批量声明并赋值
不允许重复声明:
let dog = "狗";
let dog = "狗";
// 报错:Uncaught SyntaxError: Identifier 'dog' has already been declared
块儿级作用域(局部变量):
let cat = "猫";
console.log(cat);
}
console.log(cat);
// 报错:Uncaught ReferenceError: cat is not defined
不存在变量提升:
// 什么是变量提升:就是在变量创建之前使用(比如输出:输出的是默认值),let不存在,var存在;
console.log(people1); // 可输出默认值
console.log(people2); // 报错:Uncaught ReferenceError: people2 is not defined
var people1 = "大哥"; // 存在变量提升
let people2 = "二哥"; // 不存在变量提升
不影响作用域链:
// 什么是作用域链:很简单,就是代码块内有代码块,跟常规编程语言一样,上级代码块中的局部变量下级可用
{
let p = "大哥";
var s; //p的作用域是块(花括号内)级的,而s的作用域为全局
function fn() {
console.log(p); // 这里是可以使用的
}
fn();
}
应用场景:
以后声明变量使用 let 就对了;
二、const 关键字
特性
const 关键字用来声明常量 ,const 声明有以下特点:
- 声明必须赋初始值·;
- 标识符一般为大写(习惯);
- 不允许重复声明;
- 值不允许修改;
- 块儿级作用域(局部变量);
const创建变量代码示例:
// const声明常量
const DOG = "旺财";
console.log(DOG);
// 1. 声明必须赋初始值;
const CAT;
// 报错:Uncaught SyntaxError: Missing initializer in const declaration
// 2. 标识符一般为大写(习惯);
const dog = "旺财"; // 小写也不错
// 3. 不允许重复声明;
const CAT = "喵喵";
const CAT = "喵喵";
// 报错:Uncaught SyntaxError: Identifier 'CAT' has already been declared
// 注意:对数组元素的修改和对对象内部的修改是可以的(数组和对象存的是引用地址);
// 4. 值不允许修改;
const CAT = "喵喵";
CAT = "咪咪";
// 特例:
const arr = ['55','66'];
arr.push('77'); //arr的中已经接上了‘77’ 这是因为arr指向的地址并没有发生改变
// 报错:Uncaught TypeError: Assignment to constant variable.
// 5. 块儿级作用域(局部变量);
{
const CAT = "喵喵";
console.log(CAT);
}
console.log(CAT);
// 报错:Uncaught ReferenceError: CAT is not defined
应用场景:
声明对象类型使用 const,非对象类型声明选择 let;
三、变量和对象的解构赋值
什么是解构赋值
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值;
// ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值;
// 1、数组的解构赋值
const F4 = ["大哥", "二哥", "三哥", "四哥"];
let [a, b, c, d] = F4;
// 这就相当于我们声明4个变量a,b,c,d,其值分别对应"大哥","二哥","三哥","四哥"
console.log(a + b + c + d); // 大哥二哥三哥四哥
// 2、对象的解构赋值
const F3 = {
name: "大哥",
age: 22,
sex: "男",
xiaopin: function () { // 常用
console.log("我会演小品!");
}
}
let {
name,
age,
sex,
xiaopin
} = F3; // 注意解构对象这里用的是{}
console.log(name + age + sex + xiaopin); // 大哥22男
xiaopin(); // 此方法可以正常调用
//好像只是一个指向
console.log(name===F3.name);//true
console.log(xiaopin===F3.xiaopin);//true
应用场景:
频繁使用对象方法、数组元素,就可以使用解构赋值形式;
四、模板字符串
概述:
模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:
- 字符串中可以出现换行符;
- 可以使用 ${xxx} 形式引用变量
// 声明字符串的方法:单引号('')、双引号("")、反引号(``)
// 声明
let string = `我也一个字符串哦!`;
console.log(string);
// 特性
// 1、字符串中可以出现换行符
let str =
`<ul>
<li>大哥</li>
<li>二哥</li>
<li>三哥</li>
<li>四哥</li>
</ul>`;
console.log(str);
// 2、可以使用 ${xxx} 形式引用变量
let s = "大哥";
let out = `${s}是我最大的榜样!`;
console.log(out);
应用场景:
当遇到字符串与变量拼接的情况使用模板字符串
五、简化对象和函数写法
概述:
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁;
// ES6允许在对象的大括号内直接写入变量和函数作为对象的属性和方法
// 变量和函数
let name = "訾博";
let change = function () {
console.log("活着就是为了改变世界!");
}
//创建对象
const school = {
// 完整写法
// name:name,
// change:change
// 简化写法
name,
change,
// 声明方法的简化
say() {
console.log("言行一致!");
}
}
school.change();
school.say();
六、箭头函数
概述:
ES6允许使用箭头(=>)定义函数,箭头函数提供了一种更加简洁的函数书写方式,箭头函数多用于匿名函数的定义;
箭头函数的注意点:
- 如果形参只有一个,则小括号可以省略;
- 函数体如果只有一条语句,则花括号可以省略,并省略return,函数的返回值为该条语句的执行结果;
- 箭头函数 this 指向声明时所在作用域下 this 的值;
- 箭头函数不能作为构造函数实例化;
- 不能使用 arguments;
特性:
- 箭头函数的this是静态的,始终指向函数声明时所在作用域下的this的值;
- 不能作为构造实例化对象;
- 不能使用 arguments 变量;
// ES6允许使用箭头(=>)定义函数
// 传统写法:无参数
var say = function () {
console.log("hello!");
}
say();
// ES写法2:无参数
let speak = () => console.log("hello 哈哈!");
speak();
// 传统写法:一个参数
var hello = function (name) {
return "hello " + name;
}
console.log(hello("pj"));
// ES6箭头函数:一个参数
let hi = name => "hi " + name;
console.log(hi("pj"));
// 传统写法:多个参数
var sum = function (a, b, c) {
return a + b + c;
}
console.log(sum(1, 2, 3));
// ES6箭头函数:多个参数
let he = (a, b, c) => a + b + c;
console.log(he(1, 2, 3));
// 特性
// 1、箭头函数的this是静态的,始终指向函数声明时所在作用域下的this的值
const school = {
name: "大哥",
}
// 传统函数
function getName() {
console.log("getName:" + this.name);
}
// 箭头函数
getName1 = () => console.log("getName1:" + this.name);
window.name = "訾博";
// 直接调用
getName();
getName1();
// 使用call调用
getName.call(school);
getName1.call(school);
// 结论:箭头函数的this是静态的,始终指向函数声明时所在作用域下的this的值
// 2、不能作为构造实例化对象
let Persion = (name,age) => {
this.name = name;
this.age = age;
}
let me = new Persion("pj",24);
console.log(me);
// 报错:Uncaught TypeError: Persion is not a constructor
// 3、不能使用 arguments 变量
let fn = () => console.log(arguments);
fn(1,2,3);
// 报错:Uncaught ReferenceError: arguments is not defined
应用场景:
- 箭头函数适合与this无关的回调,定时器,数组的方法回调
- 箭头函数不适合与 this 有关的回调,事件回调,对象的方法
七、ES6中函数参数的默认值
概述:
ES允许给函数的参数赋初始值;
//ES6 允许给函数参数赋值初始值
//1. 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
function add(a, b, c = 10) {
return a + b + c;
}
let result = add(1, 2);
console.log(result); // 13
//2. 与解构赋值结合
// 注意这里参数是一个对象
function connect({//参数
host = "127.0.0.1",
username,
password,
port
}) {//函数体
console.log(host)
console.log(username)
console.log(password)
console.log(port)
}
connect({
host: 'atguigu.com',
username: 'root',
password: 'root',
port: 3306
})
八、rest参数
概述:
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments;
// ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments;
// ES5获取实参的方式
function data() {
console.log(arguments);
}
data("大哥", "二哥", "三哥", "四哥");
// ES6的rest参数...args,rest参数必须放在最后面
function data(...args) {
// args是一个数组
console.log(args); // fliter some every map
}
data("大哥", "二哥", "三哥", "四哥");
九、扩展运算符
介绍:
… 扩展运算符
能将数组转换为逗号分隔的参数序列;
扩展运算符(spread)也是三个点(…)。它好比rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包;
// ... 扩展运算符能将数组转换为逗号分隔的参数序列
//声明一个数组 ...
const tfboys = ['易烊千玺', '王源', '王俊凯'];
// => '易烊千玺','王源','王俊凯'
// 声明一个函数
function chunwan() {
console.log(arguments);
}
chunwan(...tfboys); // chunwan('易烊千玺','王源','王俊凯')
应用:
//1. 数组的合并
const kuaizi = ['王太利', '肖央'];
const fenghuang = ['曾毅', '玲花'];
// 传统的合并方式
// const zuixuanxiaopingguo = kuaizi.concat(fenghuang);
const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];
console.log(zuixuanxiaopingguo);
//2. 数组的克隆
const sanzhihua = ['E', 'G', 'M'];
const sanyecao = [...sanzhihua]; // ['E','G','M']
console.log(sanyecao);
//3. 将伪数组转为真正的数组
const divs = document.querySelectorAll('div');
const divArr = [...divs];
console.log(divArr); // arguments
十、Symbol
概述
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的·第七种数据类型·,是一种类似于字符串的数据类型;
特点
- Symbol 的值是唯一的,用来解决命名冲突的问题;
- Symbol 值不能与其他数据进行运算;
- Symbol定义的对象属性不能使用for…in循环遍历 ,但是可以使用Reflect.ownKeys 来获取对象的所有键名;
基本使用:
//创建Symbol
let s = Symbol();
// console.log(s, typeof s);
let s2 = Symbol('尚硅谷');
let s3 = Symbol('尚硅谷');
console.log(s2 == s3); // false
//Symbol.for 创建
let s4 = Symbol.for('尚硅谷');
let s5 = Symbol.for('尚硅谷');
console.log(s4 == s5); // true
//不能与其他数据进行运算
// let result = s + 100;
// let result = s > 100;
// let result = s + s;
//七种数据类型
// USONB you are so niubility
// u undefined
// s string symbol
// o object
// n null number
// b boolean
Symbol创建对象属性:
// 向对象中添加方法 up down
let game = {
name: '俄罗斯方块',
up: function () {},
down: function () {}
};
// 我们要往game对象里面添加方法,但是怕game对象已经存在同名方法,所以我们这时使用到了Symbol
// 方式一
// 声明一个对象
let methods = {
up: Symbol(),
down: Symbol()
};
game[methods.up] = function () {
console.log("我可以改变形状");
}
game[methods.down] = function () {
console.log("我可以快速下降!!");
}
console.log(game);
//调用方法
game[methods.up]();
// 方式二
let youxi = {
name: "狼人杀",
[Symbol('say')]: function () {
console.log("我可以发言")
},
[Symbol('zibao')]: function () {
console.log('我可以自爆');
}
}
console.log(youxi);
let say = Symbol('say'); //'say'类似一个注解作用,没有实际意义
let youxi1 = {
name: "狼人杀",
[say]: function () {
console.log("我可以发言")
},
[Symbol('zibao')]: function () {
console.log('我可以自爆');
}
}
// 调用
youxi1[say]();
Symbol内置值:
概述:
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方
法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行;
Symbol内置值:
概述:
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方
法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行;
方法:
- Symbol.isConcatSpreadable 对象的 Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。
- Symbol.species创建衍生对象时,会使用该属性Symbol.match 当执行 str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值。
- Symbol.replace 当该对象被.replace(myObject)方法调用时,会返回该方法的返回值。
- Symbol.search 当该对象被 str. search(myObject)方法调用时,会返回该方法的返回值。
- Symbol.split 当该对象被 str. split(myObject)方法调用时,会返回该方法的返回值。
- Symbol.iterator 对象进行 for…of 循环时,会调用Symbol.iterator 方法,返回该对象的默认遍历
- Symbol.toPrimitive该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
- Symbol. toStringTag 在该对象上面调用 toString 方法时,返回该方法的返回值
- Symbol. unscopables 该对象指定了使用 with 关键字时,哪些属性会被 with环境排除。
特别的: Symbol内置值的使用, 都是作为某个对象类型的属性去使用 ;
class Person {
static[Symbol.hasInstance](param) {
console.log(param);
///可以自定义类型检测
console.log("我被用来检测类型了");
return false;
}
}
let o = {};
console.log(o instanceof Person);
const arr = [1, 2, 3];
const arr2 = [4, 5, 6];
// 合并数组:false数组不可展开,true可展开
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));