一、变量声明
关键字let、const
总结:
-
作用域:
- var声明的变量具有全局作用域或函数作用域。在全局作用域下,使用var声明的变量会被附加到window对象上。
- let和const声明的变量具有块级作用域,仅在声明它们的代码块内有效。这意味着它们的作用域被限制在一对花括号内,即一个块内。
-
变量提升:
- var声明的变量会发生变量提升,无论在函数的哪个部分声明,它们都会被移动到函数的顶部。这可能导致预期之外的变量访问行为。
- let和const声明的变量也会提升,但它们不会被初始化。在代码执行到声明之前,它们是不可访问的,这个区间被称为“暂时性死区”(Temporal Dead Zone, TDZ)。
-
重复声明:
- var允许在同一作用域中重复声明同一个变量。
- let不允许在同一个作用域中重新声明已经存在的变量。
- const也不允许在相同作用域内重复声明变量。
-
重新赋值:
- var声明的变量可以被重新赋值。
- let声明的变量可以被重新赋值,但不能重复声明。
- const声明的变量不能被重新赋值,它们必须在声明时初始化,并且声明后值是固定的。但是,如果const变量指向的是一个对象或数组,那么对象或数组的内容是可以被修改的。
1、let
// 变量声明
let a;
let d,b,c;
let e = 99;
let f = 520,g = 'I love you';
//1、let变量不能重复声明
let star = '狗蛋';
let star = '二娃';
//此时会报错
//2、let块级作用域 全局,函数,eval
{
let girl = '邓紫棋';
}
console.log(girl); //读取不到,
//3、不从在变量提升
log(song);
let song = '恋爱搭子';
//不能先使用后声明
2、const
//声明常量,一定要赋值
const GANDA = '代码达人';
//2、常量的值不允许修改
GANDA = '石山代码'; //错误写法
//3、对于数组和对象的元素修改,不算对常量的修改,不会报错但是不生效
const TEAM = ['GBA','CBA''NBA','DDZ'];
TEAM.push('MHD'); // 不生效 因为常量地址没有发生改变
4、报错
TEAM = 666;
二、变量的结构赋值
ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。
1、数组解构
const Sb = ['吴亦凡','李易峰','鹿晗','小宝'];
let [wyf, lyf, lh, xb] = Sb;
log(wyf);
log(lyf);
log(lh);
log(xb);
2、对象解构
const zhou = {
name:'周扒皮',
age:'不详',
zuoping: function(){
consloe.log('我是小丑呀')
}
};
let {name, age, xiaopin} = zhou;
三、模板字符串
ES6 引入新的字符串方式 ``(反斜杠,键盘第二排第一个)
1、声明
let str = `我是一个字符串哦!`;
console.log(str, typeof str) //检测str属性
2、内容中可以直接出现换行符
例:
let str = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`; //会解析标签
3、变量拼接
let lovest = '魏翔';
let out = `${lovest}是我心目中组搞笑的演员!`
consloe.log(out);
四、简化对象的写法
ES6 允许在大括号里面直接写入变量跟函数,作为对象的属性和方法。
let name = '狮子搏兔,亦用全力。';
let change = function(){
console.log('全力以赴');
}
const struggle = {
name, //name:'name'
change,
improve(){
console.log('函数的简写形式');
}
}
五、箭头函数
ES6 允许使用 箭头 => 定义函数
1、声明一个函数
let fn = function(){
};
let fn = (a,b) =>{
return a+b;
}
调用函数
let result = fn(1,2);
console.log(result);
2、this
this 是静态的, this 始终指向函数声明时所在作用域下的this 的值
function getName(){
console.log(this.name);
}
let getName2 = () => {
console.log(this.name);
}
//设置 window 对象name属性
window.name = '小八嘎';
const school = {
name;'###小八嘎';
}
//直接调用
getName();
getName2();
1、call方法调用
getName.call(school);
getName.call2(school);
2、不能作为构造实例化对象
let Person = (name,age) =>{
this.name = name;
this.age = age;
}
let me = new Person('xiao',30);
console.log(me);
3、不能使用 arguments 变量
let fn = () => {
console.log(arguments);
}
fn(1,2,3);
4、箭头函数简写
(1)省略小括号,当形参有且只有一个的时候
let add n =>{
return n+n;
}
console.log(add(1));
(2)省略花括号,当代码体只有一条语句的时候
语句的执行结果就是函数的返回值
let pow = n => n*n
console.log(pow(9));
六、函数参数默认值
ES6 允许给函数参数赋值初始值
1、形参初始值 具有默认值的参数,一般位置要靠后(潜规则)
function add(a,b,c = 10){
return a + b + c;
}
let result = add(1,2);
console.log(result);
2、与解构赋值结合
function connect({host='127.0.0.1' ,username,password,post}){
console.log(host);
console.log(username);
console.log(password);
console.log(post);
}
connect({
host: 'i love you',
username:'root',
password:'root',
post:123456
})
七、rest(剩余参数)
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arfuments。
ES5 获取参数的方法
function date(){
console.log(arguments);
}
date('阿胶','桂皮','硅胶','树脂',); //此时打印出来一个对象
如果有多个参数要制定, rest 参数必须放到参数最后
function fn(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
}
fn(1,2,3,4,5,6,7) // a = 1, b = 2, args = [3,4,5,6,7]
args返回的是数组,并且可以使用数组方法。
八、扩展用算符
... 扩展用算符能将[数组]转换成逗号隔开的参数序列。
const tfboys = ['易烊千玺','王源','王俊凯'];
function chunwan(){
console.log(arguments);
}
chunwan(...tfboys); //chunwan('易烊千玺','王源','王俊凯');
用法示例:
//1、数组合并
const kuaizi = ['王太利','肖央'];
const fenghuang = ['曾毅','玲花'];
const zxxpg = [...kuaizi,...fenghuang];
//2、数组克隆
const sanzhihua = ['E','G','M'];
const sanyecao = [...sanzhihua ];
九、Symbol基本使用
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol特点
1、Symbol 的值是唯一的,用来解决命名冲突的问题。
2、Symbol 值不能与其他数据进行运算。
3、Symbol 定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
//创建Symbol
let s1 = Symbol('回访');
let s2 = Symbol('回访');
conlose.log(s1===s2) //false唯一性
//Symbol.for 创建
let s4 = Symbol.for('回放')
let s5 = Symbol.for('回放')
//不能运算
数据类型记忆法 USONB you are so niubility
u undefined
s string Symbol
o object
n null number
b boolean
1、Symbol 用法
//当game对象中方法多且不易于阅读时,为了防止变量冲突
let game = {...}
//声明一个对象
let methods = {
up: Symbol(),
down: Symbol()
}
game[methods.up] = function(){
console.log('我可以改变形状');
}
game[methods.down] = function(){
console.log('我可以快速下降!!!');
}
2、Symbol 其他方法
Symbol.hasInstance
|
当其他对象使用
instanceof
运算符,判断是否为该对 象的实例时,会调用这个方法
|
Symbol.isConcatSpreadable
|
对象的
Symbol.isConcatSpreadable
属性等于的是一个 布尔值,表示该对象用于 Array.prototype.concat()
时, 是否可以展开。
|
Symbol.species
|
创建衍生对象时,会使用该属性
|
Symbol.match
|
当执行
str.match(myObject)
时,如果该属性存在,会 调用它,返回该方法的返回值。
|
Symbol.replace
|
当该对象被
str.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 环境排除。
|
十、迭代器
(1)ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费 。
(2)原生具备 iterator 接口的数据(可用 for of 遍历)。
十一、生成器
生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同
function * gen(){
yield '一只没有耳朵';
yield '一只没有尾巴';
return '真奇怪';
}
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
十二、Promise
Promise 是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
(1)Promise 构造函数 : Promise(excutor){ }
(2)Promise.prototype.then 方法
(3)Promise.prototype.catch方法
//实例化 Promise 对象
const p = new Promise(function(resolve,reject){
setTimeout(function(){
//成功调用
//let data = '数据库中的用户数据';
// resolve(data);
//失败调用
ler err = '数据读取失败';
reject(err);
},1000)
});
//调用 promise 对象的 then 方法
p.then(function(value){
console.log(value)
},function(reason){
console.log(reason);
})
十三、Set
ES6 提供了新的数据解构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用扩展用算符 和 for...of 进行遍历,集合的属性和方法:
- size 返回集合的元素个数
- add 增加一个新元素,返回当前集合。
- delete 删除元素,放回boolean 值
- has 检测集合中是否包含某个元素,返回boolean值
- clear 清空集合,返回undefined。
//声明一个 set
let s = new Set();
let s2 = new Set(['大事儿','小事儿','好事儿','坏事儿','大事儿','下事儿']);
//元素的个数
console.log(s2.size);
//添加新的元素
s2.add('喜事儿');
//删除元素
s2.delete('坏事儿');
//检测
console.log(s2.has('糟心事'));
//清空
s2.clear();
for(let v of s2){
console.log(v);
}
十四、Map
ES6 提供了Map数据结构。它类似于对象,也是键值对的集合。它是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator接口,所以可以使用扩展用算符 和 for...of 进行遍历。Map的属性和方法:
- size 返回Map的元素个数。
- set 增加一个新元素,返回当前Map
- get 返回键名对象的键值
- has 检测Map中是否包含某个元素,返回boolean值
- clear 清空集合,返回undefined。
//声明 Map
let m = new Map();
//添加元素
m.set('name','牛逼');
m.set('change',function(){
console.log('锤子吧!!!');
});
let key = {
school ; 'ABCDEF'
};
m.set(key,['北京','深圳','上海'])
console.log(m);
十五、class类
ES6 提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它是绝大部分功能,ES6都可以做到,新的class写法只是让对象原型链的写法更加清晰、更像面向对象编程的写法而已。
知识点:
- class声明类
- constructor 定义构造函数初始值
- extends 继承父类
- super 调用父级构造方法
- static 定义静态方法和属性
- 父类方法可以重写
初步体验:
class Phone{
//构造方法 名字不能修改
constructor(brand,price){
this.brand = brand;
this.price = price
}
//方法必须使用改语法,不能使用ES5的对象完整形式
call(){
console.log('我可以打电话!!!');
}
}
let onePlus = new Phone('1+',1999);
console.log(onePlus);
十六、数值扩展
1、二进制和八进制
2、Number.isFinite() 与Number.isNaN()
Number.isFinite() 用来检查一个数值是否为有限的Number.isNaN() 用来检查一个值是否为 NaN
3、Number.parseInt() 与Number.parseFloat()
4、Math.trunc
5、Number.isInteger
十七、对象扩展
1) Object.is 比较两个值是否严格相等,与『 === 』行为基本一致( +0 与 NaN )2) Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象3) __proto__ 、 setPrototypeOf 、 setPrototypeOf 可以直接设置对象的原型
十八、模块化
模块化是指将一个大的程序文件拆分成许多小的文件,然后将小文件结合起来。
1、模块化的好处
- 防止命名冲突,
- 代码复用,
- 高维护性,
2、模块化规范产品以前
- commonJS => NodeJS、Browserify
- AMD => requireJS
- CMD => seaJS
3、ES6模块化规范
模块功能主要由两个命令构成:export和import。
- export命令用于规范模块的对外接口。
- import命令用于输入其他模块提供的功能。
解构赋值方式暴露
export { str } 分别暴露
export default str 默认暴露
import {str} from '地址' 分别引入
import str from ‘地址’ 默认引入
4、babel 将ES6新特性转换为ES5代码
1、安装工具 npm install
2、开发依赖 npm i babel-cli babel-preset-env browserify -D
3、代码转换npx babel src/js -d dist/js --presetes-babel-preser-env
src/js 源文件
dist/js 转换之后的文件
4、npx browserify dist/js/app.js -o dist/bundle.js
5、引入dist/bundle.js
十九、ES7新特新
1、Array.prototype.includes
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值
const mingzhu = ['西游记','红楼梦','三国演义','水浒传'];
//判断
console.log(mingzhu.include('西游记'));
console.log(mingzhu.include('金瓶梅'));
2、指数操作符
在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同
二十、ES8新特性
1、async 函数
async function fn(){
return '大爷的';
}
const result = fn();
console.log(result);
//返回的是promise对象
2、await表达式
- await必须写在async函数中
- await右侧的表达式一般为promise对象
-
await 返回的是 promise 成功的值
-
await 的 promise 失败了 , 就会抛出异常 , 需要通过 try...catch 捕获处理
二十一、对象方法扩展
1、Object.values 和 Object.entries
Object.values() 方法返回一个给定对象的所有可枚举属性值的数组Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组
//对象声明
const school = {
name:'牛努力',
cities:['北京','上海','深圳'],
xueke:['前端','Java','大数据','运维']
};
//获取对象所有的键
console.log(Object.Keys(school));
//获取对象所有的值
console.log(Object.values(school));
//entries
console.log(Object.entries(school));
2、Object.getOwnPropertyDescriptors
二十二、ES9新特新
Rest参数与 spread扩展用算符在 ES6 中已经引入,不过ES6只针对于数组,在ES9中为对象提供了像数组一样的rest参数和扩展运算符
1、对象的扩展运算与rest参数
function connect({host,port,...user}){
console.log(host);
console.log(port);
console.log(username);
console.log(password);
}
connect({host: '127.0.0.1',
port: 3006,
username: 'root',
password;'root'
})
2、正则扩展——命名捕获分组
//声明一个字符串
let str = '<a href="http://www.baidu.com">百度</a>'
//提取
const reg = /<a href="(.*)">(.*)</a>
//执行
const result = reg.exec(str);
console.log(result[1]);
console.log(result[2])
命名捕获:
//声明一个字符串
let str = '<a href="http://www.baidu.com">百度</a>'
//提取
const reg = /<a href="(?<url>.*)">(?<text>.*)</a>
//执行
const result = reg.exec(str);
console.log(result);
3、正则扩展——反向断言
正向断言:
//声明字符串
let str = 'JS314514只知道不222???';
const reg = /\d+(? = ?)/;
const result = reg.exec(str);
console.log(result);
反向断言:
//声明字符串
let str = 'JS314514只知道不222???';
const reg = /(?<=只)\d+/;
const result = reg.exec(str);
console.log(result);
4、正则扩展——dotAll模式
//dot . 元字符 除换行符意外的任意单个字符
//字符串 let str = ` <ul> <li> <a>标题1</a> <p>描述1</p> </li> <li> <a>标题2</a> <p>描述2</p> </li> </ul>`; //正则-dotAll模式 。* let reg = /<li>.*?<a>(?<title>.*?)<\/a>.*?<p>(?<desc>.*?)<\/p>/gs; let result; let data = []; //执行 while (result = reg.exec(str)){ data.push(result.groups); } console.log(data);
二十三、ES10新特新
Object.fromEntries
//二维数组
const result = Object.fromEntries([
['name','牛哈'],
['shuzi','六,七,吧']
])
//Map
const m = new Map();
m.set('name','act');
const result = Object.fromEntries(m);
console.log(result);
trimStart 和 trimEnd
trimStart 清除字符串左侧空格,trimEnd清除字符串右边空格
Array.prototype.flat 与 flatMap
flat将多维数组转换为低位数组,
const arr = [1,2,3,4,[5,6,[7,8,9]]] //参数为深度 是一个数字 console.log(arr.flat(2))
flatMap
const arr = [1,2,3,4,5] const result = arr.map(item => item*10); console.log(result);
Symbol.prototype.description
//创建Symbol
let s = Symbol('阿迪');
console.log(s.description)
二十四、ES11新特新
1、私有属性
class Person{
//公有属性
name;
//私有属性
#age;
#weight;
constructor(name,age,weight){
this.name = name,
this.#age = age,
this.#weight = weight
}
}
//实例化
const girl = new Person('晓红',18,'45kg');
2、Promise.allSettled
Promise.allSettled() 是 JavaScript 中的一个 Promise 方法,它接收一个由多个 Promise 对象组成的可迭代对象,并在所有 Promise 对象都已解决或拒绝后返回一个 Promise 对象,该对象解析为一个数组,每个元素对应于相应的 Promise 对象的结果。
与 Promise.all() 不同的是,Promise.allSettled() 不会在任何 Promise 被拒绝时中止,并且总是等待所有 Promise 对象都已解决或拒绝后才返回结果。返回的数组中的每个元素都是一个对象,包含以下属性之一:
status:表示 Promise 的状态,可能的值为 “fulfilled”(已解决)或 “rejected”(已拒绝)。
value:如果 Promise 已解决,则为解决值;如果 Promise 已拒绝,则为拒绝原因。
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'error'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 200, 'resolved'));
Promise.allSettled([promise1, promise2, promise3])
.then((results) => {
results.forEach((result) => {
console.log(result.status); // 输出 "fulfilled", "rejected", "fulfilled"
console.log(result.value); // 输出 3, "error", "resolved"
});
});
3、可选链操作符
简介
可选链运算符(?.)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 运算符的功能类似于 . 链式运算符,不同之处在于,在引用为空 (nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。
当尝试访问可能不存在的对象属性时,可选链运算符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链运算符也是很有帮助的。
4、动态 import
动态绑定当某一时刻需要时再引入:
import('地址').then(module =>{
console.log(module)
})
5、globalThis 对象
globalThis旨在通过定义一个标准的全局属性来整合日益分散的访问全局对象的方法。该提案目前处于第四阶段,这意味着它已经准备好被纳入ES2020标准。所有流行的浏览器,包括Chrome 71+、Firefox 65+和Safari 12.1+,都已经支持这项功能。你也可以在Node.js 12+中使用它。
// 浏览器环境
console.log(globalThis); // => Window {...}
// node.js 环境
console.log(globalThis); // => Object [global] {...}
// web worker 环境
console.log(globalThis); // => DedicatedWorkerGlobalScope {...}