在学习javascript中我们往往会被this的指向问题弄的头昏转向,今天我们就来学习一下this的指向问题,和改变this指向的方法。

一.this的指向问题

在学习this的指向问题之前我们需要明白两点:

1:this永远指向一个对象;

2:this的指向完全取决于函数调用的位置;

针对上面第一点我们能很好理解,因为在javascript中一切都是对象。第二点其实也是好理解,当函数调用的位置不同是,this的指向的对象就不同,所以可以说this的指向可以动态变换的,下面我们先通过一个简单的例子来看一下this的指向是变换的

<script>
function fun(){
console.log(this.name); }
var change={
name:'hello',
f:fun
}
var name ='world'
var result=change.f()//hello
fun();//world
</script>

通过上述例子我们可以很清楚的看到this的指向的变化,因为有一个函数在对象change里面,所以this就是指向的函数外部的对象,所以输出了hello。

想必看完上述例子后大家对this的动态指向切换有了一定的了解。

那么接下来,我们对this使用最频繁的几种情况做一个总结,最常见的基本就是以下3种:

对象中的方法,事件绑定 ,构造函数 ,定时器

前两个就不必多说了,我们看一下定时器中的this指向问题,

var obj = {
fun:function(){
this ;
}
}

setInterval(obj.fun,1000); // this指向window对象
setInterval('obj.fun()',1000); // this指向obj对象

setInterval() 是window对象下内置的一个方法,接受两个参数,第一个参数允许是一个函数或者是一段可执行的 JS 代码,第二个参数则是执行前面函数或者代码的时间间隔;

在上面的代码中,setInterval(obj.fun,1000) 的第一个参数是obj对象的fun ,因为 JS 中函数可以被当做值来做引用传递,实际就是将这个函数的地址当做参数传递给了 setInterval 方法,换句话说就是 setInterval 的第一参数接受了一个函数,那么此时1000毫秒后,函数的运行就已经是在window对象下了,也就是函数的调用者已经变成了window对象,所以其中的this则指向的全局window对象;

而在 setInterval('obj.fun()',1000) 中的第一个参数,实际则是传入的一段可执行的 JS 代码;1000毫秒后当 JS 引擎来执行这段代码时,则是通过 obj 对象来找到 fun 函数并调用执行,那么函数的运行环境依然在 对象 obj 内,所以函数内部的this也就指向了 obj 对象;

除了这些我们还需要理解三个可以改变this指向的函数,包括箭头函数,call(),apply()

箭头函数:官方有解释,箭头函数引入的其中一个原因,就是其不绑定this;在箭头函数中,箭头函数的this被设置为封闭的词法环境的,换句话说,箭头函数中的this取决于该函数被创建时的环境。

var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true


// 接着上面的代码
// 作为对象的一个方法调用
var obj = {foo: foo};
console.log(obj.foo() === globalObject); // true // 尝试使用call来设定this
console.log(foo.call(obj) === globalObject); // true // 尝试使用bind来设定this
foo = foo.bind(obj);
console.log(foo() === globalObject); // true

无论如何,foo 的 this 被设置为他被创建时的环境(在上面的例子中,就是全局对象)。这同样适用于在其他函数内创建的箭头函数:这些箭头函数的this被设置为封闭的词法环境的。

// 创建一个含有bar方法的obj对象,
// bar返回一个函数,
// 这个函数返回this,
// 这个返回的函数是以箭头函数创建的,
// 所以它的this被永久绑定到了它外层函数的this。
// bar的值可以在调用中设置,这反过来又设置了返回函数的值。
var obj = {
bar: function() {
var x = (() => this);
return x;
}
}; // 作为obj对象的一个方法来调用bar,把它的this绑定到obj。
// 将返回的函数的引用赋值给fn。
var fn = obj.bar(); // 直接调用fn而不设置this,
// 通常(即不使用箭头函数的情况)默认为全局对象
// 若在严格模式则为undefined
console.log(fn() === obj); // true // 但是注意,如果你只是引用obj的方法,
// 而没有调用它
var fn2 = obj.bar;
// 那么调用箭头函数后,this指向window,因为它从 bar 继承了this。
console.log(fn2()() == window); // true
call和apply方法:将一个对象作为call或者apply的第一个参数,this将会被绑定到这个参数对象上
var obj = {parent:'男'};
var parent = '28';
function child(obj){
console.log(this.parent);
}
child(); // 28
child.call(obj); //男
child.apply(obj); //男

