理解学习this指向问题

要点

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

this指向的三种状况

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

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指向构造函数建立的对象实例。this

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

运行结果spa

clipboard.png

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

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

运行结果对象

clipboard.png

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

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

运行结果ip

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,是自带的封装好的方法。简单数据类型存放在内存的栈中,而复杂数据类型存放在内存的堆中,把地址存放在内存的栈中,先获取地址,再读取堆中数据。

相关文章
相关标签/搜索