本系列作为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"]]

总结

  1. 依据函数的调用方式的不同,this的指向也会不同。
  2. 使用self,me,that来保存当前this的引用供其它函数使用。

Effective JavaScript Item 37 认识this的隐式指向的更多相关文章

  1. Effective JavaScript Item 22 使用arguments来创建接受可变參数列表的函数

    本系列作为Effective JavaScript的读书笔记. 在Item 21中,介绍了结合apply方法实现的可变參数列表函数average,它实际上仅仅声明了一个数组作为參数,可是利用apply ...

  2. Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表

    本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...

  3. Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合

    本系列作为Effective JavaScript的读书笔记. ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 可是在使用for..in循环对Objec ...

  4. Effective JavaScript Item 10 避免使用with

    本系列作为Effective JavaScript的读书笔记. Item 9:避免使用withkeyword 重点: 设计withkeyword本来是为了让代码变简洁,可是却起到了相反的效果.比方: ...

  5. Effective JavaScript Item 39 绝不要重用父类型中的属性名

    本系列作为Effective JavaScript的读书笔记. 假设须要向Item 38中的Actor对象加入一个ID信息: function Actor(scene, x, y) { this.sc ...

  6. Effective JavaScript Item 31 优先使用Object.getPrototypeOf,而不是__proto__

    本系列作为Effective JavaScript的读书笔记. 在ES5中引入了Object.getPrototypeOf作为获取对象原型对象的标准API.可是在非常多运行环境中.也提供了一个特殊的_ ...

  7. Effective JavaScript Item 38 调用父类的构造函数在子类的构造函数

    作为这一系列Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中.都会有场景(Scene)这一概念.在一个场景中会包括一个对象集合,这些对象被称为角色(Actor). ...

  8. Effective JavaScript Item 30 理解prototype, getPrototypeOf和__proto__的不同

    本系列作为Effective JavaScript的读书笔记. prototype,getPropertyOf和__proto__是三个用来訪问prototype的方法.它们的命名方式非常类似因此非常 ...

  9. Effective JavaScript Item 49 对于数组遍历,优先使用for循环,而不是for..in循环

    本系列作为Effective JavaScript的读书笔记. 对于以下这段代码,能看出最后的平均数是多少吗? var scores = [98, 74, 85, 77, 93, 100, 89]; ...

随机推荐

  1. 掌握Linux编程的10个步骤

    Linux 编程经典书籍推荐 Denis 2008年10月17日 浏览:84168 成为一名精通 Linux 程序设计的高级程序员一直是不少朋友孜孜以求的目标.根据中华英才网统计数据,北京地区 Lin ...

  2. AndroidのActivity启动模式

    Activity启动模式      .概念      Activity启动模式定义了Activity启动的规则,它决定着Activity的实例创建与重用与否    .属性     Activity的启 ...

  3. OE_ORDER_PUB.PROCESS_ORDER to Release a hold on sales order in R12

    PURPOSE: This post is to provide a sample script to Release a hold on sales order using an API OE_OR ...

  4. oracle如何查询哪个表数据量大

  5. mac远程链接 windows

    https://bbs.feng.com/read-htm-tid-10516042.html 一.利用电脑系统自带的远程(喜欢懒人版的方法,或者小白用户,可以跳过这个方法看下一个) 1.打开mac, ...

  6. OpenCV平面物体检测

    平面物体检测 这个教程的目标是学习如何使用 features2d 和 calib3d 模块来检测场景中的已知平面物体. 测试数据: 数据图像文件,比如 “box.png”或者“box_in_scene ...

  7. 流畅的python第十一章接口学习记录

    鸭子协议(忽略对象真正类型,转而关注对象有没有实现所需的方法,签名和语义) 标准库中的抽象基类 collections.abc模块中的抽象基类 抽象方法是抽象基类中用来强制子类必须实现的方法,如果子类 ...

  8. solr 自聚类实现

    参考官网:https://lucene.apache.org/solr/guide/6_6/result-clustering.html 最近用到solr自聚类的,先简单介绍如下: 1.配置文件 主要 ...

  9. YARN Application执行流程

    原文见  http://xiguada.org/yarn-application_run/ 本节简单描述了一个Application在YARN上的执行流程,希望对初识YARN的同学提供一些帮助. 图1 ...

  10. 假设这篇文章也能訪问过万,我的那些朋友就是SB

    能和我这个疯子交朋友的一定是神经病