js关于this那点事

this的四种情况

  • this 的指向一共有四种情况,记住理解就可以玩遍js的this。
  • 函数预编译过程this --> window
  • 全局作用域 this --> window
  • call/apply 可以改变this的指向
  • obj.fun();谁调用指向谁

第一种情况:函数预编译过程this --> window

  • 这种情况多数指的是纯函数调用前预编译的过程,在作用域链上的this指向。大家可以看下面的图:
    js关于this那点事_第1张图片
  • 可以看如下代码
function demo(){
    this.demo1 = function(){
        console.log(this === window);
    }
    demo1();
}
demo();
var d = new demo();
d.demo1();
  • 第一个输出为true,而第二个new函数也相当于是调用函数输出true。这就证明了this指向的是window,而第三个为false是由于对象调用this指向的是对象,所以this.demo1是一个对象属性,输出为false。
    js关于this那点事_第2张图片

第二种情况:全局作用域 this --> window

  • 在全局作用域下,this是指向window的。
console.log(this == window);

js关于this那点事_第3张图片

第三种情况:call/apply 可以改变this的指向

  • 大家要明白call和apply的区别,只有传递参数不同。
	function Person(name){
        this.name = name;
        this.info = function(){
            console.log(this.name);
        }
    }
    var name = "bbb";
    var p = new Person("aaa");
    p.info();
    p.info.call(window);

js关于this那点事_第4张图片

  • p.info();这个是属于咱们的第四种情况,对象谁调用就指向谁,输出。p.info.call(window),指向window,输出bbb。

第四种情况:谁调用指向谁

  • new对象之后谁调用指向谁(这个对象)。
	function Person(name){
        this.name = name;
        this.info = function(){
            console.log(this.name);
        }
    }
    var name = "bbb";
    var p = new Person("aaa");
    p.info();

js关于this那点事_第5张图片

实际上还有第五种特殊情况(ES6箭头函数)

  • 在箭头函数中,永远指向箭头函数this总是代表包含箭头函数的上下文。
  • 这里面new Demo()是必须的,如果只是普通的调用函数,那么包含箭头函数的执行期上下文只有一个就是window对象,因为只有对象才可以用this。
	function Demo(){
        var f = () => this;
        console.log(f() === window);
    }
    var demo = new Demo();

js关于this那点事_第6张图片

  • 对比着来看普通函数:
 	function Demo(){
        var f = function(){return this;}
        console.log(f() === window);
    }
    var demo = new Demo();

js关于this那点事_第7张图片

一个简单的例子(坏坏的表情)

  • 如果你理解了这个例子,那么就证明你吃透了this。
    var name = "222";
    var a = {
        name : "111",
        say : function (){
            console.log(this.name);
        }
    }
    var fun = a.say;
    fun();
    a.say();
    var b = {
        name : "333",
        say : function (fun){
            fun();//走预编译
        }
    }
    b.say(a.say);
    b.say = a.say;
    b.say();

js关于this那点事_第8张图片

  • 看到这个结果是不是有点小懵。
  • 我们来慢慢分析一下,var fun = a.say;实际上是将a.say这个函数赋值给fun,但是fun的是是属于window全局的,所以呢调用this.name输出222。属于第二种情况。
  • a.say();这个好说this指向的是obj对象,输出111。属于第四种情况。
  • b.say(a.say);将a.say这个函数放到b.say的环境下调用,实际上属于预编译过程,属于第一个情况。输出222。
  • b.say = a.say;替换b.say。 b.say();执行,返回b对象中的name为333。

你可能感兴趣的:(Web前端开发,js的this)