什么是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上下文一致的更多相关文章

  1. 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  2. 如何一步一步用DDD设计一个电商网站(七)—— 实现售价上下文

    阅读目录 前言 明确业务细节 建模 实现 结语 一.前言 上一篇我们已经确立的购买上下文和销售上下文的交互方式,传送门在此:http://www.cnblogs.com/Zachary-Fan/p/D ...

  3. 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文

    阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...

  4. CSS——关于z-index及层叠上下文(stacking context)

    以下内容根据CSS规范翻译. z-index 'z-index'Value: auto | <integer> | inheritInitial: autoApplies to: posi ...

  5. EF上下文对象线程内唯一性与优化

    在一次请求中,即一个线程内,若是用到EF数据上下文对象,就创建一个,这也加是很多人的代码中习惯在使用上下文对象时,习惯将对象建立在using中,也是为了尽早释放上下文对象, 但是如果有一个业务逻辑调用 ...

  6. 【.NET深呼吸】基于异步上下文的本地变量(AsyncLocal)

    在开始吹牛之前,老周说两个故事. 第一个故事是关于最近某些别有用心的人攻击.net的事,其实我们不用管它们,只要咱们知道自己是.net爱好者就行了,咱们就是因为热爱.net才会选择它.这些人在这段时间 ...

  7. 【.NET深呼吸】应用上下文(AppContext)

    在.net 4.6中新增了一个类,叫AppContext,这个家伙嘛,技术含量不算高,只不过是在编程的时候可以方便用用而已.应用上下文允许定义一个标识(用字符串表示),并且在应用程序运行期间可以切换状 ...

  8. Javascript的“上下文”(context)

    一:JavaScript中的“上下文“指的是什么 百科中这样定义: 上下文是从英文context翻译过来,指的是一种环境. 在软件工程中,上下文是一种属性的有序序列,它们为驻留在环境内的对象定义环境. ...

  9. IDDD 实现领域驱动设计-理解限界上下文

    上一篇:<IDDD 实现领域驱动设计-理解领域和子域> <实现领域驱动设计>前两章内容,基本上读完了,和<领域驱动设计>不同的是,它把很多的概念都放在前面进行讲述了 ...

  10. IDDD 实现领域驱动设计-上下文映射图及其相关概念

    上一篇:<IDDD 实现领域驱动设计-理解限界上下文> 距离上一篇有几天时间了,<实现领域驱动设计>第三章的内容都是围绕一个词-上下文映射图,我大概断断续续看了几天,总共看了两 ...

随机推荐

  1. jquery.axios无刷新机制删除

    思路:无刷新机制就是不用的刷新动作 ,用前端html语法删除和后端的数据库删,同时删除达到效果 除操作,来实现无刷洗的方法

  2. 批量查询"_mget"

    1.不同index的批量查询GET /_mget{ "docs":[{ "_index":"test_index1", "_typ ...

  3. 10.6-uC/OS-III内部任务(统计任务 OS_StatTask())

    1.这个任务能够统计总的CPU使用率(0到100%),每个任务的CPU使用率( 0到100%),每个任务的堆栈使用量. 2.统计任务在uC/OS-III中是可选的,当设置OS_CFG.H中的OS_CF ...

  4. 【雅思】【写作】【大作文】Advantage VS. Disadvantage

    Advantage VS. Disadvantage Advantage vs. Disadvantage 社会现象或者做法 “People can work or study on the Inte ...

  5. CentOS 系列安装 Docker

    CentOS6对于 CentOS6,可以使用 EPEL 库安装 Docker,命令如下$ sudo yum install http://mirrors.yun-idc.com/epel/6/i386 ...

  6. MySQL 5.7 的SSL加密方法

    MySQL 5.7 的SSL加密方法 MySQL 5.7.6或以上版本 (1)创建证书开启SSL验证--安装opensslyum install -y opensslopenssl versionOp ...

  7. 以太坊nonce

    以太坊系列(ETH&ETC)在发送交易有三个对应的RPC接口,分别是ethsendTransaction.ethsendRawTransaction和personal_sendTransact ...

  8. Python实现文字聊天室

    你是否想过用所学的Python开发一个图形界面的聊天室程序啊? 像这样的: 如果你想开发这样一个有点怀旧风格的聊天程序,那么可以接着看: 要开发这个聊天程序,你需要具备以下知识点: asyncore ...

  9. Groovy动态解析

    A:前面需要说些什么吗? B:不需要吗? A:需要吗? 解析方式一:通过指定的paths来初始化GroovyScriptEngine //通过指定的paths来初始化GroovyScriptEngin ...

  10. android怎么抓取双向认证https的包

    这里仅提供思路. 第一种方法: dex层面,可以直接用插日志方法,找到app使用的https库,这里以某app为例,使用okhttp, okhttp收发包相关代码: Request request = ...