摘要:由于匿名函数的作用域是全局性的,因此闭包的通常指向全局对象调用返回值为而不是我们预期的,在闭包中函数作为某个对象的方法调用时,要特别注意,该方法内部匿名函数的指向的是全局变量。
有人的地方就有江湖,有函数的地方就有this。而this在不同的环境下,又表现为不同的形式,难免让人有种此this非彼this的疑惑
在java等面向对象的语言中,this指的就是当前对象,而在javascript中这就不灵了,javascript中this是在编译期动态绑定的,这就形成了一把双刃剑:足够灵活却又容易让人迷惑。在javascript中this可以是全局对象、当前对象甚至任意对象(obj.call(this))。
我们通过函数的几种不同调用方式来看一下各自this的意义:
在javascript中函数也是个对象,因此,函数可以作为一个对象的属性出现:
var object = { name:"jeffie", sayWhat:function(){ console.log(this.name + ":hello"); //jeffie:hello } } object.sayWhat();
此处的this指向object对象,也就是函数所在的对象。
作为函数调用当函数直接被调用时,此时函数中的this指向全局变量,也就是window对象:
function obj(){ console.log(this); } obj();//Window构造函数中的this
在作为构造函数调用时,this指向的是新生成的实例对象:
function Plugin(name,type){ this.name = name; this.type = type; } var plugin = new Plugin("core",1); console.log(plugin.name);//core使用apply或者call调用
javascript中每个函数都包含两个方法:apply()和call(),这两个方法非常强大,它们可以切换函数的上下文执行环境,也就是说可以修改this绑定的对象。简单来说,这两个方法可以用来设置函数的this,两个方法都接收两个参数,第一个参数是运行函数的作用域,第二个参数是参数对象,唯一的区别是apply第二个参数为参数数组(Array或者arguments):
function Plugin(name,type){ this.name = name; this.type = type; this.debugs = function(name,type){ console.log(this); //Object {name: "base", type: 3} } } var plugin1 = new Plugin("core",1); var plugin2 = {name:"base",type:3}; console.log(plugin1.debugs.call(plugin2));
通过上面的示例可以看出this值不再指向Plugin对象了,而是指向了plugin2的对象。
闭包中使用this通常我们理解this对象是运行时基于函数绑定的,全局函数中this对象就是window对象,而当函数作为对象中的一个方法调用时,this等于这个对象。由于匿名函数的作用域是全局性的,因此闭包的this通常指向全局对象window:
var scope = "global"; var object = { scope:"local", getScope:function(){ return function(){ return this.scope; } } }
调用object.getScope()()返回值为global而不是我们预期的local,在闭包中函数作为某个对象的方法调用时,要特别注意,该方法内部匿名函数的this指向的是全局变量。参考上一篇闭包
这属于 JavaScript 的设计缺陷,正确的设计方式是内部函数的 this 应该绑定到其外层函数对应的对象上,为了规避这一设计缺陷,聪明的 JavaScript 程序员想出了变量替代的方法,只需要把外部函数作用域的this存放到一个闭包能访问的变量里面即可,约定俗成,该变量一般被命名为 that:
var scope = "global"; var object = { scope:"local", getScope:function(){ var that = this; return function(){ return that.scope; } } } object.getScope()()返回值为local。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/87605.html
摘要:下面是用实现转成抽象语法树如下还支持继承以下是转换结果最终的结果还是代码,其中包含库中的一些函数。可以使用新的易于使用的类定义,但是它仍然会创建构造函数和分配原型。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第 15 篇。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是...
摘要:到底是什么函数被调用时的位置是动态的箭头函数不在此范围,因为它的是函数定义时的上下文,是静态的判断规则如果是在中调用,则为新创建的对象通过,调用,是之前定的对象第一个参数注意若第一个参数是,则执行第四条判断规则在么某个上下文中调用,是该上下 this到底是什么? 函数被调用时的位置(是动态的!)(箭头函数不在此范围,因为它的this是函数定义时的上下文,是静态的!) 判断规则 1.如果...
摘要:插件开发前端掘金作者原文地址译者插件是为应用添加全局功能的一种强大而且简单的方式。提供了与使用掌控异步前端掘金教你使用在行代码内优雅的实现文件分片断点续传。 Vue.js 插件开发 - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins译者:jeneser Vue.js插件是为应用添加全局功能的一种强大而且简单的方式。插....
普通函数的this指向 简单说说 首先,按照惯例,我们先举个栗子: var bar = 2; function foo() { this.bar = 1; this.getBar = function() { console.log(this.bar); } } var test = new foo(); var getBar = test.getBar; test.getB...
摘要:将对象的属性拷贝到了对象,合并成一个新的对象。而这种行为也是新增的标准。总结本章讲解了对象字面量语法拓展,新增方法,允许重复的对象字面量属性,自有枚举属性排序,增强对象原型,明确了方法的定义。但是,就算把全部新增的功能记住也不是难事。 变量功能被加强了、函数功能被加强了,那么作为JavaScript中最普遍的对象,不加强对得起观众吗? 对象类别 在ES6中,对象分为下面几种叫法。(不需...
阅读 1477·2021-11-18 10:02
阅读 1622·2021-09-04 16:40
阅读 3148·2021-09-01 10:48
阅读 851·2019-08-30 15:55
阅读 1830·2019-08-30 15:55
阅读 1341·2019-08-30 13:05
阅读 2996·2019-08-30 12:52
阅读 1597·2019-08-30 11:24