网站首页 > 技术文章 正文
在编程语言中,我们都会看到有this的出现,但是JavaScript比较特殊,this在其中的含义与其他语言很不相同
例如在Java中,this一般只会出现在类的方法中,也就是说想使用this需要先创建一个类,同时this表示的就是当前调用的对象
然而在JavaScript中的this表达的含义有很多种,这也使得我们许多前端开发的小伙伴们有点迷惑,从而无法真正的掌握其用法,那么这篇文章就带你一起来学习JavaScript中的this。
JavaScript中的this的绑定规则?
this在执行的上下文中会绑定一个对象,但究竟怎么绑定或者根据什么条件绑定,是有一套规则,我在这里称之为this的绑定规则,在讲述规则之前,先来看一下在网上找到的关于this指向的信息。
通过上面表格中的内容,我们可以大致了解this的指向,但是感觉还是有些迷惑,例如普通函数的调用是都指向window吗?构造函数的this为什么指向的是实例对象?等等...
要想搞清楚这些疑惑,我们必须了解其原理。
首先我们为什么要使用this?使用this有什么好处?
我们可以来看一下两段代码
看上去下边的代码只是比上边多了this的使用,但是上边的代码依旧可以正常执行,从某些角度来说,开发中如果没有this,也是有很多解决方案的,看似这样的调用是没有问题的,但是存在一些弊端。
在实际开发中我们的业务代码可能会有上百行或者上千行,当我们想要修改或者复用obj对象时,上边的代码需要将每一处的obj做修改,而下边的只需要修改对象名称即可,大大提高了开发效率。
当然this在实际开发中的作用还不止这一点,很多地方都有它的应用,这也是它让人困惑的原因。
this的指向?
this在全局作用域下的指向是什么?
在浏览器环境中,全局作用域下的this指向的是window
在node环境中,全局作用域下this的指向是{}
因为在node环境中没有window,所有的js文件都会被当作一个个单独的模块来执行
加载->编译->放入到一个函数中->通过call来调用该函数执行
感兴趣的小伙伴可以去看一下node的源码,在这里我们就不过度展开了。
我们来说浏览器环境
当我们在全局作用域下输出this时,在浏览器中会打印window。
当我们在全局作用域下定义一个函数并使用不同的方式调用,this的指向完全不同,可见普通函数调用this指向是window的说法并不严谨。
从以上三种结果我们暂时可以总结出四点:
1.函数在调用时,JavaScript会默认给this绑定一个值;
2.this的绑定和函数定义的位置没有关系;
3.this的绑定和函数的调用方式以及调用位置有关系;
this是在函数被执行时绑定的;
当我们知道以上四点后,就可以来学习this的绑定规则。
1.默认绑定
当我们对一个函数进行独立调用时,就会使用默认绑定
通常默认绑定会将window绑定给this
2.隐式绑定
这是一种很常见的调用方式,通过对象进行调用
这时候this会被绑定到该对象上
隐式绑定前提条件:
必须在调用的对象内部有一个对函数的引用,如果没有引用,在调用是就会报错,找不到该函数,正是通过这样的引用间接的将this绑定到这个对象上。
3.显示绑定
在实际开发中如果我们不希望在对象内部包含这个函数的引用,同时有希望使用该对象强制调用,该如何做?
在JavaScript中所有的函数都可以使用call和apply方法(箭头函数除外,这个跟函数的prototype有关,而箭头函数没有protype)。
这两个方法都可以绑定指定参数给this,接受的第一个参数便是要绑定的this。而两者不同在于前者接收的第二个参数为参数列表,后者则是一个数组。
以上代码便是通过call方法将fn函数的this绑定给obj对象
call与apply方法的区别
除了以上那个两种方式,显示绑定规则中还有一项就是bind
bind与call,apply最大的区别在于bind不会调用函数,只负责绑定。
可简单理解为某个函数通过bind绑定this,返回值是一个函数。
4.new绑定
在JavaScript中可以使用new关键字来调用某一个函数,被称之为构造函数。
this会绑定到被创建出来的对象,为什么会是这样?我们就要搞明白,当通过new来调用某一函数时究竟发生了什么?
1.会在内存中开辟一块空间,生成一个新的对象;
2.会将函数的prototype赋值给该对象的__proto__;
3.构造函数内部的this会指向被创建出来的对象;
4.执行函数中的代码;
5.自动返回被创建的对象;
绑定规则的优先级
默认绑定规则优先级最低,显示绑定高于隐式绑定,因为显示绑定是强制性的,new绑定优先级也高于隐式绑定而且高于bind绑定,但是new绑定和call,apply无法同时使用所以不存在谁的优先级更高。
箭头函数
在没有箭头函数之前,我们想使用定时器,并且想在定时器中访问到对象的this,通常会对this做一个转存,因为setTimeout是被强制绑定给window(是由浏览器实现),那如果我们不想转存该如何做?
使用箭头函数
就是如此简单,但这里又引入了另外一个问题,箭头函数this的绑定规则是什么?
箭头函数是不绑定this的,它会沿着自己的作用域向上查找,如果查找到全局作用域还没有找到,就会被绑定为window
以上便是JavaScript中this的绑定规则,希望这篇文章能帮助到正在学习前端开发的小伙伴,加油!!!
猜你喜欢
- 2024-10-16 JS中(a==1 && a==2 && a==3)可以在JavaScript中计算为“true”吗?
- 2024-10-16 JavaScript 的这个难点,毁掉了多少程序员
- 2024-10-16 前端开发之彻底搞懂this指向(前端this指向问题)
- 2024-10-16 JavaScript中的变量声明和作用域(一)
- 2024-10-16 Top 26 JavaScript面试问题和答案
- 2024-10-16 JS 经典实例知识点整理汇总【实践】
- 2024-10-16 苦恼于JavaScript中的reduce函数?五分钟讲透彻
- 2024-10-16 前端基础:JavaScript(前端基础题)
- 2024-10-16 一句话彻底理解JS中的回调(Callback)函数
- 2024-10-16 面试中被问到最多的 19 个 JavaScript 问题
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)