博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
this的五种指法
阅读量:7093 次
发布时间:2019-06-28

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

this 到底指向哪里

以下如果没提及,则为严格模式。

js中作用域有两种:

  1. 词法作用域
  2. 动态作用域

词法作用域

词法作用域指在书写代码时就被确定的作用域。

看如下代码

var value = 1;    function foo() {        console.log(value);    }    function bar() {        var value = 2;        foo();    }    bar();// 结果是1

动态作用域

动态作用域指在代码运行时才被确定的作用域。

js中只有this的作用域是动态作用域

this的五种绑定

初学js时,会想当然认为this遵循某一条规律,就像物理学那样,然而并不是。

this的绑定分为五种情况,这五种情况之间毫无规律可言。不过好在都很简单。

一. 默认绑定

当以如下形式执行一个函数时,this为默认绑定;

func()
  • 严格模式下,this为undefined
  • 非严格模式下,this是全局对象。

与函数调用嵌套多少层如何嵌套无关

/* 全是undefined */function printThis(){    return this}var obj = {    say(){        console.log('obj.say',printThis())    }}function funcB(){    console.log('funcB',printThis());    obj.say();}console.log('funcA',printThis())obj.say()funcB()

二. 隐式绑定

当以如下行驶执行一个函数时,this为隐式绑定;

a.b.func()

此时this指向前面一个对象

赋值会改变隐式绑定this的指向

  • 方法赋值给变量
class T {    dotInvoke() {        console.log('dotInvoke', this.sayThis())    }    sayThis() {        return this    }    assignInvoke() {        var sayThis = this.sayThis;        console.log('assignInvoke', sayThis())    }}var tt = new T();tt.dotInvoke()// 指向Ttt.assignInvoke()// undefined
  • 函数被赋值成方法
function printThis(){    return this}var obj = {};obj.say = printThis;obj.say()/* 指向obj */
  • 赋值给参数

极为常见的是回调函数的this是undefined,因为回调函数被复制给参数,参数再调用时变成了默认绑定

function asyncFun(cb){    cb()}var obj = {    callback(){        console.log(this)    }}obj.callback()/*隐式绑定 obj */asyncFun(obj.callback);/*默认绑定 undefined */

三. 箭头函数

箭头函数会让this指向最近的函数或全局作用域

  • 与最近的函数的this指向相同
function foo() {        // 返回一个箭头函数        return (a)=>{            //this 继承自 foo()            return this.a        }        ;    }    var obj1 = {        a: 'obj1'    };    var obj2 = {        a: 'obj2'    }    var arrow1 = foo.call(obj1);    var arrow2 = foo.call(obj2);    var arrow3 = foo();    console.log('arrow1',arrow1())/* obj1 */    console.log('arrow2',arrow2())/* obj2 */    console.log('arrow3',arrow3())/* undefined,严格模式下报错 */
  • 指向全局
var printThis = ()=>this;console.log('printThis',printThis());/* global */
  • 指向实例
class Test {    printThis = ()=>{        return this    }}//会被babel翻译成var test = function test() {  var _this = this;  this.printThis = function () {    return _this;  };};

四. 显示绑定

call, apply, bind指定this指向

五. new绑定

构造函数,ES6中的class
new构造函数,new class时,this指向实例

总结

  1. 五种绑定,后面两种情况单一,前面两种会因为方法,函数被赋值而互相转化。
  2. 因为this处于动态作用域,而目前开发时又大量使用框架。我们写下的代码,并不总是由我们自己调用,而是被打包工具打包后,由框架调用。导致我们并不知道我们写下的函数和方法是否被框架复制过或显示绑定过而改变了this指向。以至this指向更加扑朔迷离。
  3. 写完本文顿时觉得,python里指向明确的self完爆js的this。

来源:

转载于:https://www.cnblogs.com/lovellll/p/10225272.html

你可能感兴趣的文章
javascript精度问题与调整
查看>>
《从零開始学Swift》学习笔记(Day 63)——Cocoa Touch设计模式及应用之单例模式...
查看>>
hdu 3342 Legal or Not (拓扑排序)
查看>>
Dubbo限制大数据传输的解决方案
查看>>
ML学习分享系列(2)_计算广告小窥[中]
查看>>
form怎样正确post文件
查看>>
JVM概述
查看>>
artTemplate子模板include
查看>>
C#模拟POST提交表单(一)--WebClient
查看>>
[Spark][python]从 web log 中提取出 UserID 作为key 值,形成新的 RDD
查看>>
数据结构与算法(周鹏-未出版)-第六章 树-6.5 Huffman 树
查看>>
Zephyr的Shell
查看>>
fpga技能树
查看>>
国内的Android SDK镜像
查看>>
Bootstrap系列 -- 36. 向上弹起的下拉菜单
查看>>
TMS320C6455 SRIO 实现方案
查看>>
Hough transform(霍夫变换)
查看>>
background-color
查看>>
提升单元测试体验的利器--Mockito使用总结
查看>>
SVN功能详解
查看>>