ES6
内容纲要
let块级作用域
let和var的主要区别
- let声明的变量只在当前(块级)作用域内有效
- let声明的变量不能被重复声明
- 不存在变量提升
- 暂存死区(不能使用父级变量)
ES6之前的作用域
- 全局作用域
- 函数作用域
- eval作用域
块级作用域
- 通俗的讲就是一对花括号中的区域{ ... }
- if () {}
- switch () { }
- for() { }
- try{ } catch (err) { }
- { }
块级作用域可嵌套
const
- 常量-不可改变的量
- 常量为引用类型的时候不能保证不可变(不能修改常量指向的地址)
引用类型常量指向的是一个地址,修改地址内部的值是不会报错的] - 防止常量为引用类型的时候能被修改的情况
Object.freeze(常量名)常量冻结 - es6之前声明常量
- 假装是常量
var BASE_COLOR = '#ff0000'; - Object.defineProperty(描述)
- 常量为引用类型的时候不能保证不可变(不能修改常量指向的地址)
- 和声明变量一样基本只是关键字的区别
- 常量必须在声明的时候赋值
- 否则报错: Missing initializer in const declaration
与let类似的特征
- 不能重复声明
- 不存在提升
- 只在当前(块级)作用域内有效
解析赋值
解构赋值语法是一个JavaScript 表达式,这使得可以将值从数组或属性从对象提取到不同的变量中。--MDN
数组的解构赋值
//数组的解析结构赋值
const arr = [1, 2, 3, 4];
let [a, b, c, d] = arr;
let a = arr[1];
let b = arr[2];
let c = arr[3];
let d = arr[4];
//更复杂的匹配规则
const arr = ['a', 'b', ['c', 'd', ['e', 'f', 'g']]]
const [, b] = arr;
const [, , g]=['e', 'f', 'g'];
const [, , [, f]]=['c', 'd', ['e', 'f', 'g']];
const [, , [, , [, , g]]] = arr
//扩展运算符:...(扩展运算符为三个点)
const arr1 = [1,2,3];
const arr2 = ['a','b'];
const arr3 = ['zz',1];
const arr4 = [...arr1,...arr2,...arr3];
arr4
(7) [1, 2, 3, "a", "b", "zz", 1]
-----------------------------------
const arr = [1, 2, 3, 4];
const [a, b, ...c] = arr;
c
(2) [3, 4]
//默认值
const arr = [1, undefined, undefined];
const [a, b=2, c, d='aaaaa'] = arr;
// 交换变量
let a = 20;
let b = 10;
[a, b] = [b, a];
// let temp;
// temp = a;
// a = b;
// b = temp;
// 接受多个 函数返回值
function getUserInfo(id) {
//...ajax
return [
true,
{
name:'小明',
gender:'女',
id:id
},
'请求成功'
];
};
const [status,data,msg]=getUserInfo(123);
对象的解构赋值
对象是无序的,可以直接通过属性名获取
// 对象的解构赋值
const obj = {
saber : 'niaho',
archer: '卫宫'
};
// 匹配的时候需要保证属性名相同
const {saber,archer} = obj;
// 稍微复杂的解构条件
const player = {
nickname: '唐僧洗头艹飘柔',
master : '东海龙王',
skill : [{
skillName : '龙吟',
mp:'100',
time : 60000
},{
skillName : 'abc',
mp:'100',
time : 60000
},{
skillName : '123',
mp:'100',
time : 60000
}]
}
const { nickname } = player;
const { master } = player;
// 数组状态下,数组中的数组中的属性名合法就ok
const {skill: [skill1, {skillName}, {skillName: sklName}]} = player;
const obj = {
saber : '阿尔托利亚',
archer : '卫宫',
lancer : '实体店'
};
const {saber,...oth} = obj;
//使用扩展运算符合并对象
const obj = {
archer: '卫宫',
lancer: '实体店'
};
const obj1 = {
saber: '阿尔托利亚',
...obj
};
// 默认值
let girlfrienf = {
name : ' xiaohong',
age : undefined,
// hoby : ['看书',
// '洗澡']
};
let { name , age = 24, hoby = [ ' 学习']} = girlfrienf;
// 提取对象的属性
const { name , hobby:[hobby1] ,hobby } = {
name : '小红',
hobby : ['学习']
};
// 使用对象传入乱序的函数参数
function AJAX({
url,
data,
type = 'get',
}) {
// var type = option.type || 'get';
console.log(type);
};
AJAX({
url: 'getinfo',
data:{
a:1
},
});
// 获取多个 函数返回值
function getUserInfo(uid) {
//...ajax
return {
status: true,
data : {
name : '小红'
},
msg : '请求成功',
uid: uid
};
};
const { status , data , msg ,uid} = getUserInfo(123);
字符串的解构赋值
const str = 'You is the bone of my sword';// 你是贱骨头
const [a, b, c,...d] = str;
// 字符串分解
const [...spStr1] = str;
const spStr2 =str.split('');
const spStr3 = [...str];
// 提取属性
const {length,split} = str;
数值与布尔值的解构赋值
const { valueOf: vo } = 1;
const { toString: ts} = false;
函数参数的解构赋值
function Computer({
cpu,
memory,
software = ['ie6'],
OS = 'windows 1909'
}) {
console.log(cpu);
console.log(memory);
console.log(software);
console.log(OS);
}
new Computer({
memory:'1T',
cpu:'i9',
software:['idea'],
OS:'mac'
});
ES6扩展
字符串扩展
- 模版字符串
const xiaoming = {
name: 'xiaoming',
age: 14,
say1: function() {
console.log('我叫' + this.name.toUpperCase() + ', 我今年' + this.age + '岁!');
},
say2: function() {
console.log(`我叫${ `Mr.${ this.name.toUpperCase() }` }, 我今年${ this.age }岁!`);
}
}
xiaoming.say1();
xiaoming.say2();
// 列子
const getImoocCourseList = function() {
// ajax
return {
status: true,
msg: '获取成功',
data: [{
id: 1,
title: 'Vue 入门',
date: 'xxxx-01-09'
}, {
id: 2,
title: 'ES6 入门',
date: 'xxxx-01-10'
}, {
id: 3,
title: 'React入门',
date: 'xxxx-01-11'
}]
}
};
const { data: listData, status, msg } = getImoocCourseList();
function foo(val) {
return val.replace('xxxx', 'xoxo');
}
if (status) {
let arr = [];
listData.forEach(function({ date, title }) {
// arr.push(
// '<li>\
// <span>' + title + '</span>' +
// '<span>' + date + '</span>' +
// '</li>'
// );
arr.push(
`
<li>
<span>${ `课程名: ${ title }` }</span>
<span>${ foo(date) }</span>
</li>
`
);
});
let ul = document.createElement('ul');
ul.innerHTML = arr.join('');
document.body.appendChild(ul);
} else {
alert(msg);
}
- 部分新的方法
// 部分新方法
// padStart padEnd 补全字符串长度
{
let str = 'i';
// 往字符串前面补
let str1 = str.padStart(5, 'mooc');
console.log(str1);
// 往字符串后面补
let str2 = str.padEnd(5, 'mooc');
console.log(str2);
}
// repeat
{
//重复字符串10遍
console.log('i'.repeat(10));
function repeat(str, num) {
return new Array(num + 1).join(str);
}
console.log(repeat('s', 3));
}
// startsWith endsWith 判断字符串以什么开头或者以什么结尾
{
const str = 'A promise is a promsie';
console.log(str.startsWith('B'));
console.log(str.startsWith('A pro'));
console.log(str.endsWith('promsie'));
console.log(str.endsWith('A'));
}
// includes 判断这个字符串中是否有该子字符串
{
const str = 'A promise is a promise';
// if (str.indexOf('promise') !== -1) {
if (~str.indexOf('promise')) {
console.log('存在1');
}
~x = -(x + 1)
if (str.includes('a promise')) {
console.log('存在2');
}
}
- 新的Unicode表示法和遍历方式
let str = 'PROMISE';
/***************************************************************/
// ES6之前遍历字符串的方式
// 使用for循环
for (var i = 0, len = str.length; i < len; i ++) {
console.log(str[i]);
console.log(str.charAt(i));
}
/***************************************************************/
// 转成数组后遍历
var oStr = Array.prototype.slice.call(str);
var oStr = str.split('');
const oStr = [...str];
const [...oStr] = str;
oStr.forEach(function(word) {
console.log(word);
});
console.log(oStr);
// 有时候遍历是为了操作字符串
// 对全是英文的字符串中的大写字符加密 A -> 100 B -> 99。。。
const map = {A: '100', B: '99', C: '98', D: '97', E: '96', F: '95', G: '94', H: '93', I: '92', J: '91', K: '90', L: '89', M: '88', N: '87', O: '86', P: '85', Q: '84', R: '83', S: '82', T: '81', U: '80', V: '79',W: '78',X: '77',Y: '76', Z: '75'};
const words = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
oStr.forEach(function(word, index) {
if (words.includes(word)) oStr[index] = map[word];
});
console.log(oStr.join(''));
/***************************************************************/
// 使用for-of遍历字符串,类似于java中的增强for循环
for (let word of str) {
console.log(word);
}
let newStr = '';
for (let word of str) {
if (words.includes(word)) newStr += map[word];
}
console.log(newStr)
/***************************************************************/
// 🐶 \u1f436 unicode码(点)。emoji
console.log('\u1f436');
console.log('\u{1f436}');
// Unicode是一项标准 包括字符集、编码方案等
// 他是为了解决传统的字符编码方案的局限而产生的,为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
// codePointAt 获取字符串中对应字符的一个码点
// '🐶'.codePointAt(0);
// at 根据下标取字符
// '🐶abc'.at(0) 🐶
正则扩展
//正则表达是基础
const regexp1 = /^a/g; //匹配以a开头的字符串,g代表全局匹配
/*******************************/
const regexp2 = new RegExp('^a', 'g');
const regexp3 = new RegExp(/a/g);
const regexp4 = new RegExp(/a/);
console.log('aabbcc'.match(regexp1));
console.log('babbcc'.match(regexp1));
console.log('aabbccaabbaa'.match(regexp3));
console.log('aabbccaabbaa'.match(regexp4));
/*******************************/
// 构造函数的变化
const regexp5 = new RegExp(/a/giuy, 'ig');
/***************************/
// uy修饰符
// u. unicode
console.log(/^\ud83d/.test('\ud83d\udc36'))
//u会将后面的当做一个字符处理
console.log(/^\ud83d/u.test('\ud83d\udc36'))
// '\ud83d\udc36'
// y 粘连修饰符 sticky 从上一个匹配结果的开始就满足匹配条件,才会执行下一次的匹配
const r1 = /imooc/g;
const r2 = /imooc/y;
const str = 'imoocimooc-imooc';
console.log(r1.exec(str));
console.log(r1.exec(str));
console.log(r1.exec(str));
console.log(r1.exec(str));
console.log('-----------------');
console.log(r2.exec(str));
console.log(r2.exec(str));
console.log(r2.exec(str));
数值扩展
新的进制表示法
// 新的进制表示法
// 016 => 14
0o 0O octonary 八进制
0b 0B binary 二进制
console.log(0o16);
console.log(0b1111);
新的方法与安全数
- Number.parseInt 转换为整数
- Number.parseFloat 转换为浮点数
- isNaN 判断一个值是不是NaN的,挂载Number下
- ifFinite 判断一个数是不是有限的(Infinity-----无限的)
- Number.isSafeInteger(); 这个数值是不是处在js能精确表示的范围之内(2的53次-1和负的2的53次-1)
- Number.MAX_SAFE_INTEGER Number.MIN_SAFE_INTEGER
- 幂运算
- let a = 2 ** 10 ** 0 结果为2 幂运算默认为右运算,如需要打括号
函数扩展
默认参数
- 函数参数的默认值
function People({ name, age = 38 } = {name: 1}) {
console.log(name, age);
};
People({ name: 3 });
与扩展运算符的结合
- 结合扩展运算符(剩余参数...)
// 结合扩展运算符(剩余参数...)
// 扩展运算符是做展开
// 剩余参数是做聚合的
function sum(...args) {
// // let args = Array.prototype.slice.call(arguments);
// // let args = [...arguments];
// // let [...args] = arguments;
console.log(args);
}
sum(1, 2, 321, 4354, 'fdafsd');
// 输出结果为一个数组
/*******************************/
// 扩展用法 可以给多个参数,但是剩余参数必须是在最后一位
function op(type, b, ...nums) {
console.log(type);
console.log(nums);
}
op('sum', 1, 23, 454, 3, 67, 234);
/***************************/
//使用剩余参数计算总和
function sum(...numbers) {
return numbers.reduce(function(a, b) {
return a + b;
}, 0);
}
console.log(sum(1, 2, 3, 4));
箭头函数(=>)
const add1 = (a ,b) => a + b;
//等效于
const add2 = function(a , b) {
return a + b;
}
// 多行函数
const add1 = (a, b) => {
a += 1;
return a + b;
};
// 上下结果等效
const add2 = function(a, b) {
a += 1;
return a + b;
// 使用void可以让后面的表达式不返回或者返回一个undefined
const pop = arr => void arr.pop();
}
// 箭头函数和普通函数的区别
const log = () => {
console.log(arguments);
};
箭头函数中没有arguments,只能通过扩展运算符接受剩余参数
const log = (...args) => {
console.log(args)
}
箭头函数没有他自己的this,箭头函数的this指的是箭头函数所处环境的this->Window
const xiaoming = {
name: 'xiaoming',
age: null,
getAge: function() {
let _this = this; // 对this做一个保留
// ...ajax
setTimeout(function() {
_this.age = 14;
console.log(_this);
}, 1000);
}
};
===============采用箭头函数==============
const xiaoming = {
name: 'xiaoming',
age: null,
getAge: function() {
// ...ajax
setTimeout(() => {
this.age = 14;
console.log(this);
}, 1000);
}
};
在箭头函数中可以不采用保留this,箭头函数调用的this是所处环境中的this
对象扩展
简介表示法与属性名表达式
- 简介表示法
//原
const getUserInfo = (id = 1) => {
// AJAX ....
const name = 'xiaoming';
const age = 10;
return {
name: name,
age: age,
say: function() {
console.log(this.name + this.age);
}
};
};
const xiaoming = getUserInfo();
------------------------------------------
//es6
const getUserInfo = (id = 1) => {
// AJAX ....
const name = 'xiaoming';
const age = 10;
return {
name,
age,
say() {
console.log(this.name + this.age);
}
};
};
const xiaoming = getUserInfo();
- 属性名表达式
const obj = {
a: 1,
$abc: 2, // 以上可以通过obj.属性名访问
'FDASFHGFgfdsgsd$#$%^&*%$#': 3 //通过obj['属性名访问']
};
const key = 'age';
const xiaoming = {
name: 'xiaoming',
[`${key}123`]: 14
};
部分新方法与扩展运算符
- 复制对象 - 浅拷贝
复制一个对象后,只是作为引用 - 合并对象 - 浅拷贝
在使用扩展运算符合并对象是,有相同属性名的变量将会使用靠后的哪一个对象的值 - 部分新的方法和属性
- Object.is -> === 全等于
+0 -0 和NaN的判断时 - Object.assign
对数据进行合并
const obj = Object.assign({a: 1}, {b: 2}, {c: 3}, {d: 4, e: 5});
合并后
obj={a:1,b:2,c:3,d:4,e:5}
- Object.keys 返回自身key所组成的keys
- Object.values 返回自身value所组成的值
- Object.entries 返回每一组key value组成的数组
- __ proto__ 代表当前对象的原型(了解)
- super 可以访问到原型对象上的方法,只能是对象的简介表示法才行
- Object.is -> === 全等于
共有 0 条评论