let const
1. var 出了块级作用域有效, let 出了块级作用域无效
2. var 具有变量提升的能力, let不具备
3. var 可以重复声明一个变量, let不可以
4. let 更适合局部变量
5. 在一个区块内部,只要使用了let声明,这个区域就形成了封闭的作用域
6. 如果在let声明前使用变量,这段区域被称为'临时锁区(或暂时性锁区)',临时死区,使用typeof也会报错
7. 在循环中,var与let的区别尤为明显,var 全局有效,导致后续使用i会引起干扰,而let不会
8. 如果在循环体内设置函数方法,体外输出var会得不到预期数值
1. const声明的作用是:创建一个只读的常量,一旦声明不可改变
2. 与let 声明一样,const声明的常量无法提升, 也存在临时死区
3. 和elt 声明不同的是,const 声明常量后必须立刻赋值,否则会报错
const PI = 3.14;
console.log(PI); // 常量约定俗成大写
块级作用域
1. ES6之前只有全局作用域与函数作用域,并没有块级作用域
2. 循环体和条件体就是块级作用域,{} 中
3. 如果在块级作用域里不使用 let ,就会造成全局变量污染的问题
4. {{{...}}}块级作用域支持多层嵌套,每一层均是封闭的,只作用于此
5. 在ES6之前,采用自我执行匿名函数的方式来防止变量污染
(function (){
var vaule = 10;
}());
console.log(value) //报错
{
let value = 10;
}
6. 块级作用域内的函数声明,在全局作用域内依旧可以访问
7. 解决方式是:使用函数表达式的方式创建
{
let fun = function(){};
}
数组与对象的解构
1. 为何要解构操作? JSON格式的普及,导致大量数据提取工作
2. 数组解构赋值:1.分行解构,2.单行解构
let info = ['Mr.z', 100, '男'];
let [name, age, gender] = info;
console.log(name)
console.log(age)
console.log(gender)
let [name, age, gender] = ['Mr.z', 100, '男'];
3. 无论是单行还是分行解构,都必须一一匹配
//数组层次也需要匹配
let [name, [age, gender]] = ['Mr.z', [100, '男']];
//用逗号作为占位符不赋值
let [, , gender] = ['Mr.z', 100, '男'];
4. 在变量解构时,可以在数组的元素中设置一个默认值
let [name, age, gender='男'] = ['Mr.z', 100];
5. 还有一种 ...var 的语法,可以将没有赋值的内容都赋值给这个变量
let [name, ...other] = ['Mr.z', 100, '男'];
1. 对象解构,与数组解构相似
let obj = {
name: 'Mr.z',
age: 100
};
let {name, age} = obj
2. 对象解构也可以设置一个默认值
let obj = {
name: 'Mr.z'
};
let {name, age = 100} = obj;
3. 如果不想要对象属性名作为解构变量,可以通过键值对的方式改变属性名
let obj = {
name: 'Mr.z'
};
let {name:myname} = obj
4. 嵌套对象--解构可以通过键值对方式
let obj = {
name: 'Mr.z',
info: {
age: 100,
gender: '男'
}
};
let {name, info:{age, gender}} = obj
5. 对象的解构也支持单行简写
let {name, age} = {'Mr.z', 100}
1. 其它解构--常用解构
普通变量的 值交换
let key = 1;
let value = 'Mr.z';
// 解构操作,变量互换
[key, value] = [value, key];
2. 如果函数的返回值是一个数组或对象, 直接将函数进行赋值解构
function fun(){
return ['Mr.z', 100, '男']
}
let [name, age, gender] = fun();
3. 当函数进行参数传递时,可以进行数组和对象字面量方式的传参
function fun([name, age, gender]){
console.log(name)
}
fun(['Mr.z', 100, '男']);
4. 字符串的解构
let [x, y, z] = 'abc';
let {length:len} = 'abc';
函数的传参
1. ES6之前,函数是无法给参数设置默认值的, ES6支持了这一特性
function fun(number = 100,age = 111){
console.log(number); // 123
console.log(age); // [ 111, 222 ]
}
fun(123,[111,222]);
2. 如果只想传递第二往后的参数值,可以使用 undefined 占位
function fun(number = 100,age = 111){
console.log(number);
console.log(age);
}
fun(undefined, 222);
3. 支持参数使二使用参数一的值作为默认值,反之不可以
function fn(x, y=x){}
4. 解构变量有不确定元素,那么函数的传参也可以有不定参数
function fn(x, ...y){}
5. name属性 用于获取函数名
function fn(){}
let fn2 = function(){};
let obj = {
fn3: function(){}
};
console.log(fn.name)
console.log(fn2.name)
console.log(obj.fn3.name)
console.log((new Function()).name) // anonymous 匿名函数
箭头函数和this
1. 箭头函数
let fn = name => name;
console.log(fn('Mr.z'))
function fn(name){
return name
}
2. 箭头函数也可以传递两个或以上的参数,并实现运算后返回
let fn = (x, y) => x+y;
3. 定义的函数不需要传参的话,可以直接用()
let fn = () => '123';
4. 如果函数体需要更复杂的操作,箭头函数右侧使用传统函数体
let fn = (x, y) =>{
return x + y;
}
5. 自执行函数也可以用箭头函数创建
((age) => {
console.log(age)
})('22');
(function(age){
console.log(age)
})('22');
1. 绑定this ES中的典型问题,this指向问题,当对象中包含了类似setTimeout函数内部,this的指向就会发生问题
let obj = {
name: 'Mr.z',
age: 22,
fn: function(){
setTimeout(function(){
console.log(this.name + ',' + this.age); // 此时this指向window
}, 500)
}
}
obj.fn(); // 输出 undefined,undefined
解决方式: 1.将this在setTimeout外部进行赋值保存 2.箭头函数,箭头函数中的this是最外层的函数绑定,不受内部影响
let obj = {
name: 'Mr.z',
age: 22,
fn: function(){
_this = this; // 将this在setTimeout外部进行赋值保存
setTimeout(function(){
console.log(_this.name + ',' + _this.age);
}, 500)
}
};
obj.fn();
let obj = {
name: 'Mr.z',
age: 22,
fn: function(){
_this = this;
setTimeout(() => console.log(_this.name + ',' + _this.age), 500) //使用箭头函数
}
};
obj.fn();
箭头函数扩展与尾调用
1. 箭头函数也支持一些内置函数的使用,比如 sort排序
let arr = [3, 2, 1].sort((a, b) => a-b);
console.log(arr)
2. 箭头函数不支持arguments绑定,请直接使用...other模式
let fn = (...other) => {
return other[0] + other[1];
}
console.log(fn(1,2))
3. 箭头函数和普通函数一样,可以用typeof 和 instanceof 验证
4. 尾调用:即在一个函数的最后可执行的一步调用了其他函数
尾调优化:原因: 每次尾调用都会创建栈帧,如果尾调次数过多,则可能会出现程序问题
必须满足下面条件,才可执行严格模式下的优化
1. 尾调用必须 return 返回
2. 尾调用 return 返回不得含其他操作
'use strict'
function fn (x) {
if (x<=1) {
return 1;
}
return fn(x - 1);
}
console.log(fn(10))
字符串的扩展与改进
新增方法
1. 处理超过两个字符(四字节)的异体字, ES6新增了 codePointAt() 方法
2. 对于超过两个字符的,可以通过ES6新增的 String.fromCodePoint()
console.log(String.fromCodePoint(134071));
3. ES6提供的 normalize() 方法用于有音标的符号组合形成统一
4. ES6提供了三种判断字符串的方法 includes(), startWith(), endsWith(),若找到返回true
console.log('abc'.includes('a')) // true
console.log('abc'.startsWith('a')) // true
console.log('abc'.endsWith('c')) // true
5. repeat() 重复字符串, padStart() 补全字符串头部, endStart() 补全字符串尾部
console.log('x'.repeat(2)) // xx
console.log('x'.padStart(2,'0')) // 0x 前补0,补全后一共两位
console.log('x'.padEnd(2,'0')) // x0 尾补0,补全后一共两位
模板字符串
1. 反引号实现变量解析--可用于字符串拼接
let name = 'Mr.z',
age = 22;
console.log(`名字: ${name}, 年龄: ${age}`)
2. 支持表达式
console.log(`${1+1}`)
3. 支持嵌套
console.log(`${true ? (true ? `${2}` : `${3}`) : 'false' }`)
4. 可用String.raw来得到原生字符串
console.log(String.raw`我\n是`);
正则的扩展改进
1. ES6提供了u修饰符, 对占两个字符特殊字进行正则识别
/?{2}/.test('') // false
/?{2}/u.test('') // true
2. ES6提供了 y 修饰符,它的作用是匹配过一次后继续往下匹配
let text = 'xxx_xx_x_';
let patt = /x+_/y;
console.log(patt.exec(text)) // [ 'xxx_', index: 0, input: 'xxx_xx_x_', groups: undefined ]
console.log(patt.exec(text)) // [ 'xx_', index: 4, input: 'xxx_xx_x_', groups: undefined ]
console.log(patt.exec(text)) // [ 'x_', index: 7, input: 'xxx_xx_x_', groups: undefined ]
console.log(patt.flags) // y
3. 对于 y 修饰符, ES6提供了 stikcy 属性来检测是否存在 y 修饰符
console.log(patt.stikcy)
4. ES6提供了 flags 属性,用于返回正则使用的修饰符名称
5. .表示匹配所有,除了终止符。换行\n,等使用 s 修饰符匹配
let text = 'a\nbc';
let patt = /x.+bc/s;
console.log(patt.test(text));
6. ES6支持修饰符替换,之前会报错
let regex = new RegExp(/xyz/iu, 'g');
console.log(regex.flags) // g
数值扩展
1. ES6明确二进制,八进制, 十六进制分别用 0b, 0o, 0x作为前缀
console.log(Number('0b11'));
console.log(Number('0o11'));
console.log(Number('0x11'));
2. ES6提供了 Number.isFinitel(), Number.isNaN() 判断数值与NaN
3. ES6提供了 Number.parseInt(), Number.parseFloat() 转换整型与浮点型
4. ES6提供了Number.isInteger(), 来判断参数是否是一个整形
5. ES6提供了一个常量,值特别小,用于判断是否得到正确结果 Number.EPSILON
6. ES6新增了一个指数运算符 ** ,并且可以进行赋值运算
console.log(2 ** 2)
7. Math对象新增了一些方法, .trunc(), .sign() 等
console.log(Math.trunc(5.55)); // 去掉小数部分
console.log(Math.sign(10)); // 判断正负,0,NaN 正数返回1,负数返回-1 0返回0, NaN返回NaN
数组的扩展与改进
扩展运算符
1. ES6提供了(...) 三点符号将数组转换为逗号分割
function fn(x, y) {
return x + y;
}
console.log(fn(...[1,2]))
2. 扩展用法,
console.log(Math.max(...[3,2,1])) // 求最大值
console.log([...[1,2],...[3,4]]) // 合并数组
方法的扩展
1. ES6提供了Array.of()方法,主要目的是弥补Array的不足
let arr1 = Array(3);
let arr = Array.of(3);
console.log(arr) // [ 3 ]
console.log(arr1) //[ <3 empty items> ] 3位的空数组
2. ES6提供了 Array.from() 方法,将类似数组的对象或者遍历转换为真正的数组
转换数组的要求比较严格:1. key必须是数值或者字符串 2. length设置长度, 而且key在范围内
var obj = {
0: 'name',
1: 'age',
2: 'gender',
length: 3
}
console.log(Array.from(obj)) // [ 'name', 'age', 'gender' ]
3. ES6提供了 find() 和 findIndex() 方法,用于查找数组中第一个匹配的值
// 参数是一个回调函数,可以使用箭头函数
let arr = [10,20,30,40,50];
console.log(arr.find(value => value === 20)) // 20
console.log(arr.find(value => value > 20)) // 30
console.log(arr.findIndex(value => value === 20)) // 1
4. ES6提供了 fill() 方法,可以填充重写数组中的元素值
let arr = [1,2,3,4,5];
console.log(arr.fill('a')) // [ 'a', 'a', 'a', 'a', 'a' ]
let arr = [1,2,3,4,5];
console.log(arr.fill('a',1,3)) // [ 1, 'a', 'a', 4, 5 ] 从第2位开始到第4位结束 替换为 a [1,3)
5. ES6提供了 copyWithin 方法, 从数组内部赋值, 然后粘贴到指定位置
let arr = [1,2,3,4,5];
// 从0开始复制 值从索引2开始粘贴 参数3设置结束粘贴索引值
console.log(arr.copyWithin(2,0)) // [ 1, 2, 1, 2, 3 ]
对象的简写改进
1. ES6初始属性简写
function fn(name , age){
return {name, age}
}
console.log(fn('Mr.z',10))
2. ES6 对象中方法的简写
let obj = {
// ES6的写法
fn (){
return 'es6'
}
}
console.log(obj.fn())
表达式方案
1. ES6允许对象字面量,使用表达式进行属性名称的拼装操作
let obj = {
['user' + 'name'] : "Mr.z"
}
console.log(obj.username)
2. ES6支持动态属性名称
let myName = 'name';
let obj = {
[myName] : "Mr.z"
}
console.log(obj[myName])
console.log(obj.name)
3. ES6在对象字面量方法上,也支持拼装
let obj = {
['f'+'n'](){
return 'es6'
}
};
console.log(obj.fn())
对象的新增方法
1. ES6中提供了 Object.is() 来处理 ===(恒等)中的一些缺点
console.log(Object.is(NaN, NaN)) // true
console.log(Object.is(+0, -0)) // false
2. ES6提供了 Object.assign() 方法可以合并指定对象至目标对象内部
3. ES6提供了 Object.getPrototypeOf() 和 Object.setPrototypeOf()方法
var obj = {
fn(){
return 'fn'
}
}
let f = {};
Object.setPrototypeOf(f,obj) // 设置f的原型对象为 obj
console.log(f.fn())
console.log(Object.getPrototypeOf(f) === obj) // 检测obj是否是f的原型对象
4. ES6提供了super关键字,用于原型方法中的继承功能
var obj = {
fn1(){
return 'fn1'
}
}
let f = {
fn(){
return super.fn1() + ', extend'
}
};
Object.setPrototypeOf(f,obj) // 设置f的原型对象为 obj
console.log(f.fn()) // fn1, extend
Symbol类型和属性
Symbol类型
1. ES6新增了Symbol基础数据类型,表示独一无二的值,类似ID
let str1 = Symbol(); // 不支持new Symbol
let str2 = Symbol();
console.log(str1 === str2) // false
2. 在Symbol()中的参数,是对变量的描述,程序无法访问,只能日志打印
let str1 = Symbol('字符串');
console.log(str1) // 输出: Symbol(字符串)
Symbol属性
1. 最常用的是作为对象属性
let a = Symbol();
let b = Symbol();
let obj = {
[a]: 'name1',
[b]: 'name2'
}
console.log(obj) // { [Symbol()]: 'name1', [Symbol()]: 'name2' }
console.log(obj[a]) // name1
Set数据集合
1.ES6新提供了Set集合, Set集合是一种无重复元素的列表 使用 new Set() 方法创建 Set 集合
let arr = new Set();
arr.add(1);
arr.add(2);
arr.add(2);
arr.add('2');
console.log(arr) // Set { 1, 2, '2' }
console.log(arr.length) // undefined
console.log(arr.size) // 3
2. 使用 hash() 方法查找是否存在指定元素
console.log(arr.has(2)) // true
3. 使用 delete() 删除指定元素, clear() 清空元素
console.log(arr.delete(2)) // true
console.log(arr) // Set { 1, '2' }
console.log(arr.clear()) // Set {}
4. 使用 ... 将 Set集合转换为数组
console.log([...arr])
5. Set集合还提供了针对对象的Weak Set 集合,添加非对象类型会报错
6. Weak Set集合支持 add(), has(), delete() 方法
7. Weak Set不支持遍历, 内部隐藏(不支持查看), 不支持foreach和size
8. 对于应用场景来说, 存放对象的弱引用, 不用担心对象被回收后引发的问题
Map数据集合
1. ES6提供了Map数据集合, 是一种以键值对存储的有序列表
let map = new Map();
map.set('name', 'Mr.z');
map.set('age', 22);
console.log(map); // Map { 'name' => 'Mr.z', 'age' => 22 }
console.log(map.get('name')) // Mr.z
2. 可以使用 has() 检测, delete() 删除, clear() 清空等对Map集合的操作
3. foreach遍历
map.foreach((value, key, m) => {});
4. Map集合还提供了针对对象的Weak Map 集合,添加非对象类型会报错
5. Weak Map集合支持 set(), has(), delete() 方法
6. Weak Map不支持遍历, 内部隐藏(不支持查看), 不支持foreach和size
7. 对于应用场景来说, 存放对象的弱引用, 不用担心对象被回收后引发的问题
迭代器和生成器
迭代器
1. 迭代器(Tterator),用于给数据结构提供统一的访问遍历的机制
2. 生成器
function *cit(){
yield 1;
yield 2;
yield 3;
}
3. 迭代对象的 .next() 方法, 类似指针,每次执行将下移一行
let it = cit();
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
console.log(it.next()); // { value: 3, done: false }
console.log(it.next()); // { value: undefined, done: true }
4. 生成器配合循环
function *fn(arr){
for(let i=0; i<arr.length; i++){
yield arr[i];
}
}
let it = fn([1,2,3])
console.log(it.next().value) // 1
console.log(it.next().value) // 2
console.log(it.next().value) // 3
默认迭代接口
1. Array, Map, Set 等拥有默认迭代接口
2. 对于Array数组类型, 提供了 keys(), values(), entries()
let arr = [1,2,3,4,5]
console.log(arr.keys()) // Object [Array Iterator] {}
console.log(arr.values()) // Object [Array Iterator] {}
console.log(arr.entries()) // Object [Array Iterator] {}
3. for...of 迭代遍历
let arr = [1,2,3,4,5]
for(let i of arr.entries()){
console.log(i)
}
// [ 0, 1 ]
// [ 1, 2 ]
// [ 2, 3 ]
// [ 3, 4 ]
// [ 4, 5 ]
异步Promise
1. Promise: 异步通信编程的一种解决方案
let p = new Promise((resolve, reject) => {
if(true){
resolve('执行成功')
}else{
reject('执行失败')
}
});
p.then((value) => {
console.log(value);
}).catch((reason) => {
console.log(reason)
});
或
p.then((value) =>{
console.log(value);
},(reason) => {
console.log(reason)
});
实例测试
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('1.异步')
}, 3500)
});
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('2.异步')
}, 800)
});
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('3.异步')
}, 1500)
});
p1.then((value) => {
console.log(value); // 调用p1
return p2;
}).then((value) => {
console.log(value); // 调用p2
return p3;
}).then((value) => {
console.log(value) // 调用p3
});
//1.异步
//2.异步
//3.异步
Promise状态特点
1. Promise解决了异步多层回调混乱的问题
2. Promise对象异步操作的三种状态
Pending(进行中)
Fulfilled(已成功)
Rejected(已失败)
3. 当异步操作执行后, 它得到的结果来决定其状态,其他任何操作都无法改变
4. Pending -> Fulfilled -> Resolve
Pending -> Rejected -> Resolve
5. Promise提供了一个 all() 方法,可以简化多个实例调用的输出排序
let p = Promise.all([p1,p2,p3]) // 参数为数组
p.then((value) => {
console.log(value) // [ '1.异步', '2.异步', '3.异步' ]
});
6. Promise提供了 race() 方法, 只输出第一个改变状态的实例
let p = Promise.race([p1,p2,p3]) // 参数为数组
p.then((value) => {
console.log(value) // 2.异步
});
7. Promise提供了 resolve() 和 reject() 直接返回一个成功或者失败的案例
let p1 = Promise.resolve('成功');
let p2 = Promise.reject('失败')
p1.then((value) => {
console.log(value)
});
p2.then((value) => {
console.log(value)
});
代理Proxy
1. 什么是代理? 即 给目标对象封装一层拦截, 外界访问必须通过这层拦截
let obj = {
name: 'Mr.z',
age: 22,
gender: '男'
}
let p = new Proxy(obj, { //参数一 拦截的目标对象, 参数二 拦截行为
get(target, property){
// return 'fail';
if(property === 'age'){
return target[property];
}else{
return 'fail';
}
}
});
console.log(p.name) // fail
console.log(p.age) // 22
2. 如果代理对象展示合适的值,可以通过 get() 的两个参数实现(可以进行验证与修改等)
get(target, property){
if(property === 'age'){
return target[property] - 20;
}
}
3. 也可以通过 set() 方法来对代理对象的属性进行赋值
set(target, property, value){
if(property === 'age'){
target[property] = value;
}
}
p.age = 30;
console.log(p.age); // 30
小结
1. 代理并不是复制目标对象, 只是拦截目标对象, 更改默认行为
2. 代理可以使用 set() 和 get() 方法,对目标对象的数据进行过滤和验证
3. 代理对象中任何未公开或者不存在的属性, 可自定义返回内容
4. 代理可以阻止赋值的默认行为, 直接 return false
异步async
1. async也是处理异步的, 是对 Promise 的一种扩展, 让异步更加方便
2. 优势: async是基于Promise 的, 虽然是异步操作, 但看上去像同步
let as = async() => {
let result = await p2;
console.log(result)
};
as();
3. 三个异步需要队列输出
async function as(){
let r1 = await p1,
r2 = await p2,
r3 = await p3;
console.log(r1);
console.log(r2);
console.log(r3);
}
as();
// 1.异步
// 2.异步
// 3.异步
对比 Promise, 没有then, 精简许多
p1.then((value) => {
console.log(value); // 调用p1
return p2;
}).then((value) => {
console.log(value); // 调用p2
return p3;
}).then((value) => {
console.log(value) // 调用p3
});
4. await关键字只能在 async 函数内部, 否则不可识别
5. 批量异步队列, 类似Promise.all()
async function as(){
let all = [await p1, await p2, await p3];
console.log(all) // [ '1.异步', '2.异步', '3.异步' ]
}
as();
6. async如果设置了返回值, 这个值是 Promise 对象
async function as(){
return 'async'
}
console.log(as()) // Promise { 'async' }
// 可以通过then() 得到
as().then((value) => {
console.log(value) // async
});
类class实现
1. 在ES6之前, javascript没有完整的类支持
2. ES6之前采用了原型链实现面向对象的功能, ES6开始, 提供了真正的类语法
3. 本质上内部实现和原型链还是一样的
class Person {
// 构造函数(构造方法)
constructor(arg) {
// this.arg是类的属性
// 参数赋值给属性
this.arg = arg;
}
// 普通方法
run(){
return '输出:'+this.arg;
}
}
// 实例化一个Person对象
let p = new Person('Mr.z');
console.log(p.run()); // 输出:Mr.z
console.log(p.arg); // Mr.z
console.log(p instanceof Person); // true
console.log(typeof Person); // function 说明 Person 本质上还是一个函数
getter和setter
1. 根据面向对象的三大定律中成员属性, 我们需要对它进行封装, 变成私有属性
2. 目前的 this.arg, 基本是对外公开的, 可以在类外取值和赋值
class Person {
#arg // 私有声明
// 构造函数(构造方法)
constructor(arg) {
this.#arg = arg; //私有属性, 类外无法访问
}
// 普通方法
run(){
return '输出:'+this.arg;
}
}
// 实例化一个Person对象
let p = new Person('Mr.z');
console.log(p.run()); // 输出:undefined
3. 添加 getter setter 方法
class Person {
#arg // 私有声明
// 构造函数(构造方法)
constructor(arg) {
this.#arg = arg; //私有属性, 类外无法访问
}
get arg(){
return this.#arg;
}
set arg(value){
this.#arg = value;
}
// 普通方法
run(){
return '输出:'+this.arg;
}
}
// 实例化一个Person对象
let p = new Person('Mr.z');
p.arg = 'Mr.x';
console.log(p.arg); // Mr.x
类class继承
1. ES6也支持子类继承父类, 使用 extends 关键字实现
2. 当子类继承父类, 实例化子类后, 就可以直接拥有父类的构造, 属性和方法
class Person {
constructor(arg) {
this.arg = arg;
}
run(){
return '输出:'+this.arg;
}
}
class Children extends Person{
}
let c = new Children('Mr.hahaha');
console.log(c.arg); // Mr.hahaha
console.log(c.run()); // 输出:Mr.hahaha
3. 继承之后, 一般来说,我们需要覆写父类, 然后对子类进行增强
super 作为函数时, 调用父类构造, 作为对象时, 在普通方法返回指定父类方法.
class Person {
constructor(arg) {
this.arg = arg;
}
run(){
return '输出:'+this.arg;
}
}
class Children extends Person{
constructor(arg, age) { // 覆写构造
super(arg); // 执行父类构造并传参
this.age = age;
}
run(){ //覆写方法
return super.run() + this.age; // 执行父类方法并返回内容
}
}
let c = new Children('Mr.hahaha', 22);
console.log(c.run()); // 输出:Mr.hahaha22
4. 可以使用 Object.getPrototypeOf() 判断子类是否继承了父类
console.log(Object.getPrototypeOf(Children) === Person) // true
5. ES6的类支持静态属性和方法, 也支持静态被子类继承(静态属性与方法可以直接调用, 不用实例化)
class Person {
static gender = '男';
}
class Children extends Person{
}
console.log(Person.gender) // 男
console.log(Children.gender) //男
覆写静态
class Person {
static gender = '男';
}
class Children extends Person{
static gender = '女'; // 覆写静态
}
console.log(Person.gender) // 男
console.log(Children.gender) //女
Moudle模块化
1. 浏览器加载, Node加载
区别: 导入 浏览器加载(import * as obj from '/...js')
Node加载(commonJS规范, require('/...js'))