Javasript中this指向问题和改变this指向的方法的更多相关文章

  1. JS中this指向问题和改变this指向

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  2. this的指向问题及改变this指向

    概念: this是运行环境下的一个系统变量, 由于this在不同的执行环境下有不同的值, 所以在使用this时,多加注意 (使用this之前,先打印) 1,在全局作用域下,this默认指向window ...

  3. js中改变this指向的call、apply、bind 方法使用

    前言: 由于js 中this的指向受函数运行环境的影响,指向经常改变,使得开发变得困难和模糊,所以在封装sdk,写一些复杂函数的时候经常会用到this 指向绑定,以避免出现不必要的问题,call.ap ...

  4. 前端js中this指向及改变this指向的方法

    js中this指向是一个难点,花了很长时间来整理和学习相关的知识点. 一. this this是JS中的关键字, 它始终指向了一个对象, this是一个指针; 参考博文: JavaScript函数中的 ...

  5. ES5中改变this指向的三种方法

    ES5中提供了三种改变函数中this指针指向的方法,分别如下 1.call() var obj = {username:"孙悟空"}; //没有任何修饰的调用函数,函数中的this ...

  6. js中this绑定方式及如何改变this指向

    this的绑定方式基本有以下几种: 隐式绑定 显式绑定 new 绑定 window 绑定 箭头函数绑定 隐式绑定 第一个也是最常见的规则称为 隐式绑定. var a = { str: 'hello', ...

  7. 可以改变this指向的方法

    this一般指向的是当前被调用者,但也可以通过其它方式来改变它的指向,下面将介绍三种方式: 1.call用作继承时: function Parent(age){ this.name=['mike',' ...

  8. call()与apply() 改变this指向

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Consolas; color: #a5b2b9 } span.Apple-tab-span ...

  9. this指向及改变this指向的方法

    一.函数的调用方式决定了 this 的指向不同,但总的原则,this指的是调用函数的那个对象: 1.普通函数调用,此时 this 指向 全局对象window function fn() { conso ...

随机推荐

  1. 【题解】SP10570 【LONGCS - Longest Common Substring】

    \(\color{Red}{Link}\) \(\text{Solution:}\) 还是\(\text{Suffix Tree.}\) 根据\(\color{Blue}{Link}\)我们可以得到一 ...

  2. 【CSP2019-J】游记

    看我朋友们的博客里面都写了游记,我也来凑个热闹(雾) day1# 介于是\(CSP-J\),我们是比赛当天走的,上午卡点到.一路上不允许玩游戏,于是就在路上看了一路的鬼畜视频,然后看了看对拍的板子(然 ...

  3. MQTT消息队列压力测试

    环境准备: jmeter插件下载:mqttxmeter1.0.1jarwithdependencies.jar 把MQTT插件放在 %JMeter_Home%/lib/ext下.重启jmeter. M ...

  4. 九、Python+Selenium模拟登录

    研究QQ登录规则的话,得分析大量Javascript的加密解密,比较耗时间.自己也是练习很少,短时间成功不了.所以走了个捷径. Selenium是一个WEB自动化测试工具,它运行时会直接实例化出一个浏 ...

  5. Pock 把 Touch Bar 变成系统中的 Dock 栏

    Pock 把 Touch Bar 变成系统中的 Dock 栏 Pock 是一款 macOS App,你可以通过它把 Touch Bar 变成系统中的 Dock 栏,直接用来切换和启动 App,尽享全屏 ...

  6. vs code个性化设置

    文件=>首选项=>设置,直接在搜索栏搜索有背景色的部分即可 1. 鼠标滚轮缩放 "editor.mouseWheelZoom": true 2. 显示空格和tab符号 ...

  7. Celery---一个懂得异步任务,延时任务,周期任务的芹菜

    Celery是什么? celey是芹菜 celery是基于Python实现的模块,用于执行异步延时周期任务的 其结构组成是由 1.用户任务 app 2.管道任务broker用于存储任务 官方推荐red ...

  8. 习题3-5 谜题(Puzzle, ACM/ICPC World Finals 1993, UVa227)

    #include<stdio.h> #include<string.h> char s[5][5]; int main() { while(gets(s[0])) { int ...

  9. k8s-获取kuboardtoken

    master节点执行命令 echo $(kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep kub ...

  10. centos8平台使用strace跟踪系统调用

    一,strace的用途 strace  是最常用的跟踪进程系统调用的工具. 说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectfore ...