《JavaScript应用程序设计》一一2.5 方法上下文

简介:

本节书摘来华章计算机出版社《JavaScript应用程序设计》一书中的第2章,第2.5节,作者:Eric Elliott 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.5 方法上下文

在JavaScript中,执行函数的方式是在其引用的结尾处追加花括号,下面我们对highPass()函数做略微修改。

function highPass(number, cutoff) {
    cutoff = cutoff || this.cutoff;
    return (number >= cutoff);
}

var filter1 = {
    highPass: highPass,
    cutoff: 5
  },
  filter2 = {
    // No highPass here!
    cutoff: 3
  };

highPass()的入参包含一个必选参数Number与一个可选参数cutoff。如果未传入cutoff,函数会认为自己是作为方法在对象上(filter)调用,会使用对象(filter)中的属性cutoff而非入参cutoff。
普通函数的调用:

test('Invoking a function.', function () {
  var result = highPass(6, 5);

  equal(result, true,
    '6 > 5 should be true.');
});

警告: 一般来说,函数中的this始终是指向全局对象,除非你将函数作为对象的方法执行(使用点语法或者方括号)。所以在做函数调用时,最好先确认其this指向是否正确,以防像属性赋值这样的操作污染全局对象。
方法调用将函数与对象关联起来,像object.methodName()(点语法)、object['method Name']()(方括号语法)都属于方法调用。

test('Invoking a method.', function () {
  var result1 = filter1.highPass(3),
    result2 = highPass.call(filter2, 3),
    result3 = filter1.highPass(6);

  equal(result1, false,
    '3 >= filter1.cutoff should be false.');

  equal(result2, true,
    '3 >= filter2.cutoff should be true.');

  equal(result3, true,
    '6 >= filter1.cutoff should be true.');
});

当你通过点语法调用方法时,在方法中使用this,可以访问到对象的属性。在上例中,将入参与filter对象上的cutoff属性作比较,随后返回false,因为3明显是小于this.cutoff值。请牢记,this值的指向取决于方法在哪一个对象上执行。
在第二个例子中,call()方法(继承自Function.prototype)将highPass()方法代理到了filter2对象上,由于filter2对象中cutoff值是3而不是5,测试依然通过。
确切来说,call()方法存在于每一个函数中,理论上可以使用call()方法让函数在任意对象上进行方法调用,换句话说,它将函数中的this指向了你所指定的对象。方法签名如下:

someMethod.call(context, argument1, argument2, ...);

其中context是你希望this所指向的对象,如果想传入一组数组作为入参,可以使用apply():

someMethod.apply(context, someArray);
Function.prototype.bind()

诚然,call()与apply()方法非常实用,不过使用它们时,你需要格外小心,因为它们所绑定的this上下文指向是临时的,每次调用都需要准确无误地传入,而且时刻得确保this能够在当前函数作用域中访问到。不过每次调用都这么做略显麻烦,特别是在事件监听器中。
bind()方法可以解决这个问题,它用来将函数的this指向与目标对象绑定。bind()方法是JavaScript语言规范中的一门新特性,最开始在Prototype等JavaScript类库中出现,随后在ECMAScript5规范中被标准化,但是老版本的浏览器对它的兼容度不高,你可以考虑自己实现或者采用第三方类库。
bind()方法的使用场景之一,将事件监听器与对象绑定:

var lightbulb = {
    toggle: function toggle() {
      this.isOn = !this.isOn;
      return this.isOn;
    },
    isOn: false
  },
  toggle = lightbulb.toggle,
  lightswitch = document.getElementById('lightswitch');

lightswitch = document.getElementById('lightswitch');
lightswitch.addEventListener('click',
  lightbulb.toggle, false);

上述代码示例很好理解,事件监听器通过addEventListener方法绑定至lightswitch的DOM元素上。那么问题来了,事件监听器中的this指向并不是lightbulb对象,而是点击触发时的DOM元素,所以lightbulb的开关逻辑不会被执行。
打开界面上的开关按钮,lightbulb.isOn的值仍为false。下面来用bind()方法修复这个问题,仅需对toggle的赋值方式做略微修改。
toggle = lightbulb.toggle.bind(lightbulb);
OK,现在lightbulb的开关可以响应来自用户的操作了。

相关文章
|
2月前
|
监控 负载均衡 JavaScript
有哪些有效的方法可以优化Node.js应用的性能?
有哪些有效的方法可以优化Node.js应用的性能?
188 69
|
2月前
|
JavaScript 前端开发
如何减少Node.js应用中的全局变量?
如何减少Node.js应用中的全局变量?
130 43
|
1月前
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法详解
本指南详细介绍在Linux系统中安装和管理Node.js的步骤。首先检查现有环境,包括查看当前版本和清除旧版本;接着通过NodeSource仓库安装最新版Node.js并验证安装结果。推荐使用nvm(Node Version Manager)进行多版本管理,便于切换和设置默认版本。同时,提供常见问题解决方法,如权限错误处理和全局模块迁移方案,以及版本回滚操作,确保用户能够灵活应对不同需求。
118 0
|
1月前
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法
Debian 11更新Node.js主要就是这三种方式,无论你是初涉其中的新手还是找寻挑战的专家,总有一种方式能满足你的需求。现在,你已经是这个
181 80
|
3月前
|
前端开发 搜索推荐 JavaScript
如何通过DIY.JS快速构建出一个DIY手机壳、T恤的应用?
DIY.JS 是一款基于原生 Canvas 的业务级图形库,专注于商品定制的图形交互功能,帮助开发者轻松实现个性化设计。适用于 T 恤、手机壳等多种商品场景。它自带丰富功能,无需从零构建,快速集成到项目中。通过创建舞台、添加模型、定义 DIY 区域和添加素材四个步骤即可完成基础用法。支持在线演示体验,文档详细,易上手。
138 57
|
2月前
|
监控 算法 JavaScript
公司局域网管理视域下 Node.js 图算法的深度应用研究:拓扑结构建模与流量优化策略探析
本文探讨了图论算法在公司局域网管理中的应用,针对设备互联复杂、流量调度低效及安全监控困难等问题,提出基于图论的解决方案。通过节点与边建模局域网拓扑结构,利用DFS/BFS实现设备快速发现,Dijkstra算法优化流量路径,社区检测算法识别安全风险。结合WorkWin软件实例,展示了算法在设备管理、流量调度与安全监控中的价值,为智能化局域网管理提供了理论与实践指导。
86 3
|
3月前
|
存储 JavaScript 前端开发
|
5月前
|
前端开发 JavaScript
有没有方法可以保证在JavaScript中多个异步操作的执行顺序?
有没有方法可以保证在JavaScript中多个异步操作的执行顺序?
145 58
|
3月前
|
JavaScript 前端开发 Java
js 垃圾回收机制的方法
JS回收机制方法讲解
|
4月前
|
JavaScript 前端开发 算法
JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
Array.sort() 是一个功能强大的方法,通过自定义的比较函数,可以处理各种复杂的排序逻辑。无论是简单的数字排序,还是多字段、嵌套对象、分组排序等高级应用,Array.sort() 都能胜任。同时,通过性能优化技巧(如映射排序)和结合其他数组方法(如 reduce),Array.sort() 可以用来实现高效的数据处理逻辑。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

热门文章

最新文章