JavaScript的this机制与箭头函数(一)——this绑定的4种机制

来源:互联网 发布:重庆邮电大学就业知乎 编辑:程序博客网 时间:2024/06/11 21:23

传闻JavaScript有两座大山——this与作用域,在函数中,这两个难点会交织在一起。本来this就一脸懵逼,又有同样懵逼的作用域,所以说很多人就会
这里写图片描述
es6中,又出现了一个箭头函数,箭头函数的this又比普通函数的this“骨骼惊奇”得多。欲搞清楚箭头函数的this指向,必须要搞清楚this的四种绑定机制。
参考链接:深入理解this机制系列第一章

默认绑定

全局环境中,this默认绑定到window
在控制台中分别执行以下代码,注意,全局变量相当于window对象的属性

<1> console.log(this==window) // true<2> var a={        foo:"123",        bar:"456",        that:this    }    a.that // window<3> this // window

函数独立调用或者被嵌套函数独立调用时,this默认绑定到window
虽然test()函数被嵌套在obj.foo()函数中,但test()函数是独立调用,而不是方法调用。所以this默认绑定到window

var a = 0;var obj = {    a : 2,    foo:function(){         function test(){             console.log(this.a);         }         test();    }}obj.foo();//0

立即执行函数实际上是函数声明后直接调用执行

var a = 0;function foo(){    (function test(){        console.log(this.a);    })()};var obj = {    a : 2,    foo:foo}obj.foo();//0

闭包中被返回到外部的函数也是独立调用

var a = 0;function foo(){    function test(){        console.log(this.a);    }    return test;};var obj = {    a : 2,    foo:foo}obj.foo()();//0

隐式绑定

函数做为对象方法调用时(即方法调用),this隐式绑定到该直接对象

function foo(){    console.log(this.a);};var obj1 = {    a:1,    foo:foo,    obj2:{        a:2,        foo:foo    }}//foo()函数的直接对象是obj1,this隐式绑定到obj1obj1.foo();//1//foo()函数的直接对象是obj2,this隐式绑定到obj2obj1.obj2.foo();//2

隐式丢失
隐式丢失是指被隐式绑定的函数丢失绑定对象,从而默认绑定到window,有以下几种情况会造成隐式丢失

<1>函数别名

var a = 0;function foo(){    console.log(this.a);};var obj = {    a : 2,    foo:foo}//把obj.foo赋予别名bar,造成了隐式丢失var bar = obj.foo;bar();//0

<2>参数传递

var a = 0;function foo(){    console.log(this.a);};function bar(fn){    fn();}var obj = {    a : 2,    foo:foo}//把obj.foo当作参数传递给bar函数时,有隐式的函数赋值fn=obj.foobar(obj.foo);//0

<3>作为内置函数的回调

var a = 0;function foo(){    console.log(this.a);};var obj = {    a : 2,    foo:foo}//如果没有隐式丢失,this应该指向objsetTimeout(obj.foo,100);//0//结果为0,证明函数作为作为内置函数的回调时发生了隐式丢失

<4>其他特殊情况

function foo() {    console.log( this.a );}var a = 2;var o = { a: 3, foo: foo };var p = { a: 4 };o.foo(); // 3//将o.foo函数赋值给p.foo函数,然后立即执行。相当于仅仅是foo()函数的立即执行(p.foo = o.foo)(); // 2

引用与调用的区别
调用:用原函数名调用函数,如foo()
引用:通过别名调用函数,比如var a=foo;a()

显式绑定

通过call()、apply()、bind()方法把对象绑定到this上,叫做显式绑定。对于被调用的函数来说,叫做间接调用

var a = 0;function foo(){    console.log(this.a);}var obj = {    a:2};foo();//0foo.call(obj);//2

显式绑定不能解决隐式丢失问题

function foo() {    setTimeout(function (){        console.log('id:',this.id);    }, 100);}var id = 21;foo.call({ id: 42 });//21

new绑定

构造函数通常不使用return关键字,它们通常初始化新对象,当构造函数的函数体执行完毕时,它会显式返回。在这种情况下,构造函数调用表达式的计算结果就是这个新对象的值

function fn(){    this.a = 2;}var test = new fn();console.log(test);//{a:2}

如果构造函数使用return语句但没有指定返回值,或者返回一个原始值,那么这时将忽略返回值,同时使用这个新对象作为调用结果

function fn(){    this.a = 2;    return;}var test = new fn();console.log(test);//{a:2}

如果构造函数显式地使用return语句返回一个对象,那么调用表达式的值就是这个对象

var obj = {a:1};function fn(){    this.a = 2;    return obj;}var test = new fn();console.log(test);//{a:1}

以上便是this绑定的四种机制,下一篇博文将讲解箭头函数this的指向机制

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 RS编译码器原理 高德地图 导航信息 当前导航路径信息 实时导航信息 高德导航时Navi的信息 高德NaviInfo 安卓蓝牙发送信息 clj.fastble 先采用队列求一条最短迷宫路径长度minlen,再采用栈求所有长度为minlen的最短迷宫路径 iOS蓝牙 pycharm激活 shadowsocks下载 shadowsocks下载 开源沙龙 C++程序设计从键盘中输入两个整数,求这两个整数的最大公约数和最小公倍数。 江南大学五部曲 centos搭建ss 算法之美_源代码发布(8) understand halfaSPIclockcycleproducesaclockedge 贪心算法活动 TRIZ系列-创新原理-17 朴素贝叶斯分类 王者荣耀金币 探索性数据分析演示 治安防控 治安 TRIZ系列-创新原理-19 TRIZ系列-创新原理-20 利用图像的平移、旋转、缩放、镜像等空间几何变换实现对图像的自适应缩放、几何变换等特效 利用图像的平移、旋转、缩放、镜像等空间几何变换实现对图像的几何变换等特效 [Err]1005-Can\'tcreatetable\'item4.#sql-1238_2c\'( SAPFICO财务成本知识 财务管理分析(希金斯:第八版) 图像解压 巜人民曰报》采访张文宏,陈尔真 linux上服务器如何转发设置 图像的自适应缩放、几何变换等特效 千讯网络下载 Gsensor调试