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 先写下总结,通过总结下面的例子,你就会明白总结了. 下面总结一下: ...
随机推荐
- 3d Max 2015安装失败怎样卸载3dsmax?错误提示某些产品无法安装
AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...
- UGUI Image血条或者进度条效果
把图片的Image组件中的image type选成Filled,下面就出现了Fill Amount,通过GetComponent<Image>().fillAmount; 就可以拿到flo ...
- 源码剖析Linux epoll实现机制及Linux上惊群
转载:https://blog.csdn.net/tgxallen/article/details/78086360 看源码是对一个技术认识最直接且最有效的方式了,之前用Linux Epoll做过一个 ...
- Murano Weekly Meeting 2015.08.11
Meeting time: 2015.August.11th 1:00~2:00 Chairperson: Serg Melikyan, PTL from Mirantis Meeting summ ...
- Map集合练习之对字符串中字母出现的次数求和
不多说,直接上干货! 代码需求 如有这么一个字符串 String str = "fdg+avAdc bs5dDa9c-dfs"; MapTest.java package zhou ...
- 在线编辑word文档 可保存到服务器
使用说明:该方法只在office xp 和 2003上 测试通过,2000及以下 版本没试. 注意:你要打开的服务器端的word文档要有写权限.iis要开起 web服务扩展中的webdav为允许 具体 ...
- 把js生成的内容放入网页原有的div上
<script> ; ; //5列 ); ; var htmlstr="<table style='position:absolute;top:9%;left:10%; b ...
- EntityFramework报错
解决:未能加载文件或程序集“EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089” 使用 ...
- 拖拽事件--select外边框拖拽
地图上面的搜索框要可拖拽 但是搜索框是有点击事件的,点击显隐下拉菜单,如果拖拽的事件源选择select框的话,会有样式(十字拖动符cursor:move与selelt默认点击的箭头)冲突 思索良久,就 ...
- C++ Knowledge series 5
Programming language evolves always along with Compiler's evolvement On the Cusp of the Object Model ...