美文网首页
this指針

this指針

作者: ed91c134ad6f | 来源:发表于2017-12-29 15:45 被阅读7次

    (1)this在js中主要有四种用法:

    1、作为普通函数使用

    2、作为对象方法来使用

    3、call和apply

    4、作为构造函数来使用

    1>作为普通函数来使用:

    function funcA() {
    
    this.name = "hello";
    
    console.log(this.name);
    
    this.show =function() {
    
    console.log(this.name);
    
    }
    
    }
    
    funcA();//1、hello
    
    

    这个代码很简单,但也隐藏了一个坑,就是这个时候的this代表的是window的指针,所以当这段代码运行完之后,你再输出console.log(window.name)时候,你会发现输出为”hello”,在使用中尽量避免。

    2>作为对象方法来使用

    var obj={name:"hello",show:function(){
    
    console.log(this.name);
    
    }};
    
    obj.show();
    
    

    这个很简单,this指向自己,所以this.name就用hello;

    var obj={name:"hello",show:function(){
    
    console.log(this.name);
    
    }};
    
    obj.show();
    
    var objA={name:"world"}
    
    objA.show=obj.show;
    
    objA.show()
    
    

    答案是”world”,因为在js中对象都是引用类型,当objA.show=obj.show这句代码把objA.show也指向的show方法,所以在调用的时候会把this,指向objA而不是obj.

    3>call和apply

    这个在上面的继承中的原型冒充中也提过一些,这里也详细说明this在call和apply中微秒的用法:

    function funcA() {
    
    this.name = "hello";
    
    console.log(this.name);
    
    this.show =function() {
    
    console.log(this.name);
    
    }
    
    }
    
    var a =new funcA();
    
    a.show();
    
    var objA ={
    
    name:"objA"
    
    }
    
    a.show.call(objA);
    
    

    上面这段代码就是call的用法,这里我们可以把代码拆解成我们能看的懂的形式:

    a.show.call(objA)====>{
    
    obj.show=a.show();
    
    obj.show();
    
    delete obj.show();
    
    }
    
    

    上面就是call的类似执行的过程的形势(实际上并不是这样的,可以这样来记),知道了这个执行过程,我们就来探究这个的执行过程:

    1、把a.show里面的方法中的this全部换成obj.

    2、执行a.show(),同时把后面的参数作为参数处理。

    4、作为构造函数来使用

    function funcA(name){
    
    this.name;
    
    this.show=function(){
    
    console.log(name);
    
    }
    
    }
    
    var a=new funcA("hello");
    
    a.show();
    
    

    作为构造函数使用的时候,在new的关键字创建对象的时候,会先生成一个空对象,然后调用方法,把this的替换成这个空对象。(这个在上篇有详细的说明,这里不多说)。在创建对象的时候,this指针就指向了创建新对象。

    所以上面的那段代码我想应该就能看懂为什么会是这个输出结果了,唯一的有一个(objB.show = a.show)();这个比较奇怪,因为赋值的时候,返回的是右边的那个函数,所以最终执行的也是a.show();

    总结:js中的this其实是一个比较简单的东西,上面只列出了常用的东西,至于更深入的,可以自己在深入挖掘下,相信有了这个基础后,再深入的话应试就不是一件枯燥的事了

    下篇说下可以快速学习js的方面的知识。

    注意:

    var name ="Kevin Yang";
    
    function sayHi(){
    
     alert("你好,我的名字叫"+this.name); 
    
     } 
    
     sayHi();
    
    script>
    
    

    这段代码和上段代码的区别就在于sayHi函数在使用name的时候加上了this.前缀。运行结果和上面一摸一样。这说明this.name引用的也还是全局的name对象。

    var name ="Kevin Yang";
    
    functionsayHi(){ 
    
     alert("你好,我的名字叫"+this.name); 
    
     }
    
    var  person = {};
    
     person.sayHello = sayHi; 
    
     person.sayHello();
    
    script>
    
    

    这一次,我们又创建了一个全局对象person,并将sayHi函数对象赋给person对象的sayHello属性。运行结果如下:

    ![][图片上传失败...(image-6bc0b3-1514356625974)]

    我们发现this.name已经变成undefined了。这说明,在sayHello函数内部执行时已经找不着this.name对象了。如果我们重新定义person对象,在其上面加上一个name属性又会怎么样呢?

    var person = {name:"Marry"};
    
    

    运行代码发现打招呼的“人”变了:

    ![(image-3941e-1513993419330)]

    判别this指针的指导性原则:

    在Javascript里面,this指针代表的是执行当前代码的对象的所有者。

    在上面的示例中我们可以看到,第一次,我们定义了一个全局函数对象sayHi并执行了这个函数,函数内部使用了this关键字,那么执行this这行代码的对象是sayHi(一切皆对象的体现),sayHi是被定义在全局作用域中。其实在Javascript中所谓的全局对象,无非是定义在 window这个根对象下的一个属性而已。因此,sayHi的所有者是window对象。也就是说,在全局作用域下,你可以通过直接使用name去引用这个对象,你也可以通过window.name去引用同一个对象。因而this.name就可以翻译为window.name了。

    再来看第二个this的示例。我们定义了一个person的对象,并定义了它的sayHello属性,使其指向sayHi全局对象。那么这个时候,当我们运行person.sayHello的时候,this所在的代码所属对象就是sayHello了(其实准确来说,sayHi和sayHello是只不过类似两个指针,指向的对象实际上是同一个),而sayHello对象的所有者就是person了。第一次,person里面没有name属性,因此弹出的对话框就是this.name引用的就是undefined对象(Javascript中所有只声明而没有定义的变量全都指向undefined对象);而第二次我们在定义person的时候加了name属性了,那么this.name指向的自然就是我们定义的字符串了。

    理解了上面所说的之后,我们将上面最后一段示例改造成面向对象式的代码。

    var name ="Kevin Yang";
    
    function sayHi(){    
    
    alert("你好,我的名字叫"+this.name);  }
    
    function  Person(name){
    
    this.name = name;  
    
    }  
    
    Person.prototype.sayHello = sayHi;
    
    var marry =newPerson("Marry");   
    
    marry.sayHello();
    
    var kevin =newPerson("Kevin");  
    
    kevin.sayHello();
    
    script>
    
    

    在上面这段代码中,我们定义了一个Person的“类”(实际上还是一个对象),然后在这个类的原型(类原型相当于C++中的静态成员变量的概念)中定义了sayHello属性,使其指向全局的sayHi对象。运行代码我们可以看到,marry和kevin都成功的向我们打了声“招呼”。

    image

    相关文章

      网友评论

          本文标题:this指針

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