1.1.let 关键字
let 关键字用来声明变量,使用 let 声明的变量有几个特点:
- 不允许重复声明
- 块儿级作用域
- 不存在变量提升
- 不影响作用域链
应用场景:以后声明变量使用 let 就对了
//1. 变量不能重复声明
// let star = '罗志祥';
// let star = '小猪';
//2. 块儿级作用域 全局, 函数, eval
// if else while for
// {
// let girl = '周扬青';
// }
// console.log(girl);
//3. 不存在变量提升
// console.log(aa);
// var aa = 123;undefined
// console.log(song);
// let song = '恋爱达人';
//4. 不影响作用域链
// {
// let school = '啊啊啊';
// function fn(){
// console.log(school);
// }
// fn();
// }
1.2. const 关键字
const 关键字用来声明常量,const 声明有以下特点
- 声明必须赋初始值
- 标识符一般为大写
- 不允许重复声明
- 值不允许修改
- 块儿级作用域
注意: 对象属性修改和数组元素变化不会触发 const 错误
应用场景:声明对象类型使用 const,非对象类型声明选择 let
//1. 一定要赋初始值
// const A;
//2. 一般常量使用大写(潜规则)
// const a = 100;
//3. 常量的值不能修改
// SCHOOL = 'ATGUIGU';
//4. 块儿级作用域
// {
// const PLAYER = 'UZI';
// }
// console.log(PLAYER);
//5. 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错
// const TEAM = ['UZI','MXLG','Ming','Letme'];
// TEAM.push('Meiko');
// TEAM[0] = "aa"
// console.log(TEAM)
1.3.变量的解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称
为解构赋值。
//数组的解构赋值
const arr = ['张学友', '刘德华', '黎明', '郭富城'];
let [zhang, liu, li, guo] = arr;
//对象的解构赋值
const lin = {
name: '林志颖',
tags: ['车手', '歌手', '小旋风', '演员']
};
let {name, tags} = lin;
//复杂解构
let wangfei = {
name: '王菲',
age: 18,
songs: ['红豆', '流年', '暧昧', '传奇'],
history: [
{name: '窦唯'},
{name: '李亚鹏'},
{name: '谢霆锋'}
]
};
let {songs: [one, two, three], history: [first, second, third]} =
wangfei;
注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式
//ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,
//这被称为解构赋值。
//1. 数组的结构
// const F4 = ['小沈阳','刘能','赵四','宋小宝'];
// let [xiao, liu, zhao, song] = F4;
// console.log(xiao);
// console.log(liu);
// console.log(zhao);
// console.log(song);
//2. 对象的解构,变量名与属性名要一致
// 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();
1.4.模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:
- 字符串中可以出现换行符
- 可以使用 ${xxx} 形式输出变量
注意:当遇到字符串与变量拼接的情况使用模板字符串
// ES6 引入新的声明字符串的方式 『``』 '' ""
//1. 声明
let str = `我也是一个字符串哦!`;
//string类型
console.log(str, typeof str);
//2. 内容中可以直接出现换行符
// var str = `<ul>
// <li>沈腾</li>
// <li>玛丽</li>
// <li>魏翔</li>
// <li>艾伦</li>
// </ul>`;
// //3. 变量拼接,模板字符串
// // ``和 ${}配合使用
// let lovest = '魏翔';
// let out = `${lovest}是我心目中最搞笑的演员!!`;
// console.log(out);
1.5.简化对象写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这
样的书写更加简洁。
注意:对象简写形式简化了代码,所以以后用简写就对了
//ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。
//这样的书写更加简洁
let name = '尚硅谷';
let change = function(){
console.log('我们可以改变你!!');
}
//简化写法
const school = {
name,
change,
improve(){
console.log("我们可以提高你的技能");
}
}
console.log(school.change());//输出“我们可以改变你!!”
1.6.箭头函数
ES6 允许使用「箭头」(=>)定义函数。
/**
* 1. 通用写法
*/
let fn = (arg1, arg2, arg3) => {
return arg1 + arg2 + arg3;
}
箭头函数的注意点:
- 如果形参只有一个,则小括号可以省略
- 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的
执行结果 - 箭头函数 this 指向声明时所在作用域下 this 的值
- 箭头函数不能作为构造函数实例化
- 不能使用 arguments
/* 3. 省略花括号的情况*/
let fn3 = score => score * 20;
/**
* 4. this 指向声明时所在作用域中 this 的值*/
let fn4 = () => {
console.log(this);//window
}
举例:
// ES6 允许使用「箭头」(=>)定义函数。
//声明一个函数,e5方式
let fn = function(){
}
let fn = (a,b)=>{
return a*b;
}
//调用函数
let result = fn(1, 2);
console.log(result);
//1. this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
function getName(){
console.log(this.name);//window.name
}
let getName2 = () => {
console.log(this.name);//window.name
}
//设置 window 对象的 name 属性
window.name = '尚硅谷';
const school = {
name: "ATGUIGU"
}
//直接调用
getName();
getName2();
//call 方法调用
getName.call(school);
getName2.call(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(9));
//2) 省略花括号, 当代码体只有一条语句的时候, 此时 return 必须省略
而且语句的执行结果就是函数的返回值
let pow = n => n * n;
console.log(pow(8));
注意: 箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调
箭头函数不适合与 this 有关的回调. 事件回调, 对象的方法
1.7 ES6 允许给函数参数赋值初始值
//ES6 允许给函数参数赋值初始值
//1. 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
// function add(a,c=10,b) {
// return a + b + c;
// }
// let result = add(1,2);
// console.log(result);
//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
// })
1.8. rest 参数
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
/**
* 作用与 arguments 类似
*/
function add(...args){
console.log(args);//1,2,3,4,5
}
add(1,2,3,4,5);
/**
* rest 参数必须是最后一个形参
*/
function minus(a,b,...args){
console.log(a,b,args);//args :2,3,4,5,19
}
minus(100,1,2,3,4,5,19);
注意:rest 参数非常适合不定个数参数函数的场景
举例:
// ES6 引入 rest 参数(...),用于获取函数的实参,用来代替 arguments类数组对象
// ES5 获取实参的方式,类数组对象
// function date(){
// console.log(arguments);
// }
// date('白芷','阿娇','思慧');
// rest 参数,数组对象
function date(...args){
console.log(args);// filter some every map
}
date('阿娇','柏芝','思慧');//'阿娇','柏芝','思慧'
// rest 有参数必须要放到参数最后
// function fn(a,b,...args){
// console.log(a);
// console.log(b);
// console.log(args);
// }
// fn(1,2,3,4,5,6);
// //作用是代表实参,...args = 3,4,5,6
1.9. spread 扩展运算符
扩展运算符(spread)也是三个点(…)。它好比 rest 参数的逆运算,将一
个数组转为用逗号分隔的参数序列,对数组进行解包。
// 『...』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』
//声明一个数组 ...
const tfboys = ['易烊千玺','王源','王俊凯'];
// => '易烊千玺','王源','王俊凯'
// 声明一个函数
function chunwan(){
console.log(arguments);
}
chunwan(...tfboys);// chunwan('易烊千玺','王源','王俊凯'),3个参数
chunwan(tfboys);//1个参数是数组
拓展:
//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
2.0 Symbol
2.0.1.Symbol 基本使用
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是
JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol 特点
- Symbol 的值是唯一的,用来解决命名冲突的问题
- Symbol 值不能与其他数据进行运算
- Symbol 定义 的 对象属 性 不能 使 用 for…in 循 环遍 历 ,但 是可 以 使 用
Reflect.ownKeys 来获取对象的所有键名
注: 遇到唯一性的场景时要想到 Symbol
//创建 Symbol
let s1 = Symbol();
console.log(s1, typeof s1);// "symbol"
//添加标识的 Symbol
let s2 = Symbol('123');
let s2_2 = Symbol('123');
console.log(s2 === s2_2);//编号不一样,false
//使用 Symbol for 定义
let s3 = Symbol.for('123');
let s3_2 = Symbol.for('123');
console.log(s3 === s3_2);//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(){}
};
//声明一个对象
// let methods = {
// up: Symbol(),
// down: Symbol()
// };
//安全高效的添加方法
// game[methods.up] = function(){
// console.log("我可以改变形状");
// }
// game[methods.down] = function(){
// console.log("我可以快速下降!!");
// }
// console.log(game);
//方式二
let youxi = {
name:"狼人杀",
//Symbol():function这种方式错误,因为symbol是个动态值,家[]
[Symbol('say')]: function(){
console.log("我可以发言")
},
[Symbol('zibao')]: function(){
console.log('我可以自爆');
}
}
console.log(youxi)
其他属性:
//当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法
// 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];
// arr2[Symbol.isConcatSpreadable] = false;
//表示该对象用于 Array.prototype.concat()时,是否可以展开,是一个整体
// console.log(arr.concat(arr2));
2.1. 迭代器
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提
供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
- ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费
- 原生具备 iterator 接口的数据(可用 for of 遍历)
a) Array
b) Arguments
c) Set
d) Map
e) String
f) TypedArray
g) NodeList - 工作原理
a) 创建一个指针对象,指向当前数据结构的起始位置
b) 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
c) 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
d) 每调用 next 方法返回一个包含 value 和 done 属性的对象
注: 需要自定义遍历数据的时候,要想到迭代器。
//声明一个数组
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
//使用 for...in 遍历数组保存的是下标
// for (let i in xiyou){
// console.log(i);//0 1 2 3
// }
//for...of 遍历数组保存的是键名
// for(let v of xiyou){
// console.log(v);// '唐僧','孙悟空','猪八戒','沙僧'
// }
//创建一个指针对象
let iterator = xiyou[Symbol.iterator]();
// //调用对象的next方法,done表示是否完成
console.log(iterator.next());//value: "唐僧", done: false
// console.log(iterator.next());
// console.log(iterator.next());
// console.log(iterator.next());
// console.log(iterator.next());//value: undefined, done: true
2.2. 生成器
生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同
代码说明:
- * 的位置没有限制
- 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到
yield 语句后的值 - yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next
方法,执行一段代码 - next 方法可以传递实参,作为 yield 语句的返回值
//生成器其实就是一个特殊的函数,迭代器对象
//异步编程 纯回调函数 node fs ajax mongodb
//yield函数代码的分隔符
function * gen(){
// console.log(111);
yield '一只没有耳朵';
// console.log(222);
yield '一只没有尾部';
// console.log(333);
yield '真奇怪';
// console.log(444);
}
//执行获取迭代器对象,gen()的返回值是一个迭代器对象
let iterator = gen();
//通过iterator中的next()方法来运行,控制next()方法控制执行
console.log(iterator.next());//111 一只没有耳朵
console.log(iterator.next());//222 一只没有尾部
console.log(iterator.next());//333 真奇怪
console.log(iterator.next());//444 undefined
//遍历
// 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);
}
//执行获取迭代器对象,gen()的返回值是一个迭代器对象
let iterator = gen('AAA');
console.log(iterator.next());
//next方法可以传入实参,下次调用时,参数值将作为上一个yield的返回值
console.log(iterator.next('BBB'));
console.log(iterator.next('CCC'));
console.log(iterator.next('DDD'));
生成器函数,解决回调地狱问题:
// 异步编程 文件操作 网络操作(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();
},2000)
}
function three(){
setTimeout(()=>{
console.log(333);
iterator.next();
},3000)
}
function * gen(){
yield one();
yield two();
yield three();
}
//调用生成器函数
let iterator = gen();
iterator.next();
2.3 Promise
Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,
用来封装异步操作并可以获取其成功或失败的结果。
- Promise 构造函数: Promise (excutor) { }
- Promise.prototype.then 方法
- Promise.prototype.catch 方法
//实例化 Promise 对象
//通过resolve, reject来改变状态,成功则调用resolve,失败则调reject
const p = new Promise(function(resolve, reject){
setTimeout(function(){
//
// let data = '数据库中的用户数据';
// resolve
// resolve(data);
let err = '数据读取失败';
reject(err);
}, 1000);
});
//调用 promise 对象的 then 方法
p.then(function(value){
console.log(value);
}, function(reason){
console.error(reason);
})
封装ajax方法:
const p = new Promise((resolve, reject) => {
//1. 创建对象
const xhr = new XMLHttpRequest();
//2. 初始化
xhr.open("GET", "https://api.apiopen.top/getJoke");
//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);
});
then方法发返回值:
//调用 then 方法 then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定
//1. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值
// const result = p.then(value => {
// console.log(value);
// //1. 非 promise 类型的属性
// // return 'iloveyou';
// //2. 是 promise 对象,为该对象的状态和值
// // return new Promise((resolve, reject)=>{
// // // resolve('ok');
// // reject('error');
// // });
// //3. 抛出错误,为错误类型,值为该值,状态为reject,失败
// // throw new Error('出错啦!');
// throw '出错啦!';
// }, reason=>{
// console.warn(reason);
// });
读取多个文件,解决回调地狱问题:
//引入 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'));
});
Promise.prototype.catch 方法:
// 指定promise失败时的回调
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);
2.4 Set
ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯
一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进
行遍历,集合的属性和方法:
- size 返回集合的元素个数
- add 增加一个新元素,返回当前集合
- delete 删除元素,返回 boolean 值
- has 检测集合中是否包含某个元素,返回 boolean 值
- clear 清空集合,返回 undefined
//创建一个空集合
let s = new Set();
//创建一个非空集合
let s1 = new Set([1,2,3,1,2,3]);
//集合属性与方法
//返回集合的元素个数
console.log(s1.size);
//添加新元素
console.log(s1.add(4));
//删除元素
console.log(s1.delete(1));
//检测是否存在某个值
console.log(s1.has(2));
//清空集合
console.log(s1.clear());
2.5 Map
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”
的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了
iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。Map 的属
性和方法:
- size 返回 Map 的元素个数
- set 增加一个新元素,返回当前 Map
- get 返回键名对象的键值
- has 检测 Map 中是否包含某个元素,返回 boolean 值
- clear 清空集合,返回 undefined
//创建一个空 map
let m = new Map();
//创建一个非空 map
let m2 = new Map([
['name','尚硅谷'],
['slogon','不断提高行业标准']
]);
//属性和方法
//获取映射元素的个数
console.log(m2.size);
//添加映射值
console.log(m2.set('age', 6));
//获取映射值
console.log(m2.get('age'));
//检测是否有该映射
console.log(m2.has('age'));
//清除
console.log(m2.clear())
2.6 class 类
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对
象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是
一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象
原型的写法更加清晰、更像面向对象编程的语法而已。
知识点:
- class 声明类
- constructor 定义构造函数初始化
- extends 继承父类
- super 调用父级构造方法
- static 定义静态方法和属性
- 父类方法可以重写
// 使用 static 关键字,可以定义静态属性
// 所谓的静态属性,就是 可以直接通过 类名, 直接访问的属性
// 实例属性: 只能通过类的实例,来访问的属性,叫做实例属性
举例:创建一个类
//定义class类
class Shouji{
//构造方法 名字不能修改
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//方法必须使用该语法, 不能使用 ES5 的对象完整形式
call(){
console.log("我可以打电话!!");
}
}
//实例化对象
let onePlus = new Shouji("1+", 1999);
//调用方法
onePlus.call();
console.log(onePlus);
继承(es5继承方式):
//手机
function Phone(brand, price){
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function(){
console.log("我可以打电话");
}
//智能手机
function SmartPhone(brand, price, color, size){
// 改变this指向
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();
重写方法:
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方法
call(){
console.log('我可以进行视频通话');
}
}
const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
// console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();
get和set
对,对象的属性加以方法的绑定,读取的时候触发get,修改的时候触发set
// get 和 set ,get是获得,set是改变
class Phone{
get price(){
console.log("价格属性被读取了");
return 'iloveyou';
}
set price(newVal){//必须要有参数
console.log('价格属性被修改了');
}
}
//实例化对象
let s = new Phone();
// console.log(s.price);
s.price = 'free';
2.7数值扩展
2.7.1. 二进制和八进制
ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示。
2.7.2. Number.isFinite() 与 Number.isNaN()
Number.isFinite() 用来检查一个数值是否为有限的
Number.isNaN() 用来检查一个值是否为 NaN
2.7.3. Number.parseInt() 与 Number.parseFloat()
ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变。
2.7.4. Math.trunc
用于去除一个数的小数部分,返回整数部分。
2.7.5. Number.isInteger
Number.isInteger() 用来判断一个数值是否为整数
//0. Number.EPSILON 是 JavaScript 表示的最小精度
//EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16
// function equal(a, b){
// if(Math.abs(a-b) < Number.EPSILON){
// return true;
// }else{
// return false;
// }
// }
// console.log(0.1 + 0.2 === 0.3);
// console.log(equal(0.1 + 0.2, 0.3))
//1. 二进制和八进制
// let b = 0b1010;
// let o = 0o777;
// let d = 100;
// let x = 0xff;
// console.log(x);
//2. Number.isFinite 检测一个数值是否为有限数
// console.log(Number.isFinite(100));
// console.log(Number.isFinite(100/0));
// console.log(Number.isFinite(Infinity));
//3. Number.isNaN 检测一个数值是否为 NaN
// console.log(Number.isNaN(123));
//4. Number.parseInt Number.parseFloat字符串转整数
// console.log(Number.parseInt('5211314love'));
// console.log(Number.parseFloat('3.1415926神奇'));
//5. Number.isInteger 判断一个数是否为整数
// console.log(Number.isInteger(5));
// console.log(Number.isInteger(2.5));
//6. Math.trunc 将数字的小数部分抹掉
// console.log(Math.trunc(3.5));
//7. Math.sign 判断一个数到底为正数 负数 还是零
console.log(Math.sign(100));
console.log(Math.sign(0));
console.log(Math.sign(-20000));
2.8对象扩展
ES6 新增了一些 Object 对象的方法
- Object.is 比较两个值是否严格相等,与『===』行为基本一致(+0 与 NaN)
- Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象
- proto、setPrototypeOf、 setPrototypeOf 可以直接设置对象的原型
//1. Object.is 判断两个值是否完全相等
// console.log(Object.is(120, 120));// === true
// console.log(Object.is(NaN, NaN));// === true
// console.log(NaN === NaN);// === false
//2. 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));
//3. Object.setPrototypeOf 设置原型对象 Object.getPrototypeof
const city = {
name: '城市'
}
const cities = {
xiaoqu: ['北京','上海','深圳']
}
Object.setPrototypeOf(city, cities);
console.log(Object.getPrototypeOf(city));
console.log(city);
2.9 模块化
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
2.9.1. 模块化的好处
模块化的优势有以下几点:
- 防止命名冲突
- 代码复用
- 高维护性
2.9.2. 模块化规范产品
ES6 之前的模块化规范有:
- CommonJS => NodeJS、Browserify
- AMD => requireJS
- CMD => seaJS
2.9.3. ES6 模块化语法
模块功能主要由两个命令构成:export 和 import。
⚫ export 命令用于规定模块的对外接口
// 注意: 使用 export 向外暴露的成员,只能使用 { } 的形式来接收,这种形式,叫做 【按需导出】
// 注意: export 可以向外暴露多个成员, 同时,如果某些成员,我们在 import 的时候,不需要,则可以 不在 {} 中定义
// 注意: 使用 export 导出的成员,必须严格按照 导出时候的名称,来使用 {} 按需接收;
// 注意: 使用 export 导出的成员,如果 就想 换个 名称来接收,可以使用 as 来起别名;
⚫ import 命令用于输入其他模块提供的功能
引入方式:
(返回的是一个对象)
1.通用的导入方式
//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.解构赋值形式
//2. 解构赋值形式
import {school, teach} from "./src/js/m1.js";
// 重名可以使用别名
import {school as guigu, findJob} from "./src/js/m2.js";
// 重名可以使用别名,默认暴露,要使用别名
import {default as m3} from "./src/js/m3.js";
3. 简便形式 针对默认暴露
//3. 简便形式 针对默认暴露
// import m3 from "./src/js/m3.js";
// console.log(m3);
暴露的方式:
1.分别暴露–m1.js
//分别暴露
export let school = '尚硅谷';
export function teach() {
console.log("我们可以教给你开发技能");
}
2.统一暴露–m2.js
//统一暴露
let school = '尚硅谷';
function findJob(){
console.log("我们可以帮助你找工作!!");
}
//
export {school, findJob};
3.默认暴露–m3.js
//默认暴露,方式1
export default {
school: 'ATGUIGU',
change: function(){
console.log("我们可以改变你!!");
}
}
//方式2
var info = {
school: 'ATGUIGU',
change: function(){
console.log("我们可以改变你!!");
}
}
export default info
注意:使用默认暴露调用方法要加default:
注意: export default 向外暴露的成员,可以使用任意的变量来接收
注意: 在一个模块中,export default 只允许向外暴露1次
注意: 在一个模块中,可以同时使用 export default 和 export 向外暴露成员
m3.default.change();
通过app.js来导入:
一定要加:type=“module”
<script src="./src/js/app.js" type="module"></script>
<!--
1. 安装工具 npm i babel-cli babel-preset-env browserify(webpack) -D
-D表示开发依赖
2. 编译 npx babel src/js -d dist/js --presets=babel-preset-env(将前面文件存到那个文件夹下)
3. 打包 npx browserify dist/js/app.js -o dist/bundle.js
-o后面跟输出的位置
-->
<script src="dist/bundle.js"></script>