首页 > 其他 > 详细

学习中···ES5和ES6this的用法(先记录,有新的收获再补充)

时间:2019-08-01 17:50:16      阅读:74      评论:0      收藏:0      [点我收藏+]

this到底指向哪里?

  当然,大多数人都是对“this”的字面意思有些误解,例如,通常会理解成this指向函数自身,毕竟英语解释是如此。

  下面我们看个例子:

      function foo(num){
            console.log("foo:" + num);
            this.count++;
        }
        foo.count = 0;

        for(i = 0;i<5;i++){
            if(i>2){
                foo(i); // foo:3;   foo:4;
            }
        }
        console.log(foo.count); //0 

 

console.log语句产生了 foo:3  foo:4 两条语句,被调用了两次,为什么打印输出 foo.count仍然为0?

首先要明白,this既不指向函数自身也不指向函数的词法作用域;实际上是在函数被调用时发生的绑定,它指向什么只取决于在哪里调用函数。

在控制台打印便知:

 function foo(num){
      console.log(this);//Window 
      console.log(this.count);//2

    }
 foo.count = 0;
 var count = 2
 foo();

在全局变量里定义了一个count = 2;在foo()里打印this.count输出结果为2;同时也打印了this,输出为window,也就说this绑定在window(全局里)下面,为什么?

这样我们就需要讨论一下函数的调用位置如果决定this的绑定对象

如何找调用位置呢?想要找到调用位置,就需要先分析调用栈(从开始到执行位置所调用的所有函数) 我来引用下《你不知道的JavaScript》里的例子

            var a = "vv";
            var baz = function(){ //当前调用栈:baz 
                                //当前的调用位置时全局作用域
                var a = "aa";
                console.log(this.a); //vv
                bar();
            }
            var bar = function(){ //当前调用栈:baz--> bar
                                 //当前的调用位置是baz中
                var a = "bb";
                console.log(this.a);//vv
                foo();
            }
            var foo = function(){//当前调用栈:baz--> bar -->foo
                                //当前的调用位置是bar中
                var a = "cc";
                console.log(this.a);//vv
            }
           baz();      //baz调用位置

分析出真正的调用位置,就能照出this的绑定位置,所以这个例子中this的指向是全局变量中的a,而不是函数里的a。

 

 

默认绑定规则方式我们上面说的好多,简单地将,就是foo()直接使用而不带任何修饰的函数引用进行调用时,无法应用其他规则。

什么叫做不带任何修饰的函数引用调用?

 别急...看到下面就知道了

 

希望不要晕了。

  对象函数调用时,那个函数调用this就指向那个对象

  

        var name = "window";
         var obj = {
            "name":"john",
            "sayHello":function(){
                console.log(this);    //指向obj
                console.log(this.name+":Hello world!"); //john:Hello world!
            }
        }
        obj.sayHello();

sayHello()这个函数被obj引用,当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象中,所有调用sayHello()函数时被绑定到obj。

是不是觉得函数写在对象里,obj肯定绑定的啦~

    var name = "window";
    var sayHello = function(){
          console.log(this);    //指向obj
          console.log(this.name+":Hello world!"); //john:Hello world!
     }
    var obj = {
          "name":"john",
           sayHello:sayHello,
            
     }
    obj.sayHello();

 

 

  注意,是对象函数,而不是函数,在函数里是需要找到this的绑定位置,而在对象属性引用链中,只有最后一次的调用位置中起作用

不多说,例子奉上

  var name = "window";
    var sayHello = function(){
                console.log(this);    //指向obj2 {name: "john", sayHello: ƒ}
                console.log(this.name+":Hello world!"); //john:Hello world!
            }
    var obj2 = {
            "name":"john",
            sayHello:sayHello, 
                }
    var obj1 = {
            "name":"jack",
            obj2:obj2, 
                }
    obj1.obj2.sayHello();

 


 

 

在刚才几个例子中,你们肯定疑惑,在对象里面包含一个指向函数的属性,为什么?

  因为需要这个属性间接引用函数,然后利用隐式规则间接的绑定到这个函数上,在调用函数时前面会有obj进行"修饰",可以说函数被obj对象引用或调用。

 

如果你喜欢强制调用函数的,不想这么麻烦的在对象里引用或者调用的话,那你就需要用到一个方法  call()

  function sayHello(){
        console.log(this.name); //john
    }
    var obj = {
        name:"john"
    };
    sayHello.call(obj);

这样,我么就可以调用 函数的时候流氓的把它的this绑定到obj上

 

ES6中的箭头函数并不会使用以上的绑定规则,而是根据当前的词法作用域来觉得this。

简单地说,就是箭头函数里的this是指向外层函数调用的this绑定,如果没有外层函数,就指向window

例子:箭头函数常用于定时器

    var name = "window";
    var sayHello = function(){
                    console.log(this); //指向Object
                    setInterval(()=>{console.log(this.name)},1000);//john
            }

     var obj = {
            "name":"john",
                }
    sayHello.call(obj);

箭头函数的外层函数被绑定到obj中,this指向也随之指向obj;

 

  var name = "window";
    var sayHello = ()=>{
                    console.log(this); //指向window
                    setInterval(()=>{console.log(this.name)},1000);//window
            }

     var obj = {
            "name":"john",
                }
    sayHello.call(obj);

这段代码中,箭头函数没有外层函数,即使绑定在对象里,this仍然指向window,因为箭头函数是根据外层(函数或者全局)作用域决定this的指向。

 

以上是我对this的理解,如有不对,请您指出,一起学习,共同进步,谢谢!

 

学习中···ES5和ES6this的用法(先记录,有新的收获再补充)

原文:https://www.cnblogs.com/kongVv/p/11283746.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!