当前位置: 移动技术网 > IT编程>开发语言>JavaScript > class 类 this指向的问题

class 类 this指向的问题

2018年12月29日  | 移动技术网IT编程  | 我要评论

olivia burke,金敏智整容,赛尔号炫彩精灵胶囊

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网