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 先写下总结,通过总结下面的例子,你就会明白总结了. 下面总结一下: ...
随机推荐
- (转)Rsync 排错案例解析
Rsync 排错案例解析 原文:http://blog.51cto.com/irow10/1827306 错误一. 执行计划任务的备份脚本后没有看到备份的文件 1.首先查看crontab日志是否执行文 ...
- 文本框只允许输入数字.net/javascript
<input type="text" name="test" onKeyUp="test1.value=(this.value=this.val ...
- C知识要点-个人总结
[数据结构]()C 结构体.C 共用体.C 数组.C 指针..... 存储类.auto.register.static.extern C 函数.定义函数.返回类型.函数名称.参数.函数主体.返回语句. ...
- 一个position为fixed的div,宽高自适应,怎样让它水平垂直都在窗口居中?
.div{ position: fixed; left: %; top: %; -webkit-transform: translate(-%, -%); transform: translate(- ...
- MVC 模型过滤
通用返回模型 /// <summary> /// WebApi返回数据的泛型类 /// </summary> /// <typeparam name="T&qu ...
- SQL——行转列,列转行
行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现.用传统的方法,比较好理解.层次清 ...
- Hibernate系列3-----之修改
只是修改测试类,先看其他的代码的同学,请翻看我的博客Hibernate1,嘿嘿,我就在这不在重写一遍来 @Test public void testhibernate() { updateStuden ...
- Start activity with App Chooser or not ?
启动一个Activity,可以直接使用Intent,例如: Intent intent = new Intent(Intent.ACTION_SEND); ... startActivity(inte ...
- Python列表边遍历边修改问题解决方案:alist[:]
最近在看python,遇到个简单的问题:删除列表中指定的重复元素,发现一些实用并且有趣的东西. 1.错误示范 alist = [1,1,2,2,3,3,2,2,1,1] for i in alist: ...
- (三)JavaScript之[事件]与[字符串]
5].事件**JavaScript事件:HTML事件 * HTML事件是发生在HTML元素上的事情 * HTML事件可以是[浏览器的行为],也可以是[用户的行为] * * 实例: * HTML页面完成 ...