class 类 this指向的问题
程序员文章站
2022-04-13 15:32:54
ES6 实现了类的概念 ES5使用函数模拟 ES6中的 class定义一个类, 其内部包含 构造函数, 除了在构造函数显示的定义一些属性, 其余的默认都添加到这个类的原型对象上。 在一个类中定义一个读取名字的函数: 如果我们把 sayName 这个函数拿出来运行会是什么结果呢? 继以上代码 以上报错 ......
es6 实现了类的概念
class prosen { }
es5使用函数模拟
function prosen() { }
es6中的 class定义一个类, 其内部包含 constructor
构造函数, 除了在构造函数显示的定义一些属性, 其余的默认都添加到这个类的原型对象上。
在一个类中定义一个读取名字的函数:
class prosen { constructor(name) { this.name = name; } sayname() { console.log(this.name) } } const prosen = new prosen('zhangsan') prosen.sayname() //张三
如果我们把 sayname 这个函数拿出来运行会是什么结果呢?
继以上代码
const prosen1 = new prosen('lisi') const { sayname } = prosen1 sayname() // 报错
以上报错的原因是 sayname
函数中的 this不对。指向的不是 prosen1这个实例对象,所以是无法读取name
属性的。
使用 proxy来代理实例对象,拦截读取操作并修改this的指向
function classproxy(target) { const m = weakmap() // 读取拦截配置, 只需要配置 get const hanlder = { get(target, key) { const val = reflect.get(target, key) // 要获取的是函数执行, 如果不是函数就直接返回 val if (typeof val !== 'function') return val if (!m.has(val)) { // 使用 bind改变运行函数的 this为拦截的实例对象 m.set(val, val.bind(target)) } return m.get(val) } } const proxy = new proxy(target, hanlder) return proxy }
继以上代码
const prosen2 = new prosen('qiqingfu') const { sayname } = classproxy(prosen2) sayname() // qiqingfu
以上代码 classproxy(prosen2)
返回的是包含一层拦截器的实例对象, 当读取 sayname
这个函数的是和会出发 get
拦截等操作。
总结其它知识点
proxy: 拦截器, 用于对象操作的自定义行为(如属性查找, 赋值, 枚举, 函数调用, 是实例化等)
reflect 是一个内置的对象, 它提供拦截 javascript方法,和object操作类似。
weakmap: 可以实现对象 值-值的对应, 并且一个对象的键值只能是对象,且不计入垃圾回收机制,可对象引用常驻内存造成的内存泄漏等问题。
weakmap:
const n = {a: 1} const m = new weakmap() m.set(n, 1) m.get(n) // 1 m.has(n) // true