目录
class 类
ES6 声明类
class 类静态成员
ES5 构造函数继承
ES6 类继承
子类对父类方法的重写
class 中 getter 和 setter 设置
数值扩展
Number.EPSILON
二进制和八进制
Number.isFinite
Number.isNaN
Number.parseInt
Number.parseFloat
Number.isInteger
Math.trunc
Math.sign
对象方法扩展
Object.is
Object.assign
Object.setPrototypeof
Object.getPrototypeof
ES6 提供了更接近传统语言的写法,引入了 Class(类)的概念,作为对象的模板
通过 class 关键字,可以定义类
基本上,ES6 的 class 可以看作是一个语法糖,它的绝大部分功能,ES5都可以实现
新的 class 写法只是让对象圆形的写法更加清晰、更像面向对象编程的语法而已
知识点:
// 手机
// ES5 声明 class 方法
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) // Phone {brand: "华为", price: 5999}
// ES6 声明方法
class Phone1 {
// 构造方法 constructor
// 该方法在类执行 new+类名时,就会自动执行实例对象的 constructor 方法
constructor(brand, price) {
// 添加属性
this.brand = brand
this.price = price
}
// 添加方法,方法必须使用该语法,不能使用 ES5 的对象完整形式
call() {
console.log('听音乐')
}
}
let hongmi = new Phone1('红米k40', 2499)
console.log(hongmi) // Phone1 {brand: "红米k40", price: 2499}
// ES5 构造函数
function Phone() {}
// Phone.name 和 Phone.price 只属于函数对象(类),并不属于实例对象
// 对于这样的属性,我们称之为静态成员
Phone.myname = 'vivo'
Phone.price = function () {
console.log('vivoZ10 仅售2499')
}
// 实例对象
let vivo = new Phone()
console.log(vivo.myname) // undefined,实例对象并没有构造函数对象上的属性
console.log(Phone.myname) // vivo,意味着实例对象和函数对象的属性是不通的
// vivo.price(); // 方法也没有,提示 price 并不是一个函数
// 实例对象与构造函数原型对象是相通的
// 构造函数原型对象
Phone.prototype.myname = 'vivoX10'
Phone.prototype.mysize = '5.5inch'
let vivo1 = new Phone()
console.log(vivo1.myname) // vivoX10
console.log(vivo1.mysize) // 5.5inch
console.log(Phone.mysize) // undefined
// ES6 构造函数
class shouji {
// static 静态成员
static myname = '苹果'
static functions() {
console.log('打电话,听音乐')
}
}
let iPhone = new shouji()
console.log(iPhone.myname) // undefined
console.log(shouji.myname) // 苹果
// 再次证明,static 标注的属性和方法属于类,但不属于实例对象
// 手机
function Phone(brand, price) {
this.brand = brand
this.price = price
}
Phone.prototype.functions = function () {
console.log('打电话,听音乐')
}
// 以上是父级构造函数
// 声明一个子级构造函数
// 智能手机
function SmartPhone(brand, price, color, size) {
// 调用父级构造函数初始化代码,两个 this
Phone.call(this, brand, price) // Phone 通过 call 方法改变 this 值
// 此处的 this 指向 SmartPhone 里面的 this ,即 SmartPhone 中的一个实例对象
// 继承父级构造函数的 brand 和 price 属性
this.color = color
this.size = size
}
// 设置子级构造函数的原型
SmartPhone.prototype = new Phone() // 如此,子级的实例对象就会有父级的属性和方法
SmartPhone.prototype.constructor = SmartPhone // 校正,可有可无
// 声明子类的方法
SmartPhone.prototype.photo = function () {
console.log('拍照')
}
SmartPhone.prototype.game = function () {
console.log('玩游戏')
}
// 实例化
const chuizi = new SmartPhone('锤子', 2499, '黑色', '5.5inch')
console.log(chuizi)
// SmartPhone {brand: "锤子", price: 2499, color: "黑色", size: "5.5inch"}
class Phone {
// 构造方法
constructor(brand, price) {
this.brand = brand
this.price = price
}
// 父类的成员属性
functions() {
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('拍照')
}
game() {
console.log('玩游戏')
}
}
// 实例化
const xiaomi = new SmartPhone('小米', 2499, '黑色', '5.5inch')
console.log(xiaomi)
// SmartPhone {brand: "小米", price: 2499, color: "黑色", size: "5.5inch"}
xiaomi.functions() // 打电话
xiaomi.photo() // 拍照
xiaomi.game() // 玩游戏
class Phone {
// 父类的成员属性
functions() {
console.log('打电话')
}
}
// 声明子类
class SmartPhone extends Phone {
// 重写 functions 方法
functions() {
// 注意,在 JS 中,子类不能直接调用父类的同名方法
// 此处也不可以使用 super()
// super() 是父类构造方法,只在创建对象时使用
// 通过 super() 方法调用 call() 方法
// 因此只能重写父类方法
console.log('视频/语音通话')
}
}
// 实例化
xiaomi.functions() // 视频/语音通话
// Number.EPSILON
function equal(a, b) {
if (Math.abs(a - b) < Number.EPSILON) {
return true
} else {
return false
}
}
console.log(0.1 + 0.2 === 0.3) // false
console.log(equal(0.1 + 0.2, 0.3)) // true
// 二进制
let two = 0b1010
console.log(two)
// 八进制
let eight = 0o777
console.log(eight)
// 十进制
let ten = 100
console.log(ten)
// 十六进制
let sixteen = 0xff
console.log(sixteen)
// Number.isFinite 检测一个数值是否为有限数
console.log(Number.isFinite(100)) // true
console.log(Number.isFinite(100 / 3)) // true
console.log(Number.isFinite(100 / 0)) // true
console.log(Number.isFinite(Infinity)) // true
// Number.isNaN 检测一个数值是否严格等于 NaN
console.log(Number.isNaN(100)) // false
console.log(Number.isNaN('100')) // false
console.log(Number.isNaN('str')) // false
// Number.parseInt Number.parseFloat 字符串转为整型
console.log(Number.parseInt('521zdn')) // 521
console.log(Number.parseInt('zdn521')) // NaN
console.log(Number.parseFloat('5.21zdn')) // 5.21
console.log(Number.parseFloat('zdn5.21')) // NaN
// Number.isInteger 判断一个数是否为整数
console.log(Number.isInteger(100)) // true
console.log(Number.isInteger(100.1)) // false
console.log(Number.isInteger('100')) // false
console.log(Number.isInteger('hello')) // false
// Math.trunc 将数字小数部分抹掉
console.log(Math.trunc(5.21)) // 5
console.log(Math.trunc('5.21')) // 5
console.log(Math.trunc('5.21 hello')) // NaN
console.log(Math.trunc('hello')) // NaN
// Math.sign 判断一个数到底为正数、负数、零
console.log(Math.sign(10)) // 1
console.log(Math.sign(0)) // 0
console.log(Math.sign(-99)) // -1
// Object.is 判断两个值是否完全相等
// 与全等很像但并不是完全相同
console.log(Object.is(120, 120)) // true
console.log(Object.is(NaN, NaN)) // true
console.log(Object.is('hello', 'hello')) // true
console.log(Object.is('hello', 'world')) // false
// NaN 不等于 任何数值
console.log(120 === 120) // true
console.log(NaN === NaN) // false
console.log('hello' === 'hello') // true
console.log('hello' === 'world') // false
// Object.assign 对象的合并
// 经常用于配置的合并
// 合并的两个对象,后者会覆盖前者重名的属性,不重名的属性将会被保留
const config1 = {
host: 'localhost',
port: 3306,
name: 'root',
password: 'root',
test: 'test',
}
const config2 = {
host: 'http://www.jnshu.com/',
port: 3307,
name: 'IT 修真院',
password: 'root',
}
// 括号中的两个参数,第一个为被覆盖对象,第二个为覆盖对象
const config = Object.assign(config1, config2)
console.log(config) // 输出结果为 config2
// {host: "http://www.jnshu.com/", port: 3307, name: "IT 修真院", password: "root", test: "test"}
// Object.setPrototypeOf 设置原型对象
const school = {
name: 'imau',
}
const campus = {
xiaoqu: ['西区', '东区', '南区', '新区'],
}
// 为 school 设置原型 Object.getPrototypeOf 获取原型
// 将第二个参数插入第一个参数中作为原型
Object.setPrototypeOf(school, campus)
console.log(Object.getPrototypeOf(school)) // {xiaoqu: Array(4)}
// 获取到的是 school 的原型 campus
console.log(school) // {name: "imau"}
// 虽然可以通过这样的方式改变对象的原型,但是并不建议这样做
// 正确的做法还是通过 Object.create 创建对象时就将原型设置好
// 效率更高