this上下文一致
什么是this对象
先来说说什么是this对象吧,每个函数在调用的时候都会自动获取两个特殊变量:this和arguments对象。this值具体是指哪个对象是和该函数的执行环境相关的。如果是作为对象的方法,那么this就是对象实例本身;如果是一个全局函数,那么this就是window对象。用一句话来概括,this就是调用这个方法的对象。
保持this上下文
有时候,我们需要保持this的上下文,也就是在一个执行环境中想要访问到另一个执行环境的this值。在什么时候需要这么做呢?比如说将一个对象的方法赋值给了一个全局变量,然后在全局变量中调用这个方法,那么this值就不再是原来的对象而是window对象了,然而可能我们仍需要在全局环境中按照对象的方法来调用。又比如说一个方法中包含了闭包,闭包是无法访问到其外部函数的this对象的,因为this对象是在调用方法的时候自动生成,内部函数在搜索这两个变量的时候只会搜索到其自身的活动对象,而不会沿着作用域链往外搜索,所以闭包访问不到外部函数的this值。如果要想访问,就应该想办法把this值传递下去。
通常可以通过这样的方式保持this上下文:在外部函数中将this缓存到一个变量中,通常变量名称使用self, _this 或者 context,那么闭包就可以通过这个可访问的变量来获取外部函数的this值,this上下文得以保持。比如下面的代码:
var myObj = {
specialFunction: function () {},
getAsyncData: function (cb) {
cb();
},
render: function () {
var that = this;
this.getAsyncData(function () {
that.specialFunction();
});
}
};
myObj.render();
这里有一个对象myObj,它有一个render实例方法,在这个方法内部又调用了它的另一个实例方法getAsyncData,而这个方法有一个新的函数作为参数,这个函数相当于是一个闭包,是不能获取到外部函数中的this值的,为了在这个闭包中也能访问实例方法,需要获取到外部环境的this值,这里把this(this为调用render方法的对象,即实例对象myObj)缓存到了变量that中。
此外还可通过bind方法,这就是本文所要讲述的重点。
bind方法
bind方法生成了一个新的函数,称为绑定函数,传入bind方法的第一个参数作为这个绑定函数的this对象,传入bind的第二个参数连同后面调用绑定函数时传入的参数按照先后顺序(传入bind的在前)构成绑定函数的参数。
现在我们把上面的例子修改一下:
render: function () {
this.getAsyncData(function () {
this.specialFunction();
}.bind(this));
}
.bind()创建了一个函数,当这个函数在被调用的时候,它的 this 关键词会被设置成被传入的值(这里指调用bind()时传入的参数)
再看一个bind的使用例子:
var foo = {
x: 3
}
var bar = function(){
console.log(this.x);
}
bar();
// undefined
var boundFunc = bar.bind(foo);
boundFunc();
// 3
将bar方法和foo对象绑定后,bar中的this对象被替换为了foo,并生成了一个新的函数boundFunc,因此在全局环境中调用boundFunc时,也可以访问到foo对象的属性。
还可以了解一下Function.prototype.bind()内部是什么样的:
Function.prototype.bind = function (scope) {
var fn = this;//this是调用bind方法的对象(别的方法对象)
return function () {
return fn.apply(scope);//把fn环境中的this替换为scope
};
}
可看出,bind方法返回了一个新的函数,这个方法返回了原方法(调用bind的方法)通过apply修改作用域(传入的参数scope)后的执行结果。如果调用这个新函数则会立即执行fn.apply(scope),并返回执行后的结果。
fn.bind()
与call、apply的区别
call、apply是修改函数的作用域,并且立即执行,而bind是返回了一个新的函数,不是立即执行,即call and apply call a function while bind creates a function。bind在回调函数中常用到。
this上下文一致的更多相关文章
- 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 如何一步一步用DDD设计一个电商网站(七)—— 实现售价上下文
阅读目录 前言 明确业务细节 建模 实现 结语 一.前言 上一篇我们已经确立的购买上下文和销售上下文的交互方式,传送门在此:http://www.cnblogs.com/Zachary-Fan/p/D ...
- 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文
阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...
- CSS——关于z-index及层叠上下文(stacking context)
以下内容根据CSS规范翻译. z-index 'z-index'Value: auto | <integer> | inheritInitial: autoApplies to: posi ...
- EF上下文对象线程内唯一性与优化
在一次请求中,即一个线程内,若是用到EF数据上下文对象,就创建一个,这也加是很多人的代码中习惯在使用上下文对象时,习惯将对象建立在using中,也是为了尽早释放上下文对象, 但是如果有一个业务逻辑调用 ...
- 【.NET深呼吸】基于异步上下文的本地变量(AsyncLocal)
在开始吹牛之前,老周说两个故事. 第一个故事是关于最近某些别有用心的人攻击.net的事,其实我们不用管它们,只要咱们知道自己是.net爱好者就行了,咱们就是因为热爱.net才会选择它.这些人在这段时间 ...
- 【.NET深呼吸】应用上下文(AppContext)
在.net 4.6中新增了一个类,叫AppContext,这个家伙嘛,技术含量不算高,只不过是在编程的时候可以方便用用而已.应用上下文允许定义一个标识(用字符串表示),并且在应用程序运行期间可以切换状 ...
- Javascript的“上下文”(context)
一:JavaScript中的“上下文“指的是什么 百科中这样定义: 上下文是从英文context翻译过来,指的是一种环境. 在软件工程中,上下文是一种属性的有序序列,它们为驻留在环境内的对象定义环境. ...
- IDDD 实现领域驱动设计-理解限界上下文
上一篇:<IDDD 实现领域驱动设计-理解领域和子域> <实现领域驱动设计>前两章内容,基本上读完了,和<领域驱动设计>不同的是,它把很多的概念都放在前面进行讲述了 ...
- IDDD 实现领域驱动设计-上下文映射图及其相关概念
上一篇:<IDDD 实现领域驱动设计-理解限界上下文> 距离上一篇有几天时间了,<实现领域驱动设计>第三章的内容都是围绕一个词-上下文映射图,我大概断断续续看了几天,总共看了两 ...
随机推荐
- sql server外网复制+非默认端口
注意查看服务器名称,这出来的是什么,就必须要在别名上写什么,如果不一样,请参照 :修改计算机名 SELECT @@SERVERNAME as InstalledName, SERVERPROPERTY ...
- elasticsearch中文分词器ik-analyzer安装
前面我们介绍了Centos安装elasticsearch 6.4.2 教程,elasticsearch内置的分词器对中文不友好,只会一个字一个字的分,无法形成词语,别急,已经有大拿把中文分词器做好了, ...
- 如何将wordpress所有文章批量改为已发布状态
用wordpress建站的一个好处就是bd站长工具平台上有数据结构插件,可以认为bd默认支持wp发展,另外一种建站程序是discuz.我们在用wordpress发布文章时,特别是那种多用户投稿的文章一 ...
- 20170811 JQuery基础知识学习记录(一)
基本写法 $(selector).action() $(this).hide() - 隐藏当前元素 $("p").hide() - 隐藏所有 <p> 元素 $(&quo ...
- Vagrant测试
载新的BOX实现虚拟机恢复.效果如下:(可用linux命令操作,但是很多时候我们还是需要图形化界面,不然不利于开发代码编写) 参考PDF中的记录网址http://www.vagrantbox.es/ ...
- Python3学习之路~3.3 内置函数
Python内置函数表: 内置参数详解:https://docs.python.org/3/library/functions.html?highlight=built#ascii 用法: #Auth ...
- 客户机容易随机出现自动重启、游戏卡问题?不妨优化下BIOS中节能技术!
相信一些玩主板超频的人都知道,给CPU加电压能够提升CPU的处理速度,很多超频爱好者通过采购超频性能较好,且价格较低的主板和CPU来玩超频,并且通过一些参数的问题能让屌丝设备发挥出高富帅的性能.但是玩 ...
- vue 点击当前的标签,获取当前标签的value值
点击当前的标签,获取当前标签的value值 html <p class="title" v-for="(item, i) in items" :key=& ...
- spark on yarn任务提交缓慢解决
1.为什么要让运行时Jar可以从yarn端访问spark2以后,原有lib目录下的大JAR包被分散成多个小JAR包,原来的spark-assembly-*.jar已经不存在 每一次我们运行的时候,如果 ...
- Linux命令:lsof
简介 lsof(list open files)是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以如传输控 ...