class 类 this指向的问题

时间: 2018-12-29阅读: 1553标签: class

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
站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: http://www.fly63.com/article/detial/1715

vue.js 动态绑定class

vue 指令以 v- 前缀标示,数据绑定的指令 v-bind:属性名, 简写为 :属性名, 简单的数据绑定例子如下;vue 的分隔符默认是 {{ }}, 在分隔符里面的字符串会被认为是数据变量,可以通过 方式设置class

css中class和id之间有什么区别?

我们平常在用DIV+CSS制作html网页页面时,常会用到class 和id来选择调用CSS样式属性。对学习CSS的新手来说class和id可能比较模糊,同时不知道什么时候该用class,什么时候又用id,以及它们用法与限制是怎么样的。

es6中class类的使用

在es5中我们是使用构造函数实例化出来一个对象,那么构造函数与普通的函数有什么区别呢?其实没有区别,无非就是函数名称用首字母大写来加以区分,这个不用对说对es5有了解的朋友都应该知道。

Class:向传统类模式转变的构造函数

JS基于原型的类,一直被转行前端的码僚们大呼惊奇,但接近传统模式使用class关键字定义的出现,ES6的class只是个语法糖,其定义生成的对象依然构造函数。不过为了与构造函数模式区分开,我们称其为类模式。

你需要知道的 JavaScript 类(class)的这些知识

JavaScript 使用原型继承:每个对象都从原型对象继承属性和方法。在Java或Swift等语言中使用的传统类作为创建对象的蓝图,在 JavaScript 中不存在,原型继承仅处理对象。

ES6 static

ES6中新增了class这个语法糖。此class并非java中的class,ES6中的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。其中有static关键字。

mixin配合class实现多继承的绝佳妙用

mixin一般翻译为“混入”、“混合”, 早期一般解释为:把一个对象的方法和属性拷贝到另一个对象上;Mixin是一种思想,用来实现代码高度可复用性,又可以用来解决多继承的问题,是一种非常灵活的设计模式

Class 的私有属性与私有方法

proposal-class-fields与proposal-private-methods定义了 Class 的私有属性以及私有方法,这 2 个提案已经处于 Stage 3,这就意味着它们已经基本确定下来了,等待被加入到新的 ECMAScript 版本中。

快速掌握ES6的class用法

先复习一下es5常用的构建类的方法:首先es5的写法使用原型进行对象的方法的,为什么不在构造函数里添加方法呢?因为实例化对象的时候,会重复的建立好多相同的方法,浪费资源。所以需要把对象的方法挂载到prtotype里。

css modules是什么?

所有的 class 的名称和动画的名称默认属于本地作用域的 CSS 文件。所以 CSS Modules 不是一个官方的规范,也不是浏览器的一种机制,它是一种构建步骤中的一个进程。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!