尚硅谷es6新特性笔记
一、let与const
let的变量声明以及声明特性
1、变量不能重复声明
let star = '罗志祥';
let stsr = '罗猪'; //报错
2、块儿级作用域全局, 函数,eval
if else while for {
let girl = '周扬青';
}
console.log(girl); //报错
3、不存在变量提升
console.log(song);
let song = 恋爱达人; //打印成功
4、不影响作用域链
let school = '尚硅谷';
function fn(){
console.log(school);
}
fn(); //打印成功
const的变量声明以及声明特性
1、一定要赋初始值
2、一般常量使用大写(潜规则)
const A = 100;
3、常量的值不能修改
const SCHOOL = '尚硅谷';
SCHOOL = '文斗斯'; //报错
4、块儿级作用域
{
const PLAYER = 'UZI' ;
}
console.log(PLAYER); //报错
5、对于数组和对象的元素修改,不算做对常量的修改,不会报错
const TEAM = ['UZI', 'MXLG', 'Ming', 'Letme'] ;
TEAM push('Meiko');
const、let、var 三者之间的区别
- var 语句的作用域是函数作用域或者全局作用域;它没有块作用域,故不存在暂时死区;它可分配,也可重复性声明。
- let 语句属于块作用域,受到暂时死区的约束;它可分配,但不可重新声明。
- const 语句也属于块作用域,同样受到暂时死区的约束;它既不可重新分配,也不可重新声明。
二、变量解构赋值
解构赋值: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();
三、模板字符串
ES6引入新的声明字符串的方式,反引号。
1、声明
let str = `我是一个字符串`;
console.log(str, typeof str);
2、 内容中可以直接出现换行符
let str =`<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`;
3、变量拼接
let lovest = '魏翔';
let out =`${lovest}是我心目中最搞笑的演员!!`;
console.log(out);
四、对象的简化写法
ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。
let name = '尚硅谷';
let change = function(){
console.log('我们可以改变你!!');
}
//简化
const school = {
name,
change,
improve(){
console.log('我们可以你的提高技能!!');
}
}
五、箭头函数
声明特点
ES6允许使用「箭头」 (=>)定义函数。
//声明 一个函数
//let fn = function(){}
let fn=(a,b)=>{
return a + b;
}
//调用函数
let result = fn(1, 2);
console.1og(result);
箭头函数的特性
1、this 是静态的。this 始终指向函数声明时所在作用域下的this的值。
function getName(){
console.log(this.name);
}
let getName2=()=>{
console.log(this.name); //this始终指向window
}
//设置window对象的name属性
window.name = '尚硅谷';
const school = {
name:"ATGUIGU"
}
//直接调用
getName(); //打印出“尚硅谷”
getName2(); //打印出“尚硅谷”
//call方法调用
getName.cal1(school); //打印出“ATGUIGU”
getName2.ca1l(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)省略花括号,当代码体只有一条语句的时候
let pow = n => n * n;
console.log(pow(8));
六、函数参数默认值的设置
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', //若后来没有传值,则用默认值"127.0.0.1"
username:'root'
password:'root',
port: 3306
})
七、rest参数
ES6引入rest参数,用于获取函数的实参,用来代替arguments 。
1、ES5获取实参的方式
function date(){
console.log(arguments) ;
}
date('白芷','阿娇','思慧');
2、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);
八、扩展运算符
「…」扩展运算符能将「数组」转换为逗号分隔的「 参数序列」
//声明一个数组
const tfboys = ['易烊千玺','王源','王俊凯'];
// => '易烊千玺','王源','王俊凯
//声明一个函数
function chunwan(){
console.log(arguments);
}
chunwan(...tfboys);// chunwan('易烊千玺','王源','王俊凯')
扩展符的应用
//1.数组的合并
const kuaizi = ['王太利','肖央'];
const fenghuang = ['曾毅','玲花'];
const zxmzf = [...kuaizi,...fenghuang];
console.log(zxmzf);
//2.数组的克隆
const sanzhihua = ['E','G','M'];
const sanyecao = [...sanzhihua];// ['E','G','M']
console.log(sanyecao);
//3. 将伪数组转为真正的数组
<div></div>
<div></div>
<div></div>
<script>
const divs = document.querySelectorAll('div');
const divArr = [...divs];
console.log(divArr);// arguments
</script>
九、Symbol
ES6引入了一种新的原始数据类型Symbol, 表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol的特点
- Symbol 的值是唯一的, 用来解决命名冲突的问题
//创建Symbol
let s = Symbol();
console.log(s, typeof s);
let s2 = Symbol('尚硅谷');
let s3 = Symbol('尚硅谷');
console.log(s2 === s3); //flase
//Symbol.for创建
let s4 = Symbol.for('尚硅谷');
let s5 = Symbol.for('尚硅谷');
console.log(s4 === s5); //flase
- Symbol值不能与其他数据进行运算
let s = Symbol();
let result = s + 100;
let result = s >100;
let result = s + s; //全部报错
- Symbol 定义的对象属性不能使用for…in 循环遍历,但是可以使用 Reflect.ownKeys来获取对象的所有键名
Symbol的使用
对象添加Symbol类型的属性
//例1
let methods = {
up: Symbol(),
down: Symbol( )
};
game[methods.up] = function( ){
console.log("我可以改变形状");
}
game[methods.down] = function( ){
console.log("我可以快速下降!!");
}
console.log(game);
//例2
let youxi = {
name: "狼人杀",
[Symbol('say')]: function(){
console.log("我可以发言")
},
[Symbol('zibao')]: function(){
console.log('我可以自爆');
}
}
console.log(youxi)
Symbol的内置属性
//Symbol.hasInstance
//当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法
class Person{
static [Symbol.hasInstance](param){
console.log(param);
console.log("我被用来检测类型了");
}
}
let o = {};
console.log(o instanceof Person); //flase
//Symbol.isConcatSpreadable
//对象的Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。
const arr = [1,2,3];
const arr2 = [4,5,6];
arr2[Symbol.isConcatSpreadable] = false; //不可展开
console.log(arr.concat(arr2));
十、迭代器
迭代器介绍
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator 接口,就可以完成遍历操作。
1、ES6创造了一种新的遍历命令for…of循环,Iterator 接口主要供for…of消费
2、原生具备iterator接口的数据(可用for of遍历):
a) Array
b)Arguments
c)Set
d)Map
e)String
f)TypedArray
g)NodeList
3、工作原理
a)创建一个指针对象,指向当前数据结构的起始位置
b)第一次调用对象的 next方法,指针自动指向数据结构的第一个成员
c)接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
d)每调用next方法返回一个包含value和done属性的对象
//声明一个数组
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());
迭代器应用
//声明一个对象
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提供的一种异步编程解决方案,语法行为与传统函数完全不同。
生成器函数声明与调用
function * gen1(){
console. log("hello generator")
}
let iterator = gen1();
iterator.next();
function * gen2(){
console.log(111);
yield '一只没有耳朵'; //代码的分隔符
console.log(222);
yield '一只没有尾部';
console.log(333);
yield '真奇怪' ;
console.log (444);
}
let iterator = gen2();
iterator.next(); //只打印111
iterator.next(); //只打印222
iterator.next(); //只打印333
iterator.next(); //只打印444
//遍历
for(let v of gen2()){
console.log(v); //打印三个yield后面的字符串
}
生成器函数的参数传递
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'));
console.log(iterator.next('CCC'));
console.log(iterator.next('DDD'));
实例一
//回调地狱
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
},3000);
},2000);
},1000);
function one() {
setTimeout(() => {
console.log(444);
iterator.next();
}, 1000)
}
function two() {
setTimeout(() => {
console.log(555);
iterator.next();
}, 2000)
}
function three() {
setTimeout(() => {
console.log(666);
iterator.next();
}, 3000)
}
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();
console.log(users);
let orders = yield getOrders();
console.log(orders);
let goods = yield getGoods();
console.log(goods);
}
//调用生成器函数
let iterator = gen();
iterator.next();
十二、Promise
Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
Promise的基本使用
//实例化Promise 对象
const p = new Promise(function (resolve, reject) {
setTimeout(function () {
//let data = '数据库中的用户数据';
//resolve(data);
let err = '数据读取失败';
reject(err);
}, 1000);
});
//调用promise 对象的then 方法
p.then(function (value) {
console.log(value); //成功
}, function (reason) {
console.error(reason); //失败
})
Promise封装读取文件
js文件
//node.js
//1.引入fs模块
const fs = require('fs');
//2. 调用方法读取文件
// fs.readFile('./hist.txt', (err, data) => {
// //如果失败, 则抛出错误
// if (err) throw err;
// //如果没有出错,则输出内容
// console.log(data.toString());
// });
//3. 使用Promise 封装
const p = new Promise(function (resolve, reject) {
fs.readFile("./hist.txt", (err, data) => {
//判断如果失败
if (err) reject(err);
//如果成功
resolve(data);
});
});
p.then(function (value) {
console.log(value.toString());
}, function (reason) {
console.log("读取失败!");
});
Promise封装ajax请求
const p = new Promise((resolve, reject) => {
//1. 创建对象
const xhr = new XMLHttpRequest();
//2.初始化
xhr.open("GET", "http://127.0.0.1/user");
//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);
});
服务器js文件
// 1.导入express
const express = require('express')
// 2.创建web服务器
const app = express()
app.get('/user', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应体
response.send("Hello Ajax");
})
//3.启动web服务器
app.listen(80, () => {
console.log('express server running at http://127.0.0.1')
})
Promise.prototype.then方法
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据');
//reject('出错啦');
}, 1000)
})
//调用then 方法then方法的退回结果是Promise 对象,对象状态由回调函数的执行结果决定
//1.如果回调函数中返回的结果是非promise 类型的属性,状态为成功,返回值为对象的成功的值
const result = p.then(value => {
console.log(value);
//1.非promise 类型的属性
//return 123;
//2.是promise 对象
// return new Promise((resolve, reject) => {
// //resolve('ok');
// reject('error')
/ });
//3.抛出错Error
throw new Error('出错啦!')
}, reason => {
console.warn(reason);
});
console.log(result);
//也可以链式调用,嵌套异步任务,杜绝回调域
Promise实践(多个文件肉容读取)
//引入fs模块
const fs = require("fs");
// fs.readFile('./hist.txt', (err, data1) => {
// fs.readFile('./wx.txt', (err, data2) => {
// fs.readFile('./sg.txt', (err, data3) => {
// let result = data1 + '\r\n' + data2 + '\r\n' + data3 + '\n';
// console.log(result);
// });
// });
// });
//使用promise 实现,不会产生回调地狱的现象
const p = new Promise((resolve, reject) => {
fs.readFile("./hist.txt", (err, data) => {
resolve(data);
});
});
p.then(value => {
return new Promise((resolve, reject) => {
fs.readFile("./wx.txt", (err, data) => {
resolve([value, data]);
});
})
}).then(value => {
return new Promise((resolve, reject) => {
fs.readFile("./sg.txt", (err, data) => {
//压入
value.push(data);
resolve(value);
});
})
}).then(value => {
console.log(value.join('\r\n'));
})
Promise对象catch方法
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);
})
十三、Set(集合)
集合介绍
ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator 接口,所以可以使用【扩展运算符】和【for…of…】进行遍历,集合的属性和方法:
1) size: 返回集合的元素个数
2)add: 增加一个新元素,返回当前集合
3)delete: 删除元素,返回boolean 值
4)has : 检测集合中是否包含某个元素,返回boolean值
//声明一个 set
let s = new Set();
let s2 = new Set(['大事儿', '小事儿', '好事儿', '坏事儿', '小事儿']);
//自动去重,只有一个'小事儿',相当于高中数学集合的互异性
console.log(s2);
//元素个数
console.log(s2.size);
//添加新元素
s2.add('喜事儿');
console.log(s2);
//删除元素
s2.delete('坏事儿');
console.log(s2);
//检测
console.log(s2.has('中事儿'));
//遍历
for (let v of s2) {
console.log(v);
}
//清空集合
s2.clear();
console.log(s2);
集合实践
集合运算
let arr1 = [1, 2, 3, 4, 5, 4, 3, 2, 1];
//1. 数组去重
let result1 = [...new Set(arr1)];
console.log(result1);
//2. 交集
let arr2 = [4, 5, 6, 5, 6];
// let result2 = [...new Set(arr1)].filter(item => {
// let s2 = new Set(arr2); // 4 5 6
// if (s2.has(item)) {
// return true;
// } else {
// return false;
// }
// });
//简化
let result2 = [...new Set(arr1)].filter(item => new Set(arr2).has(item));
console.log(result2);
//3. 并集
let union = [...new Set([...arr1, ...arr2])];
console.log(union);
//4. 差集
let diff = [...new Set(arr1)].filter(item => !(new Set(arr2).has(item)));
console.log(diff);
十四、Map
ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator 接口,所以可以使用【扩展运算符】和【for…of…】进行遍历。Map的属性和方法:
1)size:返回Map的元素个数
2)set:增加一个新元素,返回当前Map
3)get:返回键名对象的键值
4)has:检测Map中是否包含某个元素,返回boolean值
5)clear:清空集合,返回undefined
//声明 Map
let m = new Map();
//添加元素
m.set('name', '尚硅谷');
console.log(m);
m.set('change', function () {
console.log("我们可以改变你!!");
});
console.log(m);
let key = {
school: 'ATGUIGU'
};
m.set(key, ['北京', '上海', '深圳']);
console.log(m);
//元素个数
console.log(m.size);
//删除
m.delete('name');
console.log(m);
//获取
console.log(m.get('change'));
console.log(m.get(key));
//遍历
for (let v of m) {
console.log(v);
}
//清空
m.clear();
console.log(m);
十五、class类
class介绍
ES6提供了更接近传统语言的写法,引入了Class (类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而己。
知识点:
- class 声明类
- constructor 定义构造函数初始化
- extends 继承父类
- super 调用父级构造方法
- static定义静态方法和属性
- 父类方法可以重写
//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);
onePlus.call();
console.log(onePlus);
class静态成员
静态成员,只有函数、类可以用。
function Phone() {
}
Phone.name = '手机';
Phone.change = function () { //属于函数对象(静态成员,只有函数可以用)
console.log("我可以改变世界");
}
Phone.prototype.size = '5.5inch'; //属于实例对象
let nokia = new Phone(); //实例对象和函数对象不相通
console.log(nokia.name); //undefined
// nokia.change();
console.log(nokia.size); //5.5inch
class Phone2 {
//静态属性
static name = '手机'; //属于类的对象(静态成员,只有类可以用),不属于实例对象
static change() {
console.log("我可以改变世界");
}
}
let nokia2 = new Phone2();
console.log(nokia2.name); //undefined
console.log(Phone2.name); //手机
es5构造函数的继承
//手机(父类)
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 chuiz = new SmartPhone('锤子', 2499, '黑色', '5.5inch');
console.log(chuiz);
console.log(chuiz.price);
chuiz.call();
chuiz.photo();
chuiz.playGame();
class类的继承与子类对父类方法的重写
//父类
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); // 相当于ed5的Phone.call(this, brand, price)
this.color = color;
this.size = size;
}
photo() {
console.log("拍照");
}
playGame() {
console.log("玩游戏");
}
//子类对父类方法的重写
call() {
console.log("我还可以视频通话!!");
}
}
const xiaom = new SmartPhone('小米', 799, '黑色', '4.7inch');
console.log(xiaom);
console.log(xiaom.size);
xiaom.call(); //打印“我还可以视频通话!!”,而不是“我可以打电话!”
xiaom.photo();
xiaom.playGame();
class类中getter和setter设置
// get和set
class Phone {
//对对象的动态属性进行封装
get price() {
console.log("价格属性被读取了");
return 'i love you';
}
//可对设置的值进行判断
set price(newVal) {
console.log('价格属性被修改了');
}
}
//实例化对象
let s = new Phone();
console.log(s.price);
console.log("\n");
s.price = 'free';
十六、数值扩展
1、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))
2、二进制和八进制
let b = 0b1010; //二进制
console.log(b);
let o = 0o777; //八进制
console.log(o);
let d = 100; //十进制
console.log(d);
let x = 0xff; //十六进制
console.log(x);
3、 Number.isFinite 检测一个数值是否为有限数
console.log(Number.isFinite(100));
console.log(Number.isFinite(100 / 0));
console.log(Number.isFinite(Infinity)); //无穷
4、 Number.isNaN检测一个数值是否为NaN
console.log(Number.isNaN(123));
5、Number.parseInt、Number . parseFloat字符串转整数
console.log(Number.parseInt('5211314love'));
console.log(Number.parseFloat('3.1415926神奇'));
6、 Number.isInteger判断一个 数是否为整数
console.log(Number.isInteger(5));
console.log(Number.isInteger(2.5));
7、Math.trunc 将数字的小数 部分抹掉
console.log(Math.trunc(3.5));
8、 Math.sign 判断一个数到底为正数、负数还是零
console.log(Math.sign(100));
console.log(Math.sign(0));
console.log(Math.sign(-20000));
十七、对象方法拓展
1、Object.is 判断两个值是否完全相等
console.log(Object.is(120, 120)); //ture
console.log(Object.is(120, 121)); //flase
console.log(Object.is(NaN, NaN)); //ture
console.log(NaN === NaN); //flase,所以Object.is和===不一样
2、Object.assign 对象的合并
//用于配置合并
const config1 = {
host: 'localhost ',
port: 3306,
name: 'root',
pass: 'root',
test: 'test'
};
const config2 = {
host: 'http://atguigu.com',
port: 33060,
name: 'baidu.com',
pass: 'iloveyou',
//test2: 'test2' //有则覆盖,无则不覆盖
}
console.log(Object.assign(config1, config2)); //2覆盖1
3、Object. setPrototype0f(设置原型对象)、Object.getPrototypeof(获取原型对象)
const school = {
name: '尚硅谷'
}
const cities = {
xiaoqu: ['北京', ' 上海', '深圳']
}
Object.setPrototypeOf(school, cities); //将cities设置为school的原型对象,但最好不用此方法设置
console.log(school);
console.log(Object.getPrototypeOf(school)); //获取school的原型对象
十八、模块化
模块化是指将一个大的程序文件,拆分成许多小的文件(模块),然后将小文件组合起来。
优势与规范化产品
1、模块化的优势有以下几点:
1)防止命名冲突
2)代码复用
3)高维护性
2、ES6之前的模块化规范有:
1)CommonJS => NodeJS、Browserify
2)AMD => requireJS
3)CMD => seaJS
浏览器使用ES6模块化引入模块
模块功能主要由两个命令构成:export 和import。
1、export命令用于规定模块的对外接口
2、import命令用于输入其他模块提供的功能
//html文件里面的script标签
<script type="module">
//引入m1.js 模块内容
//通用导入方式
import * as m1 from "./m1.js";
console.log(m1);
</script>
m1.js
//分别暴露
export let school = '尚硅谷';
export function teach() {
console.log("我们可以教给你开发技能");
}
ES6模块暴露数据语法汇总
m2.js
//分别暴露
//统一暴露
let school = '尚硅谷';
function find() {
console.log("我们可以帮助你找工作");
}
export{school,find};
m3.js
//默认暴露
export default {
school: 'ATGUIGU',
change: function () { //m3.default.change();
console.log("我们可以改变你!!");
}
}
ES6模块引入模块数据语法汇总
//1.通用导入方式
//2. 解构赋值形式
//import {school, teach} from"./m1.js";
//import {school as guigu, find} from "./m2.js";
//import {default as m3} from "./m3.js";
//3. 简便形式,针对默认暴露
import m3 from "./m3.js";
console.log(m3);
浏览器使用ES6模块化方式二
//html文件里面的script标签
<script src="./app.js" type="module"></script>
app.js
//入口文件
//模块引入
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);
babel对ES6模块化代码转换
1、终端安装工具babel-cli、babel-preset-env、browserify(相当于webpack)(npm i babel-cli babel-preset-env browserify -D)
2、代码转化,app.js、m1.js、m2.js、m3.js在src/js文件夹下(npx babel src/js -d dist/js --presets=babel-preset-env)
3、打包(npx browserify dist/js/app.js -o dist/bundle.js)
//html文件下的script标签,引入bundle.js文件
<script src="./dist/bundle.js"></script>
每次js文件夹下的js文件改变了就要重新代码转化以及打包!
ES6模块化引入NPM包
1、利用npm在终端安装要导入的包
2、导入npm包,如下方法导入jquery包
//修改背景颜色为粉色
import $ from 'jquery'; // const $ = require("jquery");
$('body').css('background', 'pink');