2

要点

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象。

this指向的三种情况

情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,而是指向调用函数的对象实例,这种函数中的this等于undefined。

function a(){
        var user = "维他奶";
        console.log(this);//window
        console.log(this.user);//undefined
    }
    //windonw是全局对象,所有的全局变量都是对象的属性.
    //a()<=>window.a()
    a();
    console.log(window);
    console.log(window.user);//根本没有user这个属性。只有一个name="";

运行结果
clipboard.png

严格模式,请参照https://segmentfault.com/a/11...
严格模式下定义变量必须使用var。否则报错.
在严格模式下,对象的函数中的this指向调用函数的对象实例
同样道理,可以推断出,在严格模式下,构造函数中的this指向构造函数创建的对象实例。

"use strict";//开启严格模式
    function a(){
        var user = "维他奶";
        //在严格模式下,对象的函数中的this指向调用函数的对象实例
        console.log(this);//a{}
        console.log(this.user);//undefined
    }
    var A = new a(); 

运行结果

clipboard.png

情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。

var sum = {
        a:10,
        b:{
            a:12,
            fn:function(){
                console.log(this.a);//12
            }
        }
    }
    sum.b.fn();

运行结果

clipboard.png

情况3:如果一个函数中有this,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象.

var sum = {
        a:10,
        b:{
            // a:12,
            fn:function(){
                console.log(this.a);//undefined
            }
        }
    }
    sum.b.fn();

运行结果

clipboard.png

注意事项
尽管对象b中没有属性a,这个this指向的也是对象b,因为this只会指向它的上一级对象,不管这个对象中有没有this要的东西。

情况4:this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,情况4中虽然函数fn是被对象b所引用,但是在将fn赋值给变量num的时候并没有执行所以最终指向的是window,这和情况3是不一样的,情况3是直接执行了fn。

var sum = {
        a1:10,
        b:{
            a:12,
            fn:function(){
                console.log(this.a1);//undefined
                console.log(this);//window
            }
        }
    }
    var num = sum.b.fn;
    num();

运行结果

clipboard.png

构造函数的this指向:

function A(){
        this.name = "维他奶";
    }
    var a = new A();
    console.log(a.name);//维他奶

运行结果

clipboard.png

new关键字到底做了什么?
(1) 创建一个新对象;
(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);原理:自动调用apply方法,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。
(3) 执行构造函数中的代码(为这个新对象添加属性);
(4) 返回新对象。

return 会把new创建的this覆盖.
如果返回值是复杂数据类型,那么this指向的就是那个返回的对象,如果返回值不是复杂数据类型那么this还是指向函数的实例。

    function A(){
        this.name = "维他奶";
        return 1;
    }
    var a = new A();
    console.log(a.name);//维他奶

    function A(){
        this.name = "维他奶";
        return ;
    }
    var a = new A();
    console.log(a.name);//维他奶

    function A(){
        this.name = "维他奶";
        return function(){};
    }
    var a = new A();
    //传入空函数,所以输出一个空,而不是undefined
    console.log(a.name);//""

    function A(){
        this.name = "维他奶";
        return null;
    }
    var a = new A();
    console.log(a.name);//维他奶

简单数据类型:string,boolean,number,undefined,null,NaN
复杂数据类型: Object,Function,Array,String,Boolean,Number
其中String,Boolean,Number,是自带的封装好的方法。
简单数据类型存放在内存的栈中,而复杂数据类型存放在内存的堆中,把地址存放在内存的栈中,先获取地址,再读取堆中数据。


sherlock成
1 声望2 粉丝