zoukankan      html  css  js  c++  java
  • JavaScript中的this基本问题<转>

    在函数中 this 到底取何值,是在函数真正被调用执行的时候确定下来的,函数定义的时候确定不了。 

    执行上下文环境 :

     **定义**:执行函数的时候,会产生一个上下文的对象,里面保存变量,函数声明和this。

     **作用**:用来保存本次运行时所需要的数据

    当你在代码中使用了 this,这个 this 的值就直接从执行的上下文中获取了,而不会从作用域链中搜寻。

    关于 this 的取值,大体上可以分为以下几种情况:

    情况一:全局 & 调用普通函数

    在全局环境中,this 永远指向 window。

    console.log(this === window);     //true

    普通函数在调用时候(注意不是构造函数,前面不加 new),其中的 this 也是指向 window。

    但是如果在严格模式下调用的话会报错:

    复制代码
    var x = 1;
    function first(){
        console.log(this);     // undefined
        console.log(this.x);   // Uncaught TypeError: Cannot read property 'x' of undefined
    }
    first();
    复制代码

    情况二:构造函数

    所谓的构造函数就是由一个函数 new 出来的对象,一般构造函数的函数名首字母大写,例如像 Object,Function,Array 这些都属于构造函数。

    复制代码
    function First(){
        this.x = 1;
        console.log(this);    //First {x:1}
    }
    var first = new First();
    console.log(first.x);      //1
    复制代码

    上述代码,如果函数作为构造函数使用,那么其中的 this 就代表它即将 new 出来的对象。

    但是如果直接调用 First函数,而不是 new First(),那就变成情况1,这时候 First() 就变成普通函数。

    复制代码
    function First(){
        this.x =1;
        console.log(this);    //Window
    }
    var first = First();
    console.log(first.x);      //undefined
    复制代码

    情况三:对象方法

    如果函数作为对象的方法时,方法中的 this 指向该对象。

    复制代码
    var obj = {
        x: 1,
        first: function () {
            console.log(this);        //Object
            console.log(this.x);      //1
        }
    };
    obj.first();
    复制代码

    意:若是在对象方法中定义函数,那么情况就不同了。

    复制代码
    var obj = {
        x: 1,
        first: function () {
            function second(){
                console.log(this);      //Window
                console.log(this.x);    //undefined
            }
            second();
        }
    }
    obj.first();
    复制代码

    可以这么理解:函数 second虽然是在 obj.first 内部定义的,但它仍然属于一个普通函数,this 仍指向 window。

    在这里,如果想要调用上层作用域中的变量 obj.x,可以使用 self 缓存外部 this 变量。

    复制代码
    var obj = {
        x:1,
        first: function () {
            var self = this;
            function second(){
                console.log(self);      //{x: 1}
                console.log(self.x);    //1
            }
            second();
        }
    }
    obj.first();
    复制代码

    如果 first 函数不作为对象方法被调用:

    复制代码
    var obj = {
        x: 1,
        first: function () {
            console.log(this);       //Window
            console.log(this.x);     //undefined
        }
    };
    var fn = obj.first;
    fn();
    复制代码

    obj.first 被赋值给一个全局变量,并没有作为 obj 的一个属性被调用,那么此时 this 的值是 window。

    情况四:构造函数 prototype 属性

    复制代码
    function First(){
        this.x = 1;
    }
    First.prototype.getX = function () {
        console.log(this);        //First {x: 1, getX: function}
        console.log(this.x);      //1
    }
    var first= new First();
    first.getX();
    复制代码

    在 First.prototype.getX 函数中,this 指向的first 对象。不仅仅如此,即便是在整个原型链中,this 代表的也是当前对象的值。

    情况五:函数用 call

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

    当一个函数被 call调用时,this 的值就取传入的对象的值。

    来源:知乎

    链接:https://zhuanlan.zhihu.com/p/25294187?utm_source=com.youdao.note&utm_medium=social

    作者:林东洲

  • 相关阅读:
    设计模式六大原则(PHP)
    composer update 或者 composer install提示killed解决办法
    运行composer出现do not run Composer as root/super user!
    composer install报错intervention/image 2.4.x-dev requires ext-fileinfo * -> the requested PHP extension fileinfo is missing from your system.
    laravel执行数据库迁移的过程中出现IlluminateDatabaseQueryException : SQLSTATE[HY000] [2002] Operation timed out (SQL: select * from information_schema.tables where table_schema = shop and table_name = migrations
    docker删除mysql镜像失败Error response from daemon: conflict: unable to delete 8809d5286227 (must be forced)
    测试开发岗,面试必看
    Python遍历字典去key和value需要注意的点→enumerate和items()
    Python→整数反转
    我去阿里、头条、京东的面试经(测开)
  • 原文地址:https://www.cnblogs.com/powerplay/p/7690112.html
Copyright © 2011-2022 走看看