ES6 Class对象研究

ES6 Class对象研究

Tags
ES6
JavaScript
面向对象编程
迭代器模式
函数式编程
代理模式
CreatedTime
Aug 18, 2022 10:01 AM
Slug
2019-04-09-es6-es5-class
UpdatedTime
Last updated August 31, 2022

es6 class 的 new 实例和 es5 的 new 实例有什么区别?

ES6中(和ES5相比),classnew实例有以下特点:
  • class的构造参数必须是new来调用,不可以将其作为普通函数执行
  • es6class不存在变量提升
  • 最重要的是:es6 内部方法不可以枚举。es5 的prototype上的方法可以枚举。
为此我做了以下测试代码进行验证:
console.log(ES5Class()); // es5:可以直接作为函数运行 // console.log(new ES6Class()) // 会报错:不存在变量提升 function ES5Class() { console.log("hello"); } ES5Class.prototype.func = function() { console.log("Hello world"); }; class ES6Class { constructor() {} func() { console.log("Hello world"); } } let es5 = new ES5Class(); let es6 = new ES6Class(); // 推荐在循环对象属性的时候,使用for...in // 在遍历数组的时候的时候,使用for...of console.log("ES5 :"); for (let _ in es5) { console.log(_); } // es6:不可枚举 console.log("ES6 :"); for (let _ in es6) { console.log(_); }

ES6 class 实现状态函数(static变量)

在C语言中,使用 static 关键字来增加函数变量的生命周期(不是范围),使其超出函数的调用范围。 在JS/TS中,也可以实现。通过class
const { called } = new (class { count = 0; called = () => { this.count++; console.log("Called: ", this.count); }; })(); called(); called();
也可以用闭包:
const { called: called2 } = (() => { var count = 0; return { called: () => { count++; console.log("Called: ", count); } }; })(); called2(); called2();

ES6 Class怎么把Class变成Iterator?

使用 class 的 name属性 + generator 方法:
//定义类 class Foo { constructor(...args) { this.args = args; } *[Symbol.iterator]() { for (let arg of this.args) { yield arg; } } } var foo = new Foo(1, 2, 3); for (let x of foo) { console.log(x); }

ES6 Class 如何解决 this 指向问题?

问题描述:
class Logger { constructor(name) { this.name = name; } print() { console.log(this.name); } } const logger = new Logger('sysdesign.fun'); const { print } = logger; print(); // this 指针丢失。TypeError: Cannot read property 'name' of undefined
解决1: 构建函数中,绑定 this
class Logger { constructor(name) { this.name = name; this.print = this.print.bind(this); } }
解决2: 使用 Proxy 自动绑定 this
function proxyClsThis(instance) { const cache = new WeakMap(); const proxy = new Proxy(instance, { get(target, propKey) { const val = Reflect.get(target, propKey); if (typeof val !== 'function') { return val; } // return val.bind(target); // 可以直接返回,但是用上缓存,性能更好;同时 WeakMap 能防止内存泄漏;注意 WeakMap 的 key 设计 if (!cache.has(val)) { cache.set(val, val.bind(target)); } return cache.get(val); }, }); return proxy; } const logger = proxyClsThis(new Logger('sysdesign.fun')); const { print } = logger; print();

ES6 Class 如何解决私有属性问题?

准确来说,对象的操作,都可以通过Proxy来实现。具体可以见 [[ES6的Proxy,以及Reflect]] ,或者参考前面的解决2方案。