资讯专栏INFORMATION COLUMN

this的五种指法

Caizhenhao / 1386人阅读

摘要:中只有的作用域是动态作用域的五种绑定初学时,会想当然认为遵循某一条规律,就像物理学那样,然而并不是。的绑定分为五种情况,这五种情况之间毫无规律可言。以至指向更加扑朔迷离。

this 到底指向哪里
以下如果没提及,则为严格模式。

js中作用域有两种:

词法作用域

动态作用域

词法作用域

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

    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()// 指向T
tt.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指向实例
总结

五种绑定,后面两种情况单一,前面两种会因为方法,函数被赋值而互相转化。

因为this处于动态作用域,而目前开发时又大量使用框架。我们写下的代码,并不总是由我们自己调用,而是被打包工具打包后,由框架调用。导致我们并不知道我们写下的函数和方法是否被框架复制过或显示绑定过而改变了this指向。以至this指向更加扑朔迷离。

写完本文顿时觉得,python里指向明确的self完爆js的this。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100616.html

相关文章

  • this五种不同情形

    摘要:的五种不同情形默认情况在默认的,纯粹的函数调用时,视作全局性调用,此时的指向全局对象,在浏览器环境下,也即对象。构造函数当一个函数被当做构造函数,用关键字新建一个对象的时候,这个函数内部的以及原型链上的都会指向这个新建的对象。 this的五种不同情形 默认情况 在默认的,纯粹的函数调用时,视作全局性调用,此时的this指向全局对象Global,在浏览器环境下,也即window对象。 ...

    Hydrogen 评论0 收藏0
  • 实现compose五种思路

    好久没有更新了,最近学习的过程中一直在用联想的思维来去看问题,javascript是一门非常灵活的语言,集合了好多语言的特性和多种编程模式,对于compose的实现,就有非常多的思路,每一种思路都有自己的特点,实现之后,有种殊途同归的快感。下面就是我总结的实现compose函数的五种思路。 面向过程 函数组合(reduce) 函数交织(AOP编程) Promise(sequence) Gener...

    RayKr 评论0 收藏0
  • React Native 传参五种方式

    摘要:在中由于业务的需要我们往往要在诸多的页面间,组件之间做一些参数的传递与管理在这里我总结了几大经过验证,稳定好用的方式给大家导航传值推荐指数适用范围相邻页面间传值兼容性原理为页面的上挂载了对象可用来做路由跳转,在做页面跳转时可以携带参数回调方 在React Native 中由于业务的需要, 我们往往要在诸多的页面间,组件之间做一些参数的传递与管理, 在这里我总结了几大经过验证,稳定好用的...

    cnTomato 评论0 收藏0
  • 假设高度已知,请写出三栏布局,其中左栏、右栏各为300px,中间自适应五种方法

    摘要:假设高度已知,请写出三栏布局,其中左栏右栏各为,中间自适应的五种方法页面布局题目假设高度已知,请写出三栏布局,其中左栏右栏各为,中间自适应浮动解决方案浮动解决方案这是三栏布局的中间部分这是三栏布局的中间部分绝 假设高度已知,请写出三栏布局,其中左栏、右栏各为300px,中间自适应的五种方法 HTML CSS 页面布局 题目:假设高度已知,请写出三栏布局,其中左栏、右栏各为300px...

    alaege 评论0 收藏0

发表评论

0条评论

Caizhenhao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<