🎉使用JavaScript实现一个class
🎇class属性
class的特性:
- 1.没有变量提升
- 2.使用strict模式
- 3.必须使用new关键字创建实例
- 4.私有属性不可遍历
class Person{
constructor(name, age){
this.name = name
this.age = age
}
say(){
console.log("hello")
}
sayHi(){
console.log('hi')
}
static eat(){
console.log("eat")
}
}
function Person(name, age){
//2.使用strict模式
"use strict"
var name = arguments.length > 0 && arguments[0] != undefined ? arguments[0] : name
var age = arguments.length > 1 && arguments[1] != undefined ? arguments[1] : age
classCheck()
this.name = name
this.age = age
}
//3.必须使用new关键字创建实例
function classCheck(){
if(typeof new.target == undefined){
throw new Error('必须使用new关键字调用!')
}
}
var createClass = (function (){
function defineProperties(target, props){
for(let i = 0; i< props.length; i++){
var descriptor = props[i]
//不可枚举这里也是使用ObjectdefinProperty设置私有属性
descriptor.enumerable = descriptor.enumerable || false
//可删除
descriptor.confingurable = descriptor.confingurable || true
//ES5的API
Object.definProperty(target, descriptor.key, descriptor)
}
}
return function(constructor, protoProps, stacticProps){
if(protoProps) defineProperties(constructor.prototype, protoProps)
if(stacticProps) defineProperties(constructor, stacticProps)
}
})()
createClass(Person,
[{key:'say',value:function(){console.log("hello")}},
{key:'sayHi',value:function(){console.log('hi')}}],
[{key:'eat',value:function(){ console.log("eat")}}])
🎉设置class的私有属性
🎇闭包
实现类的一个私有属性(在Typescript 中定义了私有属性)
- 能被class内部的不同方法访问,但不能在类外部被访问;
- 子类不能继承父类的私有属性。
使用闭包的形式,通过闭包就可以将x属性变为私有属性
const class = (function(){
let _x
return class Class1{
constructor(x){
_x = _x
}
get(){
return _x
}
}
return Class1
})()
🎇重要WeakMap
使用weakmap进行属性的私有化,weakmap还可以进行弱引用,但是具体的JS的回收机制如何处理回收不得而知。
const map = new WeapMap()
const internal = (obj) => {
if(!map.has(obj)){
map.set(obj,{})
}
return map.get(obj)
}
class Class2{
constructor(name, age){
internal(this).name = name
internal(this).age = age
}
get(){
return internal(this).name + internal(this).age
}
}