博客
关于我
对于js中的this指向的深入理解
阅读量:375 次
发布时间:2019-03-05

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

一、this的指向

  1. this的指向是指谁调用它,那么this就指向谁

  2. 全局环境中的this

    1)浏览器环境:无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象 window
    2)node 环境:无论是否在严格模式下,在全局执行环境中(在任何函数体外部),this 都是空对象 {}

  3. 是否是 new 绑定

    1)如果是 new 绑定,并且构造函数中没有返回 function 或者是 object,那么 this 指向这个新对象
    2)构造函数返回值不是 function 或 object,这种情况下 this 指向的是新到的对象
    实例代码:

function Person(age){           this.age = age;    }    // 23    // this指向的是这个新的对象    let person1 = new Person("23");    console.log(person1.age);

3)构造函数返回值是 function 或 object,这种情况下 this 指向的是返回的对象

实例代码:

function Person2(age){           this.age = age;        let obj = {   a:"21"};        return obj;    }    // undefined    let person2 = new Person2("hello");    console.log(person2.age);

4)new的实现原理

创建一个新对象
这个新对象会被执行 [[原型]] 连接
属性和方法被加入到 this 引用的对象中。并执行了构造函数中的方法
如果函数没有返回其他对象,那么 this 指向这个新对象,否则 this 指向构造函数中返回的对象
5)new的实例代码:

function New(func){           let target = {   };        target._proto_ = func.prototype;        let res = func.call(target);        // 排除null的情况        if(res && typeof(res) == "object" || typeof(res) == "function"){               return res;        }        return target;    }
  1. 函数是否通过 call,apply 调用,或者使用了 bind 绑定,如果是,那么this绑定的就是指定的对象为显式绑定
    1)显示绑定的实例代码:
function info(){           console.log(this.age);    }    var person3 = {           age:26,        info    };    var age = 21;    var info = person3.info;    // 26    info.call(person3);    // 26    info.apply(person3);    // 26    info.bind(person3)();

2)如果 call,apply 或者 bind 传入的第一个参数值是 undefined 或者 null,严格模式下 this 的值为传入的值 null /undefined。非严格模式下,实际应用的默认绑定规则,this 指向全局对象(node环境为global,浏览器环境为window)

实例代码:

function info2(){           // node环境中,非严格模式为global,严格模式为null        // 浏览器环境中,非严格模式为window,严格模式为null        console.log(this);        console.log(this.age);    }    var person4 = {           age:20,        info2    };    // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}    // 24    var age = 24;    var info2 = person4.info2;    // 严格模式下会报错    // 非严格模式下,node输出undefined,全局变量age不会挂在global    // 非严格模式下,浏览器环境中输出24,全局变量age会挂在window    info2.call(null);

5.隐式绑定,函数的调用是在某个对象上触发的,即调用位置上存在上下文对象。典型的隐式调用为: xxx.fn()

1)隐式绑定的实例代码:

function info3(){           console.log(this.age);    }    var person5 = {           age:26,        info3    }    // 26    // 执行的是隐式绑定    var age = 18;    person5.info3();
  1. 默认绑定,在不能应用其它绑定规则时使用的默认规则,通常是独立函数调用
    1)默认绑定的实例代码:
// 非严格模式: node环境,执行全局对象 global,浏览器环境,执行全局对象 window    // 严格模式:执行 undefined    function info4(){           console.log(this.age);    }    // 28    // 严格模式下会报错,this是undefined    // 非严格模式下,node环境会输出undefined,浏览器环境输出28    var age = 28;    info4();
  1. 箭头函数的情况
    1)箭头函数没有自己的this,继承外层上下文绑定的this
    实例代码:
let obj = {           age:27,        info:function(){               return() => {                   // this继承的是外层上下文绑定的this                console.log(this.age);            }        }    };        let person6 = {   age:26};	// 27    let info5 = obj.info();    info5();    // 26    let info6 = obj.info.call(person6);    info6();

二、this指向的面试题总结

  1. 如何正确的判断this? 箭头函数的this是什么?

    1)this的绑定规则有四种:默认绑定,隐式绑定,显式绑定,new绑定
    2)函数是否在 new 中调用(new绑定),如果是,那么 this 绑定的是新创建的对象,前提是构造函数中没有返回对象或者是function,否则this指向返回的对象/function
    3)函数是否通过 call,apply 调用,或者使用了 bind (即硬绑定),如果是,那么this绑定的就是指定的对象
    4)函数是否在某个上下文对象中调用(隐式绑定),如果是的话,this 绑定的是那个上下文对象,一般是 obj.foo()
    5)如果以上都不是,那么使用默认绑定,如果在严格模式下,则绑定到 undefined,否则绑定到全局对象
    6)如果把 null 或者 undefined 作为 this 的绑定对象传入 call、apply 或者 bind, 这些值在调用时会被忽略,实际应用的是默认绑定规则
    7)箭头函数没有自己的 this, 它的this继承于上一层代码块的this

  2. 判断下面this的值

var number = 6;    var obj2 = {           number:8,        fn1:(function(){               var number;            // 12            this.number *= 2;            number = 3;            return function(){                   var num = this.number;                this.number *= 2;                console.log(num);                number *= 3;                console.log(number);            }        })()    };    // 12 9 8 27 24    var fn1 = obj2.fn1;    fn1.call(null);    obj2.fn1();    console.log(window.number);

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

你可能感兴趣的文章
ngrok内网穿透可以实现资源共享吗?快解析更加简洁
查看>>
NHibernate动态添加表
查看>>
NHibernate学习[1]
查看>>
NHibernate异常:No persister for的解决办法
查看>>
Nhibernate的第一个实例
查看>>
NHibernate示例
查看>>
nid修改oracle11gR2数据库名
查看>>
NIFI1.21.0/NIFI1.22.0/NIFI1.24.0/NIFI1.26.0_2024-06-11最新版本安装_采用HTTP方式_搭建集群_实际操作---大数据之Nifi工作笔记0050
查看>>
NIFI1.21.0_java.net.SocketException:_Too many open files 打开的文件太多_实际操作---大数据之Nifi工作笔记0051
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_补充_插入时如果目标表中已存在该数据则自动改为更新数据_Postgresql_Hbase也适用---大数据之Nifi工作笔记0058
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_补充_更新时如果目标表中不存在记录就改为插入数据_Postgresql_Hbase也适用---大数据之Nifi工作笔记0059
查看>>
NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
查看>>
NIFI1.21.0_Postgresql和Mysql同时指定库_指定多表_全量同步到Mysql数据库以及Hbase数据库中---大数据之Nifi工作笔记0060
查看>>
NIFI1.21.0最新版本安装_连接phoenix_单机版_Https登录_什么都没改换了最新版本的NIFI可以连接了_气人_实现插入数据到Hbase_实际操作---大数据之Nifi工作笔记0050
查看>>
NIFI1.21.0最新版本安装_配置使用HTTP登录_默认是用HTTPS登录的_Https登录需要输入用户名密码_HTTP不需要---大数据之Nifi工作笔记0051
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增加修改实时同步_使用JsonPath及自定义Python脚本_03---大数据之Nifi工作笔记0055
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_插入修改删除增量数据实时同步_通过分页解决变更记录过大问题_01----大数据之Nifi工作笔记0053
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表或全表增量同步_实现指定整库同步_或指定数据表同步配置_04---大数据之Nifi工作笔记0056
查看>>