理财 网站模板 html,优化大师网页版,wordpress整合redis,好的网站具备文章目录1. let和const1.1 let声明变量1.2 const声明常量2. 模板字符串3. 解构赋值3.1 数组的解构赋值3.2 对象的解构赋值4. 函数扩展4.1 参数默认值4.2 剩余参数4.3 箭头函数5. 对象扩展5.1 对象简写5.2 属性名表达式5.3 扩展运算符6. Symbol7. Iterator和Generator7.1 Iterat…
文章目录1. let和const1.1 let声明变量1.2 const声明常量2. 模板字符串3. 解构赋值3.1 数组的解构赋值3.2 对象的解构赋值4. 函数扩展4.1 参数默认值4.2 剩余参数4.3 箭头函数5. 对象扩展5.1 对象简写5.2 属性名表达式5.3 扩展运算符6. Symbol7. Iterator和Generator7.1 Iterator7.2 Generator8. Proxy和Reflect8.1 Proxy8.2 Reflect9. Promise10. Async和Await10.1 Async10.2 Await11. 类11.1 类的定义和使用11.2 类的继承12. 模块12.1 export12.2 import1. let和const
1.1 let声明变量
var 和 let 关键字的区别
关键字是否能重复声明变量是否有块作用域是否有变量提升是否影响顶层对象var√×√√let×√××
1.let 不允许重复声明变量
// var允许重复声明变量
var a 10;
var a 10; // let不允许重复声明变量
let a 10;
let a 10; // Uncaught SyntaxError: Identifier a has already been declared2.let 声明的变量有块作用域
// var声明的变量没有块作用域
if (true) {var a 10;console.log(a); // 10
}console.log(a); // 10
// let声明的变量有块作用域
if (true) {let a 10; console.log(a); // 10
}console.log(a); // Uncaught ReferenceError: a is not defined
3.let 声明的变量没有变量提升
/* 由于有变量提升以下代码会转换成如下
var a;
console.log(a);
a 10; */// var声明的变量有变量提升
console.log(a); // undefined
var a 10;
// let声明的变量没有变量提升
console.log(a); // Uncaught ReferenceError: Cannot access a before initialization
let a 10;4.let 声明的变量不会与顶层对象挂钩 顶层对象在broswer环境中指window对象在node环境中指global对象 // var声明的变量会与顶层对象挂钩
var a 10;
console.log(window.a); // 10// let声明的变量不会与顶层对象挂钩
let a 10;
console.log(window.a); // undefined1.2 const声明常量
const 拥有 let 的全部特性与 let 不同的是const声明的变量是常量一经声明无法修改。
1.const声明的变量无法修改
// let声明的变量可以修改
let a 10;
a 20;// const声明的变量无法修改
const a 10;
a 20; // Uncaught TypeError: Assignment to constant variable2.const声明的变量必须声明时就初始化
const a; // Uncaught SyntaxError: Missing initializer in const declaration3.当变量是对象时虽然不能修改对象名但是可以修改对象的内部属性 解释因为对象是引用类型对象名存的是一个地址而改变对象的内部属性并没有改变地址本身。 const obj {name: Bill,age: 18
};obj.age 28;
console.log(obj); // {name: Bill, age: 28} let 和 const 的使用场景默认情况下使用 const在知道变量值需要修改时使用 let 2. 模板字符串
模板字符串其实就是占位符这样就可以简化字符串拼接。
1.用于字符串拼接
const name Bill;
const age 18;
const person my name is ${name}, my age is ${age};
console.log(person); // my name is Bill, my age is 182.支持使用表达式
// 1.支持四则运算
const a 10;
const b 20;
const result result is ${a b};
console.log(result); // result is 30// 2.支持三元表达式
const isEqual 结果是${a 10 ? 相等 : 不相等};
console.log(isEqual); // 结果是相等
3. 解构赋值
解构赋值用于赋值运算可以简化赋值。
3.1 数组的解构赋值
1.简化数组的赋值
const arr [1, 2, 3];const [a, b, c] arr; // 等价于 a1, b2, c3
console.log(a, b, c); // 1 2 3const [d, , e] arr; // 等价于 d1, e3
console.log(d, e); // 1 3
2.嵌套情况下的数组赋值
const arr [1, [2, 3, 4], 5];
const [a, [b, c], d] arr; // 等价于 a1, b2, c3, d5
console.log(a, b, c, d); // 1 2 3 53.2 对象的解构赋值
1.简化对象的赋值
const obj {name: Bill,age: 18
};const { name, age } obj; // 等价于 nameobj.name, ageobj.age
console.log(name, age); // Bill 18
2.声明的变量名需要与对象的属性名一致时否则在对象的属性名中匹配不到得到的值是undefined 对象的解构赋值变量赋值时会与属性名匹配不会按照声明变量的前后顺序匹配 const obj {name: Bill,age: 18,addr: Shanghai
};const { name, addr, a } obj; // 等价于 nameobj.name, addrobj.addr
console.log(name, addr, a); // Bill Shanghai undefined
3.嵌套情况下的对象赋值
const obj {name: Bill,age: 18,other: {addr: Shanghai,email: xxx163.com}
};const {name,age,other: { email }
} obj; // 等价于 nameobj.name, ageobj.age, email obj.other.email
console.log(name, age, email); // Bill 18 xxx163.com
4. 函数扩展
4.1 参数默认值
参数默认值不传参时函数使用默认的参数值传参后会覆盖默认值。
function fn(a, b 10) {console.log(a, b);
}fn(10); // 10 10
fn(10, 20); // 10 20
4.2 剩余参数
剩余参数也称可变参数剩余参数语法允许将一个不定数量的参数表示为一个数组。
function fn(a, b, ...args) {console.log(args);
}fn(10, 20, 30, 40, 50); // [30, 40, 50]
4.3 箭头函数
箭头函数箭头函数可用于简化匿名函数的定义使书写更为简洁。
1.无参数、无返回值的箭头函数
// 匿名函数写法无参数、无返回值
const fn function () {console.log(100);
};fn();
// 箭头函数写法无参数、无返回值
const fn () {console.log(100);
};fn();
2.有返回值的箭头函数
// 匿名函数写法有返回值
const fn function () {console.log(100);return 100;
};
// 箭头函数写法有返回值// 1.函数内部只有 return无其它内容
const fn1 () 100;
const fn2 () ({ name: Bill, age: 18 }); // 返回的是对象时要使用小括号包裹起来// 2.函数内部除了有 return还有其它内容
const fn3 () {console.log(100);return 100;
};
3.带参数的箭头函数
// 匿名函数写法带参数
const fn function (a, b) {console.log(a b);return a b;
};
// 箭头函数写法带参数// 1.只有一个参数时可以省略括号
const fn1 a {console.log(a);
};const fn2 a a;// 2.带多个参数时不可省略括号
const fn3 (a, b) a b;const fn4 (a, b) {console.log(a b);return a b;
};
4.箭头函数没有this
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleDocument/title/headbodybutton value按钮点击按钮/buttonscriptconst btn document.querySelector(button);btn.addEventListener(click, function () {console.log(this.value); // 按钮// 使用匿名函数const fn function () {console.log(this.value); // undefined};fn();});/script/body
/html
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleDocument/title/headbodybutton value按钮点击按钮/buttonscriptconst btn document.querySelector(button);btn.addEventListener(click, function () {console.log(this.value); // 按钮// 使用箭头函数const fn () {console.log(this.value); // 按钮};fn();});/script/body
/html 注监听事件的函数要写成匿名函数不要写成箭头函数否则this指向的就是window 5. 对象扩展
5.1 对象简写
对象简写简写对象的属性和方法
当属性名和属性值相同时可以简写为只写一个属性名可以省略方法中的:function
// es5写法
const name Bill;
const obj {name: name,test: function () {}
};// es6写法
const name Bill;
const obj {name,test() {}
};5.2 属性名表达式
属性名表达式对象的属性名可以使用变量和表达式的方式命名
const name a;
const obj {[name]: Bill,[name bc]: Jackson
};console.log(obj); // {a: Bill, abc: Jackson} 注对象简写和属性名表达式不能同时使用 5.3 扩展运算符
扩展运算符用于取出参数对象中的所有可遍历属性拷贝到当前对象之中
对象的扩展运算符用于拷贝对象属性数组的扩展运算符将数组分割为参数序列、拷贝数组
1.拷贝对象
const obj1 { name: Bill, age: 18 };
const obj2 { name: Jackson };
const obj3 { addr: Shanghai };
const obj { ...obj1, ...obj2, ...obj3 };
console.log(obj); // {name: Jackson, age: 18, addr: Shanghai} 注当对象有同名属性时后合并的对象会覆盖之前的对象的属性 2.拷贝数组
const arr1 [10, 20, 30];
const arr2 [10, 40, ...arr1];
console.log(arr2); // [10, 40, 10, 20, 30]3.将数组分割为参数序列
const arr [10, 30, 50];
console.log(Math.max(10, 20, ...arr)); // 50剩余参数的...和扩展运算符...的区别 剩余运算符把多个参数合并为一个数组扩展运算符把一个数组分割为多个参数 6. Symbol
Symbol是一种基本数据类型表示独一无二的值。
1.创建Symbol变量
// 1.创建不带描述的Symbol变量
const s1 Symbol();
console.log(s1); // Symbol()// 2.带描述的Symbol变量
const s2 Symbol(Symbol2); // 传入的字符串为Symbol变量的描述
console.log(s2); // Symbol(Symbol2) 注Symbol是基本数据类型不是对象类型所以不能使用new创建Symbol变量 2.Symbol的值是唯一的
const s1 Symbol();
const s2 Symbol();
console.log(s1 s2); // falseconst s3 Symbol(Symbol);
const s4 Symbol(Symbol);
console.log(s3 s4); // false
3.Symbol变量不能进行运算
const s Symbol();
console.log(s hello); // Uncaught TypeError: Cannot convert a Symbol value to a string7. Iterator和Generator
7.1 Iterator
迭代从一个数据集合中按照一定的顺序不断取出数据的过程。
迭代器Iterator
为各种数据结构提供了一个可以统一、简便的访问接口使得数据结构的成员能够按照某种顺序排列Symbol.iterator 为对象定义了迭代器可以被 for...of 循环使用
1.当对象具有Symbol.iterator接口时就可以使用for...of迭代对象 1.原生具备 Symbol.iterator 接口的数据结构有Array、Set、Map、String、arguments、NodeList 2.for...of 是语法糖本质上还是用的迭代器方法 const arr [1, 3, 5, 7, 9];
console.log(arr);for (const i of arr) {console.log(i);
}
点击Array对象展开[[Prototype]]: Array(0)以后发现具有Symbol(Symbol.iterator) : ƒ values()因此可以使用for...of遍历数组。 2.通过 Symbol.iterator 来创建迭代器
const arr [1, 3, 5, 7, 9];
const iter arr[Symbol.iterator](); // 创建迭代器console.log(iter.next()); // {value: 1, done: false}
console.log(iter.next()); // {value: 3, done: false}
console.log(iter.next()); // {value: 5, done: false}
console.log(iter.next()); // {value: 7, done: false}
console.log(iter.next()); // {value: 9, done: false}
console.log(iter.next()); // {value: undefined, done: true} next方法返回一个对象该对象包含两个属性 value下一个数据的值done已经迭代到序列中的最后一个值为 true否则为false Iterator 的遍历过程 创建一个指针对象指向当前数据结构的起始位置。也就是说迭代器对象本质就是一个指针对象。第一次调用指针对象的next方法可以将指针指向数据结构的第一个成员。第二次调用指针对象的next方法可以将指针指向数据结构的第二个成员。不断地调用指针对象的next方法直到它指向数据结构的结束位置。 7.2 Generator
Generator生成器函数
是一种异步编程解决方案是一个状态机封装了多个内部状态执行Generator函数会返回一个遍历器对象可以遍历每一个状态
1.next方法执行下一个状态一个yield代表一个状态碰到yield停下
function* gen() {console.log(10);yield;console.log(20);yield;console.log(30);
}const g gen();
g.next(); // 10
g.next(); // 20
g.next(); // 30
2.yield可以跟返回的结果
function* gen() {console.log(10);yield aaa;console.log(20);yield bbb;console.log(30);return ccc;
}const g gen();
const res1 g.next(); // 10
console.log(res1); // {value: aaa, done: false}const res2 g.next(); // 20
console.log(res2); // {value: bbb, done: false}const res3 g.next(); // 30
console.log(res3); // {value: ccc, done: true}
3.可以使用for...of进行遍历每个状态
function* gen() {console.log(10);yield aaa;console.log(20);yield bbb;console.log(30);return ccc;
}const g gen();
for (const i of g) {console.log(i);
}
4.通过next方法可以传入参数到生成器函数 注第一个next方法传入的参数不会生效 function* gen() {const res1 yield;console.log(res1);const res2 yield;console.log(res2);
}const g gen();
g.next(10); // 无输出
g.next(20); // 20
g.next(30); // 30 分析 1.执行第一个next时碰到第一个yield停下来了还没有执行赋值操作 2.执行第二个next时将传入的参数20赋值给了res1接着碰到第二个yield停下 3.执行第三个next时将传入的参数30赋值给了res2接着走到函数结束 8. Proxy和Reflect
8.1 Proxy
代理Proxy 作用是在对象和对象的属性值之间设置一个代理获取该对象的值、设置该对象的值以及实例化等操作都会被拦截住。经过这一层我们可以统一处理我们可以认为它就是代理器。
拦截获取和修改数据时会进行拦截用于脏数据检查。
1.es5 拦截方法Object.defineProperty()
Object.defineProperty(obj, prop, descriptor)
obj要被修改拦截的对象prop要被修改拦截的属性descriptor当访问属性时会调用get函数当属性值被修改时会调用set函数。 缺点 1.一次只能拦截一个属性 2.只能拦截对象 !DOCTYPE html
html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleDocument/title/headbodypHello World/pscriptconst p document.querySelector(p);const obj {};// 为obj对象的data属性设置拦截Object.defineProperty(obj, data, {get() {return p.innerHTML;},set(value) {p.innerHTML value;}});/script/body
/html
分别输入obj.data、obj.dataaaa、obj.data触发 get、set 和 get 运行结果如下 2.es6 拦截方法Proxy(target, handler)
Proxy(target, handler)
target要被修改拦截的对象handler执行各种操作时代理的行为 优点 1.一次可以拦截多个属性 2.可以拦截任何类型的对象包括数组、函数等 !DOCTYPE html
html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleDocument/title/headbodypHello World/pscriptconst p document.querySelector(p);const obj {};// 为obj对象创建一个代理const proxy new Proxy(obj, {get(target, key) {return target[key];},set(target, key, value) {// 访问data属性时修改dom元素if (key data) {p.innerHTML value;}target[key] value;}});/script/body
/html
操作obj对象运行结果如下 操作proxy对象运行结果如下 8.2 Reflect
反射Reflect用于获取目标对象的行为它与Object类似但是更易读为操作对象提供了一种更优雅的方式。它的方法与proxy handlers 的方法相同。
1.代替Object的某些方法
const obj {};
Reflect.defineProperty(obj, name, {value: Bill
});2.修改某些Object方法的返回结果
// Object.defineProperty返回值是对象只能使用try...catch做异常处理
try {Object.defineProperty(target, property, attributes);// success
} catch (e) {// fail
}// Reflect.defineProperty方法的返回值为Boolean值可以使用if...else做异常处理
if (Reflect.defineProperty(target, property, attributes)) {// success
} else {// fail
}
3.命令式写法改为使用函数写法
// 命令式写法
const obj { name: Bill };
console.log(name in obj); // true
delete obj.name;// Reflect函数写法
const obj { name: Bill };
console.log(Reflect.has(obj, name)); // true
Reflect.deleteProperty(obj, name);4.配合Proxy使用反射到代理对象原来的默认行为上
const s new Set();
const proxy new Proxy(s, {get(target, key) {const value Reflect.get(target, key); // 等价于const value target[key]// 判断如果是方法修正this指向if (value instanceof Function) {return value.bind(target);}return value;},set(target, key, value) {Reflect.set(target, key, value); // 等价于target[key] value}
});注还可以和扩展运算符配合使用将以上的 get 和 set 方法改为 Reflect.get(...arguments) 和 Reflect.set(...arguments) 在控制台输入内容运行结果如下 9. Promise
Promise是异步编程的一种解决方案比传统的解决方案回调函数更合理和更强大。
Promise的作用 解决异步回调地狱的问题。
回调地狱当一个回调函数嵌套一个回调函数的时候就会出现一个嵌套结构当嵌套多了就会出现回调地狱的情况。 例如发送三个ajax请求
第一个正常发送第二个请求需要第一个请求的结果中某一个值作为参数第三个请求需要第二个请求的结果中某一个值作为参数
Promise的状态
待定pending初始状态既没有被兑现也没有被拒绝。已兑现fulfilled意味着操作成功完成。已拒绝rejected意味着操作失败。 这三种状态的变化途径只有两种从待定到已兑现、从待定到已拒绝。一旦状态发生变化就凝固了不会再有新的状态变化这是Promise承诺这个名字的由来一旦承诺生效就不能再改变了。 Promise构造器语法
new Promise(executor)1.Promise的基础示例
const promise new Promise((resolve, reject) {setTimeout(() {resolve(success);}, 1000);
});promise.then(res {console.log(res); // success
}); 当执行了resolve方法则会执行第一个回调函数then方法 2.异步操作成功执行resolve方法然后回调then方法异步操作失败执行reject方法然后回调catch方法 1.resolve方法传入的参数作为then方法的入参 2.reject方法传入的参数,作为catch方法的入参 const promise new Promise((resolve, reject) {setTimeout(() {resolve(success);reject(failed);}, 1000);
});promise.then(res {console.log(res); // success}).catch(err {console.log(err); // failed});
运行结果 分析先调用了 resolve 方法导致状态从待定到已兑现然后状态发生凝固后续reject方法不再执行。 3.链式调用解决回调地狱问题
链式调用图解
const promise new Promise((resolve, reject) {setTimeout(() {resolve(success);reject(failed);}, 1000);
});promise.then(res {console.log(first ${res}); // first successreturn res;}).then(res {console.log(second ${res}); // second success}).catch(err {console.log(err);}); 分析 先调用了resolve然后执行第一个then方法promise对象的状态从待定到已兑现。第一个then方法执行完成后又返回了一个新的promise对象同时返回值也会作为第二个then方法的入参新的promise对象继续执行了第二个then方法然后新promise对象的状态也从待定到已兑现。 4.Promise.all()等待所有传入的 promise 都变为完成状态后再执行回调
const p1 new Promise((resolve, reject) {setTimeout(() {resolve(1000);}, 1000);
});const p2 new Promise((resolve, reject) {setTimeout(() {resolve(2000);}, 2000);
});const p3 new Promise((resolve, reject) {setTimeout(() {resolve(3000);}, 3000);
});// p1, p2, p3都执行了resolve后调用then
Promise.all([p1, p2, p3]).then(res {console.log(res); // [1000, 2000, 3000]}).catch(err {console.log(err);});
5.Promise.race()所有传入的 promise 中先变为完成状态的 promise 执行回调
// p1等待一秒最先执行完毕
const p1 new Promise((resolve, reject) {setTimeout(() {resolve(1000);}, 1000);
});const p2 new Promise((resolve, reject) {setTimeout(() {resolve(2000);}, 2000);
});const p3 new Promise((resolve, reject) {setTimeout(() {resolve(3000);}, 3000);
});// p1, p2, p3第一个执行resolve的调用then
Promise.race([p1, p2, p3]).then(res {console.log(res); // 1000}).catch(err {console.log(err);});
10. Async和Await
Async Await是Promise Generator的语法糖它可以使得Promise的书写更为简单可以使用同步的方式来执行异步操作。
async 和 await
async 使函数返回 Promiseawait 使函数等待 Promise
10.1 Async
1.函数前加上关键字 async使函数返回 promise 对象
async function fn() {return Hello World; // 等价于return Promise.resolve(Hello World);
}const res fn();
console.log(res); // Promise {fulfilled: Hello World}
2.return的值为promise对象时异步操作成功执行resolve方法然后回调then方法异步操作失败执行reject方法然后回调catch方法 1.resolve方法传入的参数作为then方法的入参 2.reject方法传入的参数,作为catch方法的入参 async function fn() {return new Promise((resolve, reject) {resolve(success);// reject(failed);});
}const promise fn();
promise.then(res {console.log(res); // success}).catch(err {console.log(err); // failed});
10.2 Await
await 使函数等待 promise 注await 关键字只能在 async 函数中使用 1.不使用await不会等待promise
function fn() {return new Promise((resolve, reject) {setTimeout(() {console.log(1);resolve(2);}, 2000);});
}// 不使用await
async function test() {const res fn();console.log(res); console.log(3);
}test();
运行结果 分析 1.未使用await因为setTimeout是异步的setTimeout的回调函数还未执行那么resolve也还没执行到就已经把promise对象返回了因此打印出来的res是一个还在pending状态的promise对象。 2.因为setTimeout是异步的没有阻塞后续代码的执行所以先打印了3。 3.两秒钟结束后执行setTimeout的回调函数打印了1再执行了resolve方法。 2.使用await会等待promise返回
function fn() {return new Promise((resolve, reject) {setTimeout(() {console.log(1);resolve(2);}, 2000);});
}// 使用await
async function test() {const res await fn();console.log(res);console.log(3);
}test();
运行结果 分析 1.使用了await会一直等待promise返回直到resolve方法执行后再执行后续代码因此先执行了setTimeout的回调函数因为resolve方法在该回调函数中打印了1 2.执行了resolve将resolve的结果返回给res打印了2 3.再执行后续代码最后打印了3 3.使用await只会等待promise而不会等待其他的异步 以下代码使用了await并不会等待setTimeout先执行回调函数因为resolve不在setTimeout的回调函数中 function fn() {return new Promise((resolve, reject) {setTimeout(() {console.log(1);}, 2000);resolve(2); // 不把resolve放在setTimeout回调函数内});
}// 使用await
async function test() {const res await fn();console.log(res);console.log(3);
}test();
运行结果 分析 1.调用fn时先执行到了setTimeout由于它是异步的其回调函数没有先执行 2.然后执行了resolve方法将结果返回给了res打印了2 3.再执行后续代码最后打印了3 4.两秒钟结束后执行setTimeout的回调函数打印了1 11. 类
类类不是对象而是对象的模板
11.1 类的定义和使用
类的语法
class ClassName {constructor() { ... }method_1() { ... }method_2() { ... }method_3() { ... }
}1.类的定义和使用
使用关键字 class 创建一个类通过构造方法 constructor() 给属性赋值创建类方法的语法与对象方法相同 构造方法 1.创建对象时会自动调用构造方法 2.构造方法用于初始化对象属性 3.如果没有定义构造方法JS 会添加一个空的构造方法 // 类的定义
class Person {// 构造方法constructor(name, age) {this.name name;this.age age;}// 类方法say() {console.log(this.name, this.age);}
}const person new Person(Bill, 18); // 使用类来创建对象
console.log(person.name); // Bill
console.log(person.age); // 18
person.say(); // Bill 18
2.类可以使用 getter 和 setter
在类中添加 getter 和 setter请使用 get 和 set 关键字getter/setter 的方法名不能与属性名相同建议使用下划线字符将 getter/setter 与实际属性分开
class Person {constructor(name, age) {this._name name;this._age age;}// getterget getName() {return this._name;}// setterset setName(x) {this._name x;}
}const person new Person(Bill, 18);
console.log(person.getName); // Bill
person.setName Jackson;
console.log(person.getName); // Jackson
11.2 类的继承
类继承使用类继承创建的类继承了另一个类的所有方法
1.使用关键字 extends来继承类 super()方法引用父类 1.在constructor方法中调用 super方法则调用了父类的 constructor 方法获得了父级的属性和方法的访问权限 2.在类方法中调用 super方法则调用了父类的类方法 // 创建一个Person类
class Person {constructor(name, age) {this.name name;this.age age;}say() {console.log(this.name, this.age);}
}// 创建一个Student类继承了Person类
class Student extends Person {constructor(name, age, score) {super(name, age); // 调用父类的constructor方法this.score score;}
}const student new Student(Bill, 18, 90);
student.say(); // 调用父类的方法
2.重写方法
当子类的方法名与父类的方法名一致时子类的方法会覆盖父类的方法子类的对象调用该方法时调用的是子类的方法而不会调用父类的方法
// 创建一个Person类
class Person {constructor(name, age) {this.name name;this.age age;}say() {console.log(this.name, this.age);}
}// 创建一个Student类继承了Person类
class Student extends Person {constructor(name, age, score) {super(name, age);this.score score;}// 重写父类的方法say() {console.log(${this.name}: age is ${this.age}, score is ${this.score});}
}const student new Student(Bill, 18, 90);
student.say(); // Bill: age is 18, score is 90
12. 模块
模块一个模块module就是一个js文件可以通过export和import命令来实现两个模块之间的交互也就是一个js文件可以引用另一个js文件的内容。
export表示当前模块的变量和函数可以被外部访问import导入了其它模块的变量和函数到当前模块 注以前使用script srcxxx.js/script的方式来引用js文件会带来一些问题如引用的两个js文件有函数名和变量名相同而通过模块化可以解决这些问题。 12.1 export
1.定义变量和函数的同时就导出
export const name Bill;
export const age 18;export function fn() {console.log(Hello World);
}
2.定义变量和函数后再导出
const name Bill;
const age 18;function fn() {console.log(Hello World);
}export { name, age, fn };
3.使用as关键字可以给导出的变量和函数取别名 注导出的时候取了别名的话导入时也需要使用导出时的别名 const name Bill;
const age 18;function fn() {console.log(Hello World);
}export { name as gName, age as gAge, fn as gFn };
4.export default默认导出
一个模块中只能有一个export default默认导出时可以不需要指定名字导入时不需要使用{}并且可以自己来指定名字
// 默认导出变量
const name Bill;
export default { name };// 默认导出函数
export default function fn() {console.log(Hello World);
}12.2 import
准备一个test.js文件用于导出变量和函数内容如下
const name Bill;
const age 18;function fn() {console.log(Hello World);
}export { name, age, fn };
1.在js文件中导入另一个js文件
在test.js同级目录下新建一个demo.js内容如下
import { name, age, fn } from ./test.js;console.log(name, age); // Bill 18
fn(); // Hello World
2.在html文件中导入另一个js文件 注html文件导入js文件时要设置script标签的属性typemodule否则会报错 在test.js同级目录下新建一个demo.html内容如下
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleDocument/title/headbodyscript typemodule// 导入test.jsimport { name, age, fn } from ./test.js;console.log(name, age); // Bill 18fn(); // Hello World/script/body
/html
3.使用as关键字可以给导入的变量和函数取别名
import { name as gName, age as gAge, fn as gFn } from ./test.js;console.log(gName, gAge);
gFn();
4.使用*和 as可以把所有导入变量和函数指定到一个模块对象上 注使用这种方式导入时要去掉{} import * as obj from ./test.js;console.log(obj.name, obj.age);
obj.fn();