class 类 this指向的问题
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
class 类 this指向的问题的更多相关文章
- OC3-父类指针指向子类对象
// // Cat.h // OC3-父类指针指向子类对象 // // Created by qianfeng on 15/6/17. // Copyright (c) 2015年 qianfeng. ...
- c++ 动态判断基类指针指向的子类类型(typeid)
我们在程序中定义了一个基类,该基类有n个子类,为了方便,我们经常定义一个基类的指针数组,数组中的每一项指向都指向一个子类,那么在程序中我们如何判断这些基类指针是指向哪个子类呢? 本文提供了两种方法 ( ...
- 何使用派生类指针指向基类,即downcast向下转型?
基类指针指向派生类,我们已经很熟了.假如我们想用派生类反过来指向基类,就需要有两个要求:1)马克-to-win:基类指针开始时指向派生类,2)我们还需要清清楚楚的转型一下. if you want t ...
- C++ 类中指向函数的指针 以及 类模板
C++类中总是出现诸如下面的情况 这是一篇深入浅出讲解函数指针的文章,值得参考! http://blog.csdn.net/lishuhuakai/article/details/18276477 关 ...
- c++基类指针指向继承类调用继承类函数
类里面重载运算符>>, 需要使用友元函数,而友元函数,不能作为虚函数. 所以,基类指针无法直接调用继承类里重构的 >> ; 使用类转换,能解决掉,基类指针 调用 继承类 ...
- C++中“类”相关知识点汇总
一:类中默认的成员函数 一个空的class在C++编译器处理过后就不再为空,编译器会自动地为我们声明一些member function,如果你写 class Empty{}; 就相当于: class ...
- [Effective Java]第四章 类和接口
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- C++——类和动态内存分配
一.动态内存和类 1.静态类成员 (1)静态类成员的特点 无论创建多少对象,程序都只创建一个静态类变量副本.也就是说,类的所有对象都共享同一个静态成员. (2)初始化静态成员变量 1)不能在类声明中初 ...
- C++ 类的内存分布
C++类内存分布 转自:http://www.cnblogs.com/jerry19880126/p/3616999.html 先写下总结,通过总结下面的例子,你就会明白总结了. 下面总结一下: ...
随机推荐
- NGINX编译选项
一.减小编译后的文件大小Nginx源码文件解压后,找到auto/cc/gcc文件,注释或删除:# debugCFLAGS= "CFLAGS -g"即可取消debug模式.二:为特定 ...
- python单元测试框架-unittest(一)
简介 unittest单元测试框架不仅可以适用于单元测试,还可以使用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果. ...
- (转)python学习链接
原文:http://www.cnblogs.com/spykids/category/782491.html http://www.cnblogs.com/alex3714/category/7707 ...
- 用Windows Live Writer离线写博客
作为CSDN博客的菜鸟,我发现在线写博客很不方便,而且文字编辑也不方便,比如不能傻瓜化地修改字体和颜色."有志者自有千方百计,无志者只感千难万难."一番搜索后,我发现了Window ...
- pat05-图2. Saving James Bond - Easy Version (25)
05-图2. Saving James Bond - Easy Version (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作 ...
- GitKraken使用教程-基础部分(6)
4) 放弃本次文件的改动 有些情况下,由于更改代码造成了编译无法通过等错误时,想要放弃这次对文件的修改,将文件还原成上一次提交后的状态,一种简单的恢复文件的方法就是,在Unstaged Files 列 ...
- 未能解析引用的程序集......因为它对不在当前目标框架“.NETFramework,Version=v4.0,Profile=Client”中的
解决方法:资源管理器下点击项目名(右键)属性--将.NET Framework 4 Client Profile改成.NET Framework 4 . 传送门:http://bbs.csdn.net ...
- 2019.3.26判断是否回文(java实现)
我所有的文章都是对我总结学习的总结,那里不好或者冒犯了那里,我先对您说声对不起,请告知我进行改正. 今天java老师作业题目是判断是一个字符串否是回文: emmmm,我的思路是将字符串逆序,然后使用方 ...
- BZOJ4653: [Noi2016]区间(线段树 双指针)
题意 题目链接 Sol 按照dls的说法,一般这一类的题有两种思路,一种是枚举一个点\(M\),然后check它能否成为答案.但是对于此题来说好像不好搞 另一种思路是枚举最小的区间长度是多少,这样我们 ...
- url长度
今天在测试Email Ticket的时候发现在进行Mark as Read/Unread操作时,请求是通过GET方式进行的.URL中列出了所有参与该操作的Ticket Id.于是,我想起GET请求是有 ...