zoukankan      html  css  js  c++  java
  • --外功篇-《JavaScript那些事》-01-理解This指向--

    --外功篇-《JavaScript那些事》-01-理解This指向--

    功法小传

    近日的小虾米,在研习JavaScript招式的过程中,博采众长,勤奋练习,翻阅古籍。
    终了然JavaScript招式中,容易引人走火入魔的变数之一——this指向!
    虽不敢说完全了然,但其基本理解,心中有数。
    对日后行走江湖,多有裨益。
    于是,匆匆记下,以备后事之需:

    内容正传

    JavaScript的this指向问题:
    在我们使用JavaScript操作dom时,经常会使用this来引用当前对象。但有时候,往往预料之中的指向却出现个指向错误的问题。
    近日,小虾米翻阅了《你不知道的JavaScript》这本书,对其中的this讲解做一个总结和笔记吧。

    调用栈

    首先需要明白,JavaScript的调用栈的概念。

    function three() {
    	console.log("three has done!")
    }
    
    function two() {
    	three();
    	console.log("two has done!")
    }
    
    function one() {
    	two();
    	console.log("one has done!")
    }
    
    one();
    //输出:
    // three has done!
    // two has done!
    // one has done!
    

    在这个代码片段中,我们通过one进行了one->two->three的调用。
    由输出可以知道,先进入调用栈的函数最后执行。

    this的执行方式

    this并不是在函数声明时执行的,而是在函数运行中才执行。

    因此,this的指向就与this所处的函数以及函数的状态有关。

    this指向的判断

    上文中提到“this所处的函数以及函数的状态”,就是传说中的“上下文”。

    这么解释起来还是有些抽象。

    举个代码例子:
    1.

    var val = 2;
    function a() {
    	console.log(this.val);
    }
    a();
    //输出:
    // undefined
    

    这个代码片段中的this指向的是全局,因为a函数所处于全局环境中;
    2.

    function a() {
    	console.log(this.val);
    }
    
    var obj = {
    	val: 1,
    	a: a
    }
    obj.a();
    // 输出: 
    // 1
    

    这个代码片段中的this指向的是obj,因为a函数所处于obj对象的环境中;

    这里,我们就已经解决完一般函数中的this指向问题了。

    但要注意,在连续对象嵌套中(如:obj1().obj2().a()),this只会指向他调用栈的前一位对象(例子中只会指向obj2)

    PS:有人会将“上下文”理解为this作用时其所处的对象作用域中。这种理解在大部分情况下是这样,但在JavaScript底层的运行过程中并不是如此。

    有关this的隐式绑定

    this绑定中,还存在一下代码片段的问题:

    obj = {
    	val: 1,
    	a: function() {
    		console.log(this.val);
    	}
    }
    
    function fnc(fn) {
    	fn();
    }
    fnc(obj.a);
    // 输出:
    // undefined
    

    看到这里肯定会疑惑,a明明是所处于对象obj中的,为什么输出的是undefined这个全局环境才有的结果呢?

    记得this的执行原理嘛?this是在代码运行时进行指向。

    fnc在执行时,是将obj中的a函数,作为fnc的形参传入fnc中,因此,this的指向与fnc所处环境有关,而与obj无关了。

    这就是this的隐式绑定。

    关于new绑定和硬绑定

    在JavaScript中,我们经常使用new来进行构造函数的实例化,这个过程也是创建了对象,其实例化对象的this指向与之前所讲的对象中的this指向没什么区别

    关于硬绑定,是我们使用call、apply、bind进行this强制指向传入对象的方法,来达成我们需要this指向特定对象的目的。

    补充:

    1. 关于this指向的一些案例补充

    PS:记录至此,若日后还有补充,则另开篇再记录~

    离大侠再近一步!
  • 相关阅读:
    Mybatis获取插入记录的自增长ID
    mybatisGenerator 代码自动生成报错 Result Maps collection already contains value for BaseResultMap
    <c:if test="value ne, eq, lt, gt,...."> 用法
    大话设计模式之----状态模式
    php文件加锁 lock_sh ,lock_ex
    in_array 判断问题的疑惑解决。
    我是一只IT小小鸟观后感
    《世界是数字的》
    我是一只IT小小鸟
    解压缩
  • 原文地址:https://www.cnblogs.com/Samo-Li/p/13678399.html
Copyright © 2011-2022 走看看