Effective JavaScript Item 37 认识this的隐式指向
本系列作为Effective JavaScript的读书笔记。
CSV数据通常都会被某种分隔符进行分隔。所以在实现CSV Reader时,须要支持不同的分隔符。那么,非常自然的一种实现就是将分隔符作为构造函数的參数。
function CSVReader(separators) {
this.separators = separators || [","];
this.regexp =
new RegExp(this.separators.map(function(sep) {
return "\\" + sep[0];
}).join("|"));
}
对于CSV Reader而言。它的工作原理是首先将读入的字符串依据换行符切分成为一个个的行。然后对每行依据分隔符进行切分成为一个个的单元。
所以,能够使用map方法进行实现:
CSVReader.prototype.read = function(str) {
var lines = str.trim().split(/\n/);
return lines.map(function(line) {
return line.split(this.regexp); // wrong this!
});
};
var reader = new CSVReader();
reader.read("a,b,c\nd,e,f\n"); // [["a,b,c"], ["d,e,f"]], wrong result
但是上述代码中有一个错误:传入到map函数中的回调函数的this指向有问题。即当中的this.regexp并不能正确的引用到CSVReader实例的regexp属性。因此,最后得到的结果也就是不对的了。
对于这个样例。在map的回调函数中this指向的实际上是全局对象window。关于this在各种场景下的指向,在Item
18和Item 25中进行了介绍。
为了克服this的指向问题,map函数提供了第二个參数用来指定在其回调函数中this的指向:
CSVReader.prototype.read = function(str) {
var lines = str.trim().split(/\n/);
return lines.map(function(line) {
return line.split(this.regexp);
}, this); // forward outer this-binding to callback
};
var reader = new CSVReader();
reader.read("a,b,c\nd,e,f\n");
// [["a","b","c"], ["d","e","f"]]
可是,并非全部的函数都如map考虑的这么周全。假设map函数不能接受第二个參数作为this的指向。能够使用以下的方法:
CSVReader.prototype.read = function(str) {
var lines = str.trim().split(/\n/);
var self = this; // save a reference to outer this-binding
return lines.map(function(line) {
return line.split(self.regexp); // use outer this
});
};
var reader = new CSVReader();
reader.read("a,b,c\nd,e,f\n");
// [["a","b","c"], ["d","e","f"]]
这样的方法将this的引用保存到了另外一个变量中,然后利用闭包的特性在map的回调函数中对它进行訪问。一般会使用变量名self来保存this的引用。当然使用诸如me。that也是可行的。
在ES5环境中。还能够借助于函数的bind方法来绑定this的指向(在Item
25中,对该方法进行了介绍):
CSVReader.prototype.read = function(str) {
var lines = str.trim().split(/\n/);
return lines.map(function(line) {
return line.split(this.regexp);
}.bind(this)); // bind to outer this-binding
};
var reader = new CSVReader();
reader.read("a,b,c\nd,e,f\n");
// [["a","b","c"], ["d","e","f"]]
总结
- 依据函数的调用方式的不同,this的指向也会不同。
- 使用self,me,that来保存当前this的引用供其它函数使用。
Effective JavaScript Item 37 认识this的隐式指向的更多相关文章
- Effective JavaScript Item 22 使用arguments来创建接受可变參数列表的函数
本系列作为Effective JavaScript的读书笔记. 在Item 21中,介绍了结合apply方法实现的可变參数列表函数average,它实际上仅仅声明了一个数组作为參数,可是利用apply ...
- Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表
本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...
- Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合
本系列作为Effective JavaScript的读书笔记. ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 可是在使用for..in循环对Objec ...
- Effective JavaScript Item 10 避免使用with
本系列作为Effective JavaScript的读书笔记. Item 9:避免使用withkeyword 重点: 设计withkeyword本来是为了让代码变简洁,可是却起到了相反的效果.比方: ...
- Effective JavaScript Item 39 绝不要重用父类型中的属性名
本系列作为Effective JavaScript的读书笔记. 假设须要向Item 38中的Actor对象加入一个ID信息: function Actor(scene, x, y) { this.sc ...
- Effective JavaScript Item 31 优先使用Object.getPrototypeOf,而不是__proto__
本系列作为Effective JavaScript的读书笔记. 在ES5中引入了Object.getPrototypeOf作为获取对象原型对象的标准API.可是在非常多运行环境中.也提供了一个特殊的_ ...
- Effective JavaScript Item 38 调用父类的构造函数在子类的构造函数
作为这一系列Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中.都会有场景(Scene)这一概念.在一个场景中会包括一个对象集合,这些对象被称为角色(Actor). ...
- Effective JavaScript Item 30 理解prototype, getPrototypeOf和__proto__的不同
本系列作为Effective JavaScript的读书笔记. prototype,getPropertyOf和__proto__是三个用来訪问prototype的方法.它们的命名方式非常类似因此非常 ...
- Effective JavaScript Item 49 对于数组遍历,优先使用for循环,而不是for..in循环
本系列作为Effective JavaScript的读书笔记. 对于以下这段代码,能看出最后的平均数是多少吗? var scores = [98, 74, 85, 77, 93, 100, 89]; ...
随机推荐
- 【web.xml】报错java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
今天搭建新的项目,虽然在web.xml中配置了ContextLoaderListener以及IntrospectorCleanupListener 如下: web.xml中部分代码: <!-- ...
- 十大流行linux
你可曾知道Linux的魅力或威力来自哪里?那就是,由于众多发行版百花齐放,Linux的阵营日益壮大,每一款发行版都拥有一大批用户,开发者自愿为相关项目投入精力.Linux发行版可谓是形形色色,它们旨在 ...
- nano命令,vi ed pico sed joe emacs jed ex
nano命令 nano是一个字符终端的文本编辑器,有点像DOS下的editor程序.它比vi/vim要简单得多,比较适合Linux初学者使用.某些Linux发行版的默认编辑器就是nano. nan ...
- 剖析ASP.NET Core(Part 4)- 调用MVC中间件(译)
原文:https://www.stevejgordon.co.uk/invoking-mvc-middleware-asp-net-core-anatomy-part-4 发布于:2017年5月环境: ...
- 数组类型参数传递问题:$.ajax传递数组的traditional参数传递必须true
数组类型参数传递: 若一个请求中包含多个值,如:(test.action?tid=1&tid=2&tid=3),参数都是同一个,只是指定多个值,这样请求时后台会发生解析错误,应先使用 ...
- java中return的作用
脑补一下基础的东西,return的用法. return的常用作用有以下两种第一种用法是返回参数所用的关键字,假如一个有返回值的方法执行完了之后需要返回一个参数,示例: public string fu ...
- win8.1 64位环境搭建android开发环境
1.下载JDK,http://www.oracle.com/technetwork/java/javase/downloads/index.html,选择版本 2.安装刚刚下载的JDK 3.环境变量配 ...
- Hadoop 伪分布式上安装 Hive
下载地址:点此链接(P.S.下载带bin的安装包) 下载hive后放到虚拟机文件夹内,打开: -bin.tar.gz -C /home/software/ 修改并保存环境配置: gedit /etc/ ...
- JVM性能监控工具(一)-jdk命令行工具
转载:http://blog.csdn.net/top_code/article/details/51456186 当系统出bug需要定位问题的时候,知识.经验是关键基础,数据是依据,工具是运用知识处 ...
- iOS_Objective-C測试
1. iOS中程序正常载入UIViewControlle时,下面四个方法哪个最先运行? A.viewVillAppear B.viewDidLoad C.viewDidAppear D.viewWil ...