博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
再也不用担心this指向的问题了
阅读量:6422 次
发布时间:2019-06-23

本文共 2160 字,大约阅读时间需要 7 分钟。

某日,跟公司大牛交流学习进步的方法,大牛说:要善于总结,技术总结很重要。于是自己想动手写点东西,总结一下自己近期学到的一些技术点,踩到的坑,也算是对自己一个技术复盘与总结。(作者表达能力一般,可能有表达错误或不准确的地方,欢迎纠正与交流。第一次写,有点小激动0.0)。

在工作中或面试过程中,经常会碰到有关this指向的问题,似曾相识的场景,却总是被混淆分不清,中了面试官的套路。这段时间作者研究了下,简单总结一波

1,默认规则。举个栗子,代码如下:

var name = '小明';function print() {    console.log(this.name);  // '小明'    console.log(this);   //window对象}print();  复制代码

这里我们看到打印出来的是小明,this.name被解析成了全局对象,this指向的是window对象。why?为什么this会指向window呢,因为在本例中,函数调用时应用了this的默认绑定原则,因此this指向的是全局对象。那我们怎么判断当前应用了默认绑定呢,我们可以通过函数的调用位置来判断,我们发现print函数是直接调用的,不经过任何修饰。因此只能使用默认绑定,无法使用其他原则

2,隐式绑定

function foo() {    console.log(this.a)}var obj = {    a:2,    foo:foo}obj.foo()  // 2复制代码

这里我们看到foo函数的调用者是obj对象,此时this绑定到了obj上,所以this.a输出的是obj.a。这种情况称之为隐式绑定:当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象。好,这个时候我们应该对隐式绑定有个大概的了解,那当函数有多个引用的时候会怎么样呢?让我们来看一道题:

var obj = {   a:1,   foo:function() {       console.log(this.a)   }}var obj1 = {    a:2,    obj:obj}obj1.obj.foo()  // 1复制代码

我们看到这种情况下this指向的是最后一层的对象上,即obj上。隐式绑定一定都是这样的吗,答案式否定的,这里面有一个坑:有些时候会发生隐式绑定丢失的情况。让我们来举例说明:

var a = 'hello world';function foo(){    console.log(this.a)}var obj = {    a:1,    foo:foo}var print = obj.foo;print();    // hello world复制代码

这里我们发现隐式绑定规则失效了,this.a输出的不是1,而是全局对象上的a。这又是怎么回事呢?其实print,obj.foo都是函数的引用。直接调用print函数式,相当于直接调用foo函数,是不是很熟悉呢?没错,是默认绑定,所以此时this指向的是window。所以说我们在判断是否是隐式绑定的时候需要仔细些,分清楚情况。

3,显示绑定

何为显示绑定?利用call(),apply(),bind()强制绑定this指向的我们称之为显示绑定。举个栗子:

function foo() {    console.log(this.a);}var obj = {    a:1}foo.call(obj);  // 1复制代码

这里我们看到通过call方法将this强制绑定到了对象obj上。利用bind()函数绑定this的做法我们又称之为硬绑定,硬绑定之后当前函数的this指向无法再修改,举个栗子:

var a = 'hello world';function foo() {    console.log(this.a);}var obj = {    a:1}var print = foo.bind(obj);print();    // 1// 利用call方法强制将this绑定在window上,但是失败了,this还是指向objprint.call(window);   // 1复制代码

call(),apply(),bind()这三个函数有什么区别,这里就不一一阐述了,有兴趣的同学可以去了解下。

4,new绑定

这个相信大家平时编程时会遇到过很多次,这里简单说明下,如下:

function Person(name) {    this.name = name;}var p = new Person('小明');console.log(p.name);    // 小明复制代码

这种情况我们称之为new绑定。

this绑定的四种基本规则我们基本弄清楚了,那么它们的优先级是什么样的呢?这里我们直接给出结论,不在一一举例对比说明了,有兴趣的同学可以自己举例对比下。优先级:new绑定 > 显示绑定 > 隐式绑定 > 默认绑定。我们在判断this指向的时候可以按照这个优先级顺序来判断,绝大部分情况都可以适用。

参考文献:《你不知道的JavaScript》,很nice的一本书!复制代码

转载地址:http://njgra.baihongyu.com/

你可能感兴趣的文章
dreamweaver中的 map怎么调用?_制作热点图像区域
查看>>
代码19
查看>>
Win10系列:UWP界面布局进阶5
查看>>
ABP Zero 本地化语言的初始化和扩展
查看>>
转Hibernate 一对多关联的CRUD__@ManyToOne(cascade=(CascadeType.ALL))
查看>>
FCT需求分析
查看>>
开门人和关门人(杭电1234)
查看>>
万能adapter
查看>>
开发指南专题六:JEECG微云高速开发平台代码生成
查看>>
cocos2d-x 游戏优化方案
查看>>
1.3 Quick Start中 Step 6: Setting up a multi-broker cluster官网剖析(博主推荐)
查看>>
remote desktop connection manager
查看>>
开源库RxJava、ButterKnife
查看>>
JDK内置工具jstack(Java Stack Trace)(转)
查看>>
百度之星 / 初赛第二场 B题
查看>>
Http压测工具wrk使用指南
查看>>
Excel VBA 循环“我中毒了~”
查看>>
CSS 教程Part4 [盒子模型](摘录自 W3C School)
查看>>
android开发技巧
查看>>
五个有趣的拓扑变换问题 [转]
查看>>