什么是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在回调函数中经常使用到。

參考资料: 
理解 JavaScript 中的 Function.prototype.bind 
js中bind、call、apply函数的使用方法 
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

转载:https://www.cnblogs.com/blfbuaa/p/7110641.html

用bind方法保持this上下文的更多相关文章

  1. 【转载】JS中bind方法与函数柯里化

    原生bind方法 不同于jQuery中的bind方法只是简单的绑定事件函数,原生js中bind()方法略复杂,该方法上在ES5中被引入,大概就是IE9+等现代浏览器都支持了(有关ES5各项特性的支持情 ...

  2. javascript中利用柯里化函数实现bind方法

    柯理化函数思想:一个js预先处理的思想:利用函数执行可以形成一个不销毁的作用域的原理,把需要预先处理的内容都储存在这个不销毁的作用域中,并且返回一个小函数,以后我们执行的都是小函数,在小函数中把之前预 ...

  3. 如何在JavaScript中正确引用某个方法(bind方法的应用)

    在JavaScript中,方法往往涉及到上下文,也就是this,因此往往不能直接引用,就拿最常见的console.log("info…")来说,避免书写冗长的console,直接用 ...

  4. js的bind方法

    转载:http://www.jb51.net/article/94451.htm http://www.cnblogs.com/TiestoRay/p/3360378.html https://seg ...

  5. JS 的 call apply bind 方法

    js的call apply bind 方法都很常见,目的都是为了改变某个方法的执行环境(context) call call([thisObj[,arg1[, arg2[,   [,.argN]]]] ...

  6. JS中的bind方法学习

    EcmaScript5给Function扩展了一个方法:bind 众所周知 在jQuery和prototype.js之类的框架里都有个bind jQuery里的用途是给元素绑定事件 $("# ...

  7. Javascript中bind()方法的使用与实现

    对于bind,我愣了下,这个方法常用在jquery中,用于为被选元素添加一个或多个事件处理程序. 查了下手册,发现bind的作用和apply,call类似都是改变函数的execute context, ...

  8. JS中的call、apply、bind方法

    JS中的call.apply.bind方法 一.call()和apply()方法 1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[,   [,.argN]]] ...

  9. javascript中函数的call,apply及bind方法

    call 方法调用一个对象的一个方法,以另一个对象替换当前对象.call([thisObj[,arg1[, arg2[,  [,.argN]]]]])参数thisObj可选项.将被用作当前对象的对象. ...

随机推荐

  1. windows下redis安装及应用

    一.下载安装Redis(windows版本) 1.下载地址:https://github.com/MicrosoftArchive/redis/releases 2.安装: 1)打开运行窗口,输出cm ...

  2. 【新题】ocp 062 2019年考试新题-3

    3.A database is open read write and the instance has multiple sessions some of which have active tra ...

  3. django Form的回顾--手动档和自动挡

      from django.shortcuts import renderfrom django.forms import Formfrom django.forms import fieldsfro ...

  4. PHP 单点登录实现方案

    单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任.单点登录在大型网站里使用得 ...

  5. Alamofire源码导读四:统计信息

     时间顺序如上图: self.latency = initialResponseTime - requestStartTime self.requestDuration = requestCompl ...

  6. How to manage IntelliJ IDEA projects under Version Control Systems

    如何在版本控制系统中管理 IntelliJ IDEA 项目文件 IntelliJ IDEA 设置详细,功能强大.在实际工作中,我们有时会遇到跟同事共享项目文件的情况. 那么,有哪些项目文件应该加入到版 ...

  7. diskpart 格式化u盘 制作u盘启动盘方法

    1.cmd 2.diskpart 3.list disk 4.select disk [index]   注:[index] 磁盘索引号 5.clean 6.create partition prim ...

  8. Java之集合(二十六)ConcurrentSkipListMap

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7542578.html 1.前言 一个可伸缩的并发实现,这个map实现了排序功能,默认使用的是对象自身的compa ...

  9. Java之集合(七)Map

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7327216.html 1.前言 按照顺序,本章本是要对Set的相关类进行介绍及讲解的.但是对于其实现有所了解的都 ...

  10. python——利用selenium模仿键盘输入跳转

    这是我以前遇到的一个网站:人卫临床助手,这个网站比较奇怪,不能点击右键查看源码,但是大家可以使用ctrl+U,打开开发者选项,点击network,然后点击第2页和第3页: 可以看到上面的URL是一模一 ...