美文网首页让前端飞
javascript中this那些事

javascript中this那些事

作者: hapy_c124 | 来源:发表于2018-11-30 22:20 被阅读0次

    定义

    this是函数执行的上下文

    调用方式

    1.作为函数调用,指向window(严格模式报undefined的错)。

    var name='hello';

    function a() {    console.log(this.name)    }

    a();     //hello

    2.作为属性调用,指向该对象。

    var name='hello';

    function a(){    console.log(this.name)    }

    var b={    name:'world',    a:a    }

    var c={    name:'haha',    d: function(){ a(); } }  

    b.a();    //world

    c.d();    //hello

    有个陷阱,作为函数别名调用时,会丢失this。

    var test=b.a;

    test();     //hello

    3.作为构造函数调用,会把属性挂到new出来的实例上。

    function A(){    this.name='xiaoming'    }

    var a=new A();

    a.name    //xiaoming

    如果构造函数有return,且return 对象(包括{}、[]),那么new的实例就是return的值,如果return的是字符串、“”、null、undefined,new的实例和无return时new的实例一样。

    function A(){    this.name='xiaoming';    return null    }

    var a=new A();

    a.name    //xiaoming

    function A(){    this.name='xiaoming';    return {}    }

    var a=new A();

    a.name;    //undefined

    其实new做了三件事:

    1.创建一个新对象:var obj={};

    2.将obj的__proto__指向A.prototype:obj.__proto__=A.prototype;

    该步骤是为了继承构造函数A原型链。

    3.将this指向该新对象执行A:A.call(obj)。

    function Animal(){    this.animal="animal"    }

    Animal.prototype.name="9";

    function Dog(){    this.dog="dog";    }

    Dog.prototype.__proto__=Animal.prototype;

    ----------------------------------------------------------------

    var d=new Dog();

    var obj={};

    obj.__proto__=Dog.prototype;

    Dog.call(obj);

    上面的例子中,对象d和对象obj完全一样,结果都是下图的实例,都能访问Animal构造函数原型的属性name和方法。

    new原理

    改变this指向的三种方式

    1.call

    Function.call(obj,arg0,arg1...)

    将Function的this指向obj,第一个参数是this指向,后面的参数是传入Function的参数,一般用于参数个数固定的的函数。对于改变this指向,我个人理解是把函数里所有用到this的地方替换为obj。

    2.apply

    Function.apply(obj,[arg0,arg1...])

    将Function的this指向obj,第一个参数是this指向,第二个参数是传入Function的参数组成的数组,一般用于参数个数不固定的的函数。

    3.bind

    Funtion(arg0,arg1...).bind(obj)

    不太理解这句话的话,可能有些人会有一些其他的误区。

    误区1:this指向函数本身?

    var name='hello'

    function a(){    console.log(this.name)    }

    a.name='world';

    a() ;    //打印hello

    console.log(a.name)     //world

    所有的函数都继承自Object,从下图可以看出a函数的原型是Object的实例,因为Function.__proto__.__proto__===Object.prototype为true,也可以用Function.prototype.isPrototypeOf(Object)为tue判断。是对象就可以增加属性,所以a.name挂在了函数上,那他有没有丢呢?由例子打印的第二个值可以看出来没丢。

    a.prototype

    是对象都可以增加属性,Array.__proto__.__proto__===Object.prototype为ture,Array.__proto__.__proto__.isPrototypeOf(Object)为true,所以Array和Function一样,也可以增加属性。感兴趣可自行测试。

    array

    误区2:this是函数局部作用域?

    var name='hello'

    function a(){  var name='world';    console.log(this.name)  }

    a();    //hello

    上例打印hello,不是world,说明this并不是函数的局部作用域。

    误区3:this指向父级函数作用域?

    var name='hello'

    function a(){  console.log(this.name)  }

    function b(){ var name='world';    a();   }

    b();    //hello

    该例子打印的是hello,而不是world,说明this并不是父级函数作用域,而是调用上下文。

    相关文章

      网友评论

        本文标题:javascript中this那些事

        本文链接:https://www.haomeiwen.com/subject/ohrkcqtx.html