类
继承
- 静态方法不在实例化的对象上,所以
new
出来的对象上是没有静态方法的 - 普通属性的继承,在
function B{ }
调用A.call(this, name)
- 普通方法的继承
// 方案一
B.prototype = Object.create(A.prototype) // 原型继承,创建一个空对象,并把空对象的 __proto__ 设置为 A.prototype
Object.defineProperty(B.prototype, "constructor", {
value: B,
enumerable: false
})
// 方案二
Object.setPrototypeOf(B.prototype, A.prototype)
- 以上的方法在继承层级大于二的时候有问题
- 关于静态属性、方法的继承可以利用
B.__proto__ = A
实现
类的继承
class A {
constructor(name) {
this.name = name
}
sing() {
return `${this.name}在唱歌`
}
}
class B extends A {
constructor(name, age) {
super(name)
this.age = age
}
sing() {
return `${this.age}岁的${super.sing()}`
}
}
原型链的继承
function A(name) {
this.name = name
}
A.prototype.sing = function () {
return `${this.name}在唱歌`
}
function B(name, age) {
A.call(this, name) //其实等于在 B 添加了 name 属性
this.age = age
}
// 方案一
B.prototype = Object.create(A.prototype) // 原型继承,创建一个空对象,并把空对象的 __proto__ 设置为 A.prototype
Object.defineProperty(B.prototype, "constructor", {
value: B,
enumerable: false
})
B.prototype.sing = function () {
return `${this.age}岁的${A.prototype.sing.call(this)}`
}
// 方案二
Object.setPrototypeOf(B.prototype, A.prototype)
// 方案三
B.prototype.__proto__ = A.prototype
动态与静态
原型实现
"use strict"
// 动态
function Web() {
this.aaa = "this is aaa" //普遍属性
}
Web.prototype.bbb = function () {
console.log(this)
return "this is bbb" //普遍方法
}
Web.prototype.ccc = function () {
return 'cccFun:' + this.aaa //普遍方法里调用普通属性
}
Web.prototype.ddd = function () {
return 'dddFun:' + Web.eee //普通方法里调用静态属性
}
// 静态
Web.eee = "this is eee" // 静态属性
Web.fff = function () {
console.log(this)
return "this is fff" // 静态方法
}
Web.ggg = function () {
return 'gggFun:' + this.aaa //静态方法里调用普通属性
// !!!错误的调用,因为没有 new 所以当前的 this 是指向 Web 对象,而不是 Web 实例化的对象
}
Web.hhh = function () {
return 'hhhFun:' + this.eee //静态方法里调用静态属性
}
Web.iii = function () {
return 'iiiFun:' + Web.eee //静态方法里调用静态属性
}
类实现
"use strict"
class Html {
aaa = "this is aaa" //普遍属性
bbb() {
return "this is bbb"//普遍方法
}
ccc() {
return 'cccFun:' + this.aaa //普遍方法里调用普通属性
}
ddd() {
return 'dddFun:' + Html.eee //普通方法里调用静态属性
}
// 静态
static eee = "this is eee" // 静态属性
static fff() {
return "this is fff" // 静态方法
}
static ggg() {
return 'gggFun:' + this.aaa
// !!!错误的调用,因为没有 new 所以当前的 this 是指向 Web 对象,而不是 Web 实例化的对象
}
static hhh() {
return 'hhhFun:' + this.eee //静态方法里调用静态属性
}
static iii() {
return 'iiiFun:' + Html.eee //静态方法里调用静态属性
}
}
访问/获取器
"use strict"
class Requset {
constructor(host) {
this.data = {}
}
set host(url) {
if (!/^https?:\/\//i.test(url)) {
throw new Error("地址错误")
}
this.data.host = url
}
get host() {
return this.data.host
}
}
访问权限
受保护的:Symbol 实现
"use strict"
const protecteds = Symbol()
class Requset {
constructor(host) {
this[protecteds] = {}
this.host = host
}
set host(url) {
if (!/^https?:\/\//i.test(url)) {
throw new Error("地址格式错误")
}
this[protecteds].host = url
}
get host() {
return this[protecteds].host
}
}
受保护的:WeakMap 实现
"use strict"
const protecteds = new WeakMap()
class Requset {
constructor(host) {
this.host = host
}
set host(host) {
if (!/^https?:\/\//i.test(host)) {
throw new Error("地址错误")
}
protecteds.set(this, { ...protecteds.get(this), host })
}
get host() {
return protecteds.get(this).host
}
}
#
实现
私有的:"use strict"
class Requset {
#host = ""
constructor(host) {
this.#host = host
this.#check(this.#host)
}
set host(host) {
if (!/^https?:\/\//i.test(host)) {
throw new Error("地址错误")
}
this.#check(host)
this.#host = host
}
get host() {
return this.#host
}
#check = (name) => {
if (name.length < 15) {
throw new Error("名字长度不能小于五位")
}
}
}
mixin 混合模式
就是在类的 .portotype
上追加另一个对象的所有属性
"use strict"
Object.assign(B.prototype, A)