ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制
造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该
组织改名为 Ecma 国际。
ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。
TC39(Technical Committee 39)是推进 ECMAScript 发展的委员会。其会员都是
公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。TC39 定期
召开会议,会议由会员公司的代表与特邀专家出席
⚫ ES6 的版本变动内容最多,具有里程碑意义
⚫ ES6 加入许多新的语法特性,编程实现更简单、高效
⚫ ES6 是前端发展趋势,就业必备技能
let a;
let b,c,d;
let e = 100;
let f = 521, g = 'iloveyou', h = [];
let 关键字用来声明变量,使用 let 声明的变量有几个特点:
1)不允许重复声明
let star = '罗志祥';
let star = '小猪'; //报错
if else while for
{
let girl = '周扬青';
}
console.log(girl); //报错
console.log(song);
let song = '恋爱达人'; //报错
{
let school = 'SHOOL';
function fn(){
console.log(school);
}
fn();
}
应用场景:以后声明变量使用 let 就对了
const 关键字用来声明常量,const 声明有以下特点
const SCHOOL = 'SCHOOL';
const A; //报错
const a = 100; //潜规则
const a = 100;
const b = 200;` //报错
SCHOOL = 'ATGUIGU'; //可以用作常数,如PI
{
const PLAYER = 'UZI';
}
const TEAM = ['UZI','MXLG','Ming','Letme'];
TEAM.push('Meiko'); //不报错
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>点击 DIV 换色title>
<link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
rel="stylesheet">
<style>
.item {
width: 100px;
height: 50px;
border: solid 1px rgb(42, 156, 156);
float: left;
margin-right: 10px;
}
style>
head>
<body>
<div class="container">
<h2 class="page-header">点击切换颜色h2>
<div class="item">div>
<div class="item">div>
<div class="item">div>
div>
<script>
//获取div元素对象
let items = document.getElementsByClassName('item');
//遍历并绑定事件
for(let i = 0;i<items.length;i++){
items[i].onclick = function(){
//修改当前元素的背景颜色
// this.style.background = 'pink';
items[i].style.background = 'pink';
}
}
script>
body>
html>
注意: 对象属性修改和数组元素变化不会出发 const 错误
应用场景:声明对象类型使用 const,非对象类型声明选择 let
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。
const F4 = ['小沈阳','刘能','赵四','宋小宝'];
let [xiao, liu, zhao, song] = F4;
console.log(xiao);
console.log(liu);
console.log(zhao);
console.log(song);
const zhao = {
name: '赵本山',
age: '不详',
xiaopin: function(){
console.log("我可以演小品");
}
};
let {name, age, xiaopin} = zhao;
console.log(name);
console.log(age);
console.log(xiaopin);
xiaopin();
let {xiaopin} = zhao;
xiaopin();
注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式
模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:
let str = `我也是一个字符串哦!`;
console.log(str, typeof str);
let str = `
- 沈腾
- 玛丽
- 魏翔
- 艾伦
`;
输出也一样,带换行符:
let lovest = '魏翔';
let out = `${lovest}是我心目中最搞笑的演员!!`;
console.log(out);
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
let name = '大表哥';
let change = function(){
console.log('我可以改变你!!');
}
const school = {
name,
change,
improve(){
console.log("我可以提高你的技能");
}
}
console.log(school);
注意:对象简写形式简化了代码,所以以后用简写就对了
ES6 允许使用「箭头」(=>)定义函数。
1.== 声明一个函数==
//普通函数
let fn = function(a,b){
return a + b;
}
//箭头函数
let fn = (a,b) => {
return a + b;
}
let result = fn(1, 2);
console.log(result);
function getName(){
console.log(this.name);
}
//this指向这里
let getName2 = () => {
console.log(this.name);
}
//设置 window 对象的 name 属性
window.name = '尚硅谷';
const school = {
name: "ATGUIGU"
}
//直接调用
getName();
getName2();
//call 方法调用
getName.call(school);//指向school
getName2.call(school); //始终指向window
let Person = (name, age) => {
this.name = name;
this.age = age;
}
let me = new Person('xiao',30);
console.log(me);
let fn = () => {
console.log(arguments);
}
fn(1,2,3);
//1) 省略小括号, 当形参有且只有一个的时候
let add = n => {
return n + n;
}
//2) 省略花括号, 当代码体只有一条语句的时候, 此时 return 必须省略
let pow = n => n * n;
console.log(pow(8));
注意:箭头函数不会更改 this 指向,用来指定回调函数会非常合适
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>箭头函数实践title>
<style>
div {
width: 200px;
height: 200px;
background: #58a;
}
style>
head>
<body>
<div id="ad">div>
<script>
//需求-1 点击 div 2s 后颜色变成『粉色』
//获取元素
let ad = document.getElementById('ad');
//绑定事件
ad.addEventListener("click", function(){
//保存 this 的值
// let _this = this;
//定时器
setTimeout(() => {
//修改背景颜色 this
// console.log(this);
// _this.style.background = 'pink';
this.style.background = 'pink';
}, 2000);
});
//需求-2 从数组中返回偶数的元素
const arr = [1,6,9,10,100,25];
// const result = arr.filter(function(item){
// if(item % 2 === 0){
// return true;
// }else{
// return false;
// }
// });
const result = arr.filter(item => item % 2 === 0);
console.log(result);
// 箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调
// 箭头函数不适合与 this 有关的回调. 事件回调, 对象的方法
script>
body>
html>
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
ES5 获取实参的方式
function date(){
console.log(arguments);
}
date('白芷','阿娇','思慧');
function date(...args){
console.log(args);// filter some every map
}
date('阿娇','柏芝','思慧');
function fn(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
}
fn(1,2,3,4,5,6);
注意:rest 参数非常适合不定个数参数函数的场景
扩展运算符(spread)也是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。
//声明一个数组 ...
const tfboys = ['德玛西亚之力','德玛西亚之翼','德玛西亚皇子'];
// 声明一个函数
function chunwan(){
console.log(arguments);
}
chunwan(...tfboys);// chunwan('易烊千玺','王源','王俊凯')
//展开对象
let skillOne = {
q: '致命打击',
};
let skillTwo = {
w: '勇气'
};
let skillThree = {
e: '审判'
};
let skillFour = {
r: '德玛西亚正义'
};
let gailun = {...skillOne, ...skillTwo,...skillThree,...skillFour};
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
//创建Symbol
let s = Symbol();
// console.log(s, typeof s);
let s2 = Symbol('张三');
let s3 = Symbol('张三');
//Symbol.for 创建
let s4 = Symbol.for('李四');
let s5 = Symbol.for('李四');
let result = s + 100; //报错
let result = s > 100;
let result = s + s;
// USONB you are so niubility
u undefined
s string
s symbol
o object
n null
n number
b boolean
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 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环境排除。 |
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
//声明一个数组
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
//使用 for...of 遍历数组
for(let v of xiyou){
console.log(v);
}
let iterator = xiyou[Symbol.iterator]();
//调用对象的next方法
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
a) Array
b) Arguments
c) Set
d) Map
e) String
f) TypedArray
g) NodeList
a) 创建一个指针对象,指向当前数据结构的起始位置
b) 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
c) 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
d) 每调用 next 方法返回一个包含 value 和 done 属性的对象
//声明一个对象
const banji = {
name: "终极一班",
stus: [
'xiaoming',
'xiaoning',
'xiaotian',
'knight'
],
[Symbol.iterator]() {
//索引变量
let index = 0;
//
let _this = this;
return {
next: function () {
if (index < _this.stus.length) {
const result = { value: _this.stus[index], done: false };
//下标自增
index++;
//返回结果
return result;
}else{
return {value: undefined, done: true};
}
}
};
}
}
//遍历这个对象
for (let v of banji) {
console.log(v);
}
注: 需要自定义遍历数据的时候,要想到迭代器。
生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
//生成器其实就是一个特殊的函数
//异步编程 纯回调函数 node fs ajax mongodb
//函数代码的分隔符
function * gen(){
// console.log(111);
yield '一只没有耳朵';
// console.log(222);
yield '一只没有尾部';
// console.log(333);
yield '真奇怪';
// console.log(444);
}
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
//遍历
// for(let v of gen()){
// console.log(v);
//
}
function * gen(arg){
console.log(arg);
let one = yield 111;
console.log(one);
let two = yield 222;
console.log(two);
let three = yield 333;
console.log(three);
}
//执行获取迭代器对象
let iterator = gen('AAA');
console.log(iterator.next());
//next方法可以传入实参
console.log(iterator.next('BBB'));//第二个next传入的参数作为第一个yield的返回结果
console.log(iterator.next('CCC'));//第三个next传入的参数作为第二个yield的返回结果
console.log(iterator.next('DDD'));//第四个next传入的参数作为第三个yield的返回结果
// 异步编程 文件操作 网络操作(ajax, request) 数据库操作
// 1s 后控制台输出 111 2s后输出 222 3s后输出 333
// 回调地狱
//setTimeout(() => {
//console.log(111);
//setTimeout(() => {
//console.log(222);
//setTimeout(() => {
//console.log(333);
//}, 3000);
//}, 2000);
//}, 1000);
function one(){
setTimeout(()=>{
console.log(111);
iterator.next();//回调
},1000)
}
function two(){
setTimeout(()=>{
console.log(222);
iterator.next();
},1000)
}
function three(){
setTimeout(()=>{
console.log(333);
iterator.next();//回调
},1000)
}
function * gen(){
yield one();
yield two();
yield three();//回调
}
//调用生成器函数
let iterator = gen();
iterator.next();
//模拟获取 用户数据 订单数据 商品数据
function getUsers(){
setTimeout(()=>{
let data = '用户数据';
//调用 next 方法, 并且将数据传入
iterator.next(data);
}, 1000);
}
function getOrders(){
setTimeout(()=>{
let data = '订单数据';
iterator.next(data);
}, 1000)
}
function getGoods(){
setTimeout(()=>{
let data = '商品数据';
iterator.next(data);
}, 1000)
}
function * gen(){
let users = yield getUsers();
let orders = yield getOrders();
let goods = yield getGoods();
}
//调用生成器函数
let iterator = gen();
iterator.next();
Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
//实例化 Promise 对象
const p = new Promise(function(resolve, reject){ //实例化Promise对象要传入一个参数,参数为一个函数,该函数的参数是resolve和reject,分别代表正常和异常的状态
setTimeout(function(){
//
// let data = '数据库中的用户数据';
// resolve
// resolve(data);
let err = '数据读取失败';
reject(err);
}, 1000);
});
//调用 promise 对象的 then 方法
p.then(function(value){ //返回resolve调用这个函数
console.log(value);
}, function(reason){ //返回reason调用这个函数
console.error(reason);
})
//1. 引入 fs 模块
const fs = require('fs');
//2. 调用方法读取文件
// fs.readFile('./resources/为学.md', (err, data)=>{
// //如果失败, 则抛出错误
// if(err) throw err;
// //如果没有出错, 则输出内容
// console.log(data.toString());
// });
//3. 使用 Promise 封装
const p = new Promise(function(resolve, reject){
fs.readFile("./resources/为学.mda", (err, data)=>{
//判断如果失败
if(err) reject(err);
//如果成功
resolve(data);
});
});
p.then(function(value){
console.log(value.toString());
}, function(reason){
console.log("读取失败!!");
});
// 接口地址: https://api.apiopen.top/getJoke
const p = new Promise((resolve, reject) => {
//1. 创建对象
const xhr = new XMLHttpRequest();
//2. 初始化
xhr.open("GET", "https://api.apiopen.top/getJ");
//3. 发送
xhr.send();
//4. 绑定事件, 处理响应结果
xhr.onreadystatechange = function () {
//判断
if (xhr.readyState === 4) {
//判断响应状态码 200-299
if (xhr.status >= 200 && xhr.status < 300) {
//表示成功
resolve(xhr.response);
} else {
//如果失败
reject(xhr.status);
}
}
}
})
//指定回调
p.then(function(value){
console.log(value);
}, function(reason){
console.error(reason);
});
//创建 promise 对象
const p = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('用户数据');
// reject('出错啦');
}, 1000)
});
//调用 then 方法 then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定
//1. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值
//2. 如果回调函数中返回的结果是 promise 类型的属性, 返回值为该 promise 返回的状态
//3. 如果回调函数中返回的结果是抛出错误, 返回状态是失败
const result = p.then(value => {
console.log(value);
//1. 非 promise 类型的属性
return 'iloveyou';
//2. 是 promise 对象
return new Promise((resolve, reject)=>{
resolve('ok');
//reject('error');
});
//3. 抛出错误
throw new Error('出错啦!');
throw '出错啦!';
}, reason=>{
console.warn(reason);
});
//链式调用
p.then(value=>{
}).then(value=>{
});
//引入 fs 模块
const fs = require("fs");
// fs.readFile('./resources/为学.md', (err, data1)=>{
// fs.readFile('./resources/插秧诗.md', (err, data2)=>{
// fs.readFile('./resources/观书有感.md', (err, data3)=>{
// let result = data1 + '\r\n' +data2 +'\r\n'+ data3;
// console.log(result);
// });
// });
// });
//使用 promise 实现
const p = new Promise((resolve, reject) => {
fs.readFile("./resources/为学.md", (err, data) => {
resolve(data);
});
});
p.then(value => {
return new Promise((resolve, reject) => {
fs.readFile("./resources/插秧诗.md", (err, data) => {
resolve([value, data]);
});
});
}).then(value => {
return new Promise((resolve, reject) => {
fs.readFile("./resources/观书有感.md", (err, data) => {
//压入
value.push(data);
resolve(value);
});
})
}).then(value => {
console.log(value.join('\r\n'));
});
const p = new Promise((resolve, reject)=>{
setTimeout(()=>{
//设置 p 对象的状态为失败, 并设置失败的值
reject("出错啦!");
}, 1000)
});
// p.then(function(value){}, function(reason){
// console.error(reason);
// });
p.catch(function(reason){
console.warn(reason);
});
ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法:
//声明一个 set
let s = new Set();
let s2 = new Set(['大事儿','小事儿','好事儿','坏事儿','小事儿']);
//元素个数
console.log(s2.size);
//添加新的元素
s2.add('喜事儿');
//删除元素
s2.delete('坏事儿');
//检测
console.log(s2.has('糟心事'));
//清空
s2.clear();
console.log(s2);
for(let v of s2){
console.log(v);
}
let arr = [1,2,3,4,5,4,3,2,1];
//1. 数组去重
// let result = [...new Set(arr)];
// console.log(result);
//2. 交集
let arr2 = [4,5,6,5,6];
// let result = [...new Set(arr)].filter(item => {
// let s2 = new Set(arr2);// 4 5 6
// if(s2.has(item)){
// return true;
// }else{
// return false;
// }
// });
// let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
// console.log(result);
//3. 并集
// let union = [...new Set([...arr, ...arr2])];
// console.log(union);
//4. 差集
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
console.log(diff);
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。Map 的属性和方法:
//声明 Map
let m = new Map();
//添加元素
m.set('name','上官');
m.set('change', function(){
console.log("我们可以改变你!!");
});
let key = {
school : 'ATGUIGU'
};
m.set(key, ['北京','上海','深圳']);
//size
// console.log(m.size);
//删除
// m.delete('name');
//获取
// console.log(m.get('change'));
// console.log(m.get(key));
//清空
// m.clear();
//遍历
for(let v of m){
console.log(v);
}
// console.log(m);
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对
象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是
一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象
原型的写法更加清晰、更像面向对象编程的语法而已。
ES5定义类相关操作:
//手机
function Phone(brand, price){
this.brand = brand;
this.price = price;
}
//添加方法
Phone.prototype.call = function(){
console.log("我可以打电话!!");
}
//实例化对象
let Huawei = new Phone('华为', 5999);
Huawei.call();
console.log(Huawei);
ES6定义类相关操作:
//class
class Shouji{
//构造方法 名字不能修改
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//方法必须使用该语法, 不能使用 ES5 的对象完整形式
call(){
console.log("我可以打电话!!");
}
}
let onePlus = new Shouji("1+", 1999);
console.log(onePlus);
//手机
function Phone(brand, price){
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function(){
console.log("我可以打电话");
}
//智能手机
function SmartPhone(brand, price, color, size){
Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
//设置子级构造函数的原型
SmartPhone.prototype = new Phone;
SmartPhone.prototype.constructor = SmartPhone;
//声明子类的方法
SmartPhone.prototype.photo = function(){
console.log("我可以拍照")
}
SmartPhone.prototype.playGame = function(){
console.log("我可以玩游戏");
}
const chuizi = new SmartPhone('锤子',2499,'黑色','5.5inch');
console.log(chuizi);
ES6语法:
class Phone{
//构造方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//父类的成员属性
call(){
console.log("我可以打电话!!");
}
}
class SmartPhone extends Phone {
//构造方法
constructor(brand, price, color, size){
super(brand, price);// Phone.call(this, brand, price)
this.color = color;
this.size = size;
}
photo(){
console.log("拍照");
}
playGame(){
console.log("玩游戏");
}
call(){
console.log('我可以进行视频通话');
}
}
const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
// console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();
class Phone{
//静态属性
static name = '手机';
static change(){
console.log("我可以改变世界");
}
}
let nokia = new Phone();
console.log(nokia.name); //不可访问
console.log(Phone.name); //可访问
//父类
class Phone {
//构造方法
constructor(brand, color, price) {
this.brand = brand;
this.color = color;
this.price = price;
}
//对象方法
call() {
console.log('我可以打电话!!!')
} }
//子类
class SmartPhone extends Phone {
constructor(brand, color, price, screen, pixel) {
super(brand, color, price);
this.screen = screen;
this.pixel = pixel;
}
//子类方法
photo(){
console.log('我可以拍照!!');
}
playGame(){
console.log('我可以玩游戏!!');
}
//方法重写
call(){
console.log('我可以进行视频通话!!');
}
//静态方法
static run(){
console.log('我可以运行程序')
}
static connect(){
console.log('我可以建立连接')
} }
//实例化对象
const Nokia = new Phone('诺基亚', '灰色', 230);
const iPhone6s = new SmartPhone('苹果', '白色', 6088, '4.7inch','500w');
//调用子类方法
iPhone6s.playGame();
//调用重写方法
iPhone6s.call();
//调用静态方法
SmartPhone.run();
ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示。
//二进制和八进制
let b = 0b1010;
let o = 0o777;
let d = 100;
let x = 0xff;
console.log(x); //255
Number.isFinite() 用来检查一个数值是否为有限的
Number.isNaN() 用来检查一个值是否为 NaN
//Number.isFinite 检测一个数值是否为有限数
console.log(Number.isFinite(100));
console.log(Number.isFinite(100/0));
console.log(Number.isFinite(Infinity));
//Number.isNaN 检测一个数值是否为 NaN
console.log(Number.isNaN(123));
ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变。
//Number.parseInt Number.parseFloat字符串转整数
console.log(Number.parseInt('5211314love'));
console.log(Number.parseFloat('3.1415926神奇'));
用于去除一个数的小数部分,返回整数部分。
//Math.trunc 将数字的小数部分抹掉
console.log(Math.trunc(3.5));
Number.isInteger() 用来判断一个数值是否为整数
//5. Number.isInteger 判断一个数是否为整数
console.log(Number.isInteger(5));
console.log(Number.isInteger(2.5));
//Math.sign 判断一个数到底为正数 负数 还是零
console.log(Math.sign(100));
console.log(Math.sign(0));
console.log(Math.sign(-20000));
//Object.is 判断两个值是否完全相等
console.log(Object.is(120, 120));// ===
console.log(Object.is(NaN, NaN));// ===
console.log(NaN === NaN);// ===
//Object.assign 对象的合并
const config1 = {
host: 'localhost',
port: 3306,
name: 'root',
pass: 'root',
test: 'test'
};
const config2 = {
host: 'http://atguigu.com',
port: 33060,
name: 'atguigu.com',
pass: 'iloveyou',
test2: 'test2'
}
console.log(Object.assign(config1, config2)); //出现重名,后面参数属性覆盖前面
//Object.setPrototypeOf 设置原型对象
const school = {
name: '上官'
}
const cities = {
xiaoqu: ['北京','上海','深圳']
}
Object.setPrototypeOf(school, cities);
console.log(Object.getPrototypeOf(school));
console.log(school);
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
模块化的优势有以下几点:
ES6 之前的模块化规范有:
模块功能主要由两个命令构成:export 和 import。
⚫ export 命令用于规定模块的对外接口
⚫ import 命令用于输入其他模块提供的功能
以下分别为三个独立的js文件:
1. 分别暴露
//分别暴露
export let school = '上官';
export function teach() {
console.log("我们可以教给你开发技能");
}
2. 统一暴露
//统一暴露
let school = '上官';
function findJob(){
console.log("我们可以帮助你找工作!!");
}
//
export {school, findJob};
3. 默认暴露
//默认暴露
export default {
school: 'ATSHANGGUAN',
change: function(){
console.log("我们可以改变你!!");
}
}
以下为html模块导入方式:(导入后可直接使用模块中的相关元素)
<script type="module">
//1. 通用的导入方式
// 引入 m1.js 模块内容
import * as m1 from "./src/js/m1.js";//模块相对路径
//引入 m2.js 模块内容
import * as m2 from "./src/js/m2.js";
//引入 m3.js
import * as m3 from "./src/js/m3.js";
//2. 解构赋值形式
import {school, teach} from "./src/js/m1.js";
import {school as shangguan, findJob} from "./src/js/m2.js";//as重命名
import {default as m3} from "./src/js/m3.js";
//3. 简便形式 针对默认暴露
import m3 from "./src/js/m3.js";
console.log(m3);
</script>
<script src="./src/js/app.js" type="module"></script>
以上为单独导入模块的方式,下面将介绍引入NPM包进行导入,本次打包上面单独打包的三个文件:
//入口文件
//模块引入
import * as m1 from "./m1.js";
import * as m2 from "./m2.js";
import * as m3 from "./m3.js";
console.log(m1);
console.log(m2);
console.log(m3);
m1.teach();
m2.findJob();
m3.default.change();
//修改背景颜色为粉色
import $ from 'jquery';// const $ = require("jquery");
$('body').css('background','pink');
引入html之前的准备工作:
一番操作过后会在该目录下生成 dist/bundle.js 文件,在html中引入:
<script src="dist/bundle.js"></script>
即可使用该包中的所有元素。
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值
// includes indexOf
// const mingzhu = ['西游记','红楼梦','三国演义','水浒传'];
//判断
console.log(mingzhu.includes('西游记'));
console.log(mingzhu.includes('金瓶梅'));
// **
console.log(2 ** 10); //2的10次方
console.log(Math.pow(2, 10));
async 和 await 两种语法结合可以让异步代码像同步代码一样
//async 函数
async function fn(){
// 返回一个字符串
// return '上官';
// 返回的结果不是一个 Promise 类型的对象, 返回的结果就是成功 Promise 对象
// return;
//抛出错误, 返回的结果是一个失败的 Promise
// throw new Error('出错啦!');
//返回的结果如果是一个 Promise 对象
return new Promise((resolve, reject)=>{
resolve('成功的数据');
// reject("失败的错误");
});
}
const result = fn();
//调用 then 方法
result.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
//创建 promise 对象
const p = new Promise((resolve, reject) => {
// resolve("用户数据");
reject("失败啦!");
})
// await 要放在 async 函数中.
async function main() {
try {
let result = await p;
//
console.log(result);
} catch (e) {
console.log(e);
}
}
//调用函数
main();
//1. 引入 fs 模块
const fs = require("fs");
//读取『为学』
function readWeiXue() {
return new Promise((resolve, reject) => {
fs.readFile("./resources/为学.md", (err, data) => {
//如果失败
if (err) reject(err);
//如果成功
resolve(data);
})
})
}
function readChaYangShi() {
return new Promise((resolve, reject) => {
fs.readFile("./resources/插秧诗.md", (err, data) => {
//如果失败
if (err) reject(err);
//如果成功
resolve(data);
})
})
}
function readGuanShu() {
return new Promise((resolve, reject) => {
fs.readFile("./resources/观书有感.md", (err, data) => {
//如果失败
if (err) reject(err);
//如果成功
resolve(data);
})
})
}
//声明一个 async 函数
async function main(){
//获取为学内容
let weixue = await readWeiXue();
//获取插秧诗内容
let chayang = await readChaYangShi();
// 获取观书有感
let guanshu = await readGuanShu();
console.log(weixue.toString());
console.log(chayang.toString());
console.log(guanshu.toString());
}
main();
// 发送 AJAX 请求, 返回的结果是 Promise 对象
function sendAJAX(url) {
return new Promise((resolve, reject) => {
//1. 创建对象
const x = new XMLHttpRequest();
//2. 初始化
x.open('GET', url);
//3. 发送
x.send();
//4. 事件绑定
x.onreadystatechange = function () {
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
//成功啦
resolve(x.response);
}else{
//如果失败
reject(x.status);
}
}
}
})
}
//promise then 方法测试
// sendAJAX("https://api.apiopen.top/getJoke").then(value=>{
// console.log(value);
// }, reason=>{})
// async 与 await 测试 axios
async function main(){
//发送 AJAX 请求
let result = await sendAJAX("https://api.apiopen.top/getJoke");
//再次测试
let tianqi = await sendAJAX('https://www.tianqiapi.com/api/?version=v1&city=%E5%8C%97%E4%BA%AC&appid=23941491&appsecret=TXoD5e8P')
console.log(tianqi);
}
main();
//声明对象
const school = {
name:"尚硅谷",
cities:['北京','上海','深圳'],
xueke: ['前端','Java','大数据','运维']
};
//获取对象所有的键
console.log(Object.keys(school));
//获取对象所有的值
console.log(Object.values(school));
//entries
console.log(Object.entries(school));
//创建 Map
const m = new Map(Object.entries(school));
console.log(m.get('cities'));
//对象属性的描述对象
console.log(Object.getOwnPropertyDescriptors(school));
const obj = Object.create(null, {
name: {
//设置值
value: '尚硅谷',
//属性特性
writable: true,
configurable: true,
enumerable: true
}
});
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
function connect({host, port, ...user}) {
console.log(host);
console.log(port);
console.log(user);
}
connect({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root',
type: 'master'
});
ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强
let str = '上官';
const reg = /(?.*)<\/a> /;
const result = reg.exec(str);
console.log(result.groups.url);
console.log(result.groups.text);
ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选。
//声明字符串
let str = 'JS5211314 你知道么 555 啦啦啦';
//正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);
//反向断言
const reg = /(?<=么)\d+/;
const result = reg.exec(str);
console.log(result);
正则表达式中点.匹配除回车外的任何单字符,标记『s』改变这种行为,允许行终止符出现
let str = `
`;
//声明正则
const reg = /.*?(.*?)<\/a>.*?(.*?)<\/p>
/gs;
//执行匹配
const result = reg.exec(str);
let result;
let data = [];
while(result = reg.exec(str)){
data.push({title: result[1], time: result[2]});
}
//输出结果
console.log(data);
Object.fromEntries 方法用来创建一个对象,接收的参数是二维数组或者Map
const result = Object.fromEntries([
['name','黑马'],
['xueke', 'Java,大数据,前端,云计算']
]);
console.log(result);
const m = new Map();
m.set('name','ATGUIGU');
const result1 = Object.fromEntries(m);
console.log(result1);
const arr = Object.entries({
name: "尚硅谷"
})
console.log(arr);
trimStart 方法用来删除字符串之前的空格,trimEnd 用来删除字符串后面的空格
let str = ' iloveyou ';
console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());
Array.prototype.flat 方法用于将二维数组降维,转化为一维数组,方法的参数可以是深度,可控制降维深度,flatMap 方法既可以降维,又可以对被操作的对象进行加工返回
//flat 平
//将多维数组转化为低位数组
const arr = [1,2,3,4,[5,6]];
const arr = [1,2,3,4,[5,6,[7,8,9]]];
//参数为深度 是一个数字
console.log(arr.flat(2));
//flatMap
const arr = [1,2,3,4];
const result = arr.flatMap(item => [item * 10]);
console.log(result);
Symbol.prototype.description 方法用来获取 Symbol 的字符串描述
//创建 Symbol
let s = Symbol('尚硅谷');
console.log(s.description);
Promise.allSettled 方法接收一个Promise数组,返回一个Promise对象,并且返回的状态永远是成功的
//声明两个promise对象
const p1 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('商品数据 - 1');
},1000)
});
const p2 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('商品数据 - 2');
// reject('出错啦!');
},1000)
});
//调用 allsettled 方法
const result = Promise.allSettled([p1, p2]);
const res = Promise.all([p1, p2]);
console.log(res);
类似Java,类外不能直接访问,只能通过方法内部封装调用访问
class Person{
//公有属性
name;
//私有属性
#age;
#weight;
//构造方法
constructor(name, age, weight){
this.name = name;
this.#age = age;
this.#weight = weight;
}
intro(){
console.log(this.name);
console.log(this.#age);
console.log(this.#weight);
}
}
//实例化
const girl = new Person('晓红', 18, '45kg');
// console.log(girl.name);
// console.log(girl.#age);
// console.log(girl.#weight);
girl.intro();
String.prototype.matchAll 方法用来获得正则批量匹配的结果,可以将匹配对象,匹配结果按照数组的方式匹配出来
let str = ``;
//声明正则
const reg = /.*?(.*?)<\/a>.*?(.*?)<\/p>
/sg
//调用方法
const result = str.matchAll(reg);
// for(let v of result){
// console.log(v);
// }
const arr = [...result];//返回匹配结果为可迭代对象,既可以用for...of遍历,也可以用扩展运算符进行展开
console.log(arr);
这个可以省区多层级获取对象属性的判断流程
// ?.
function main(config){
// const dbHost = config && config.db && config.db.host;
const dbHost = config?.db?.host;
console.log(dbHost);
}
main({
db: {
host:'192.168.1.100',
username: 'root'
},
cache: {
host: '192.168.1.200',
username:'admin'
}
})
export function hello(){
alert('Hello');
}
// import * as m1 from "./hello.js";
//获取元素
const btn = document.getElementById('btn');
btn.onclick = function(){
import('./hello.js').then(module => {
module.hello();
});
}
globalThis 指向全局对象,可以对全局对象进行操作
console.log(globalThis); //global(node.js)或者window(html)
//大整形
// let n = 521n;
// console.log(n, typeof(n)); //bigint类型
//函数
let n = 123;
console.log(BigInt(n));
console.log(BigInt(1.2));//报错
//大数值运算
let max = Number.MAX_SAFE_INTEGER; //最大安全整数
console.log(max);
console.log(max + 1);
console.log(max + 2); //不变,已经很大了
console.log(BigInt(max))
console.log(BigInt(max) + BigInt(1))
console.log(BigInt(max) + BigInt(2)) //变化