zoukankan      html  css  js  c++  java
  • 关于javascript中this 指向的4种调用模式

     

    this指向问题绝对可以排js 的top 5最难和最重点的问题,初学者常常搞不清楚this指向哪里,特别是学过java和c#的人,想当年俺也迷糊了好久,直到遇到蝴蝶书,主要是因为js和主流的面向对象语言java,c#都不同(相似的问题还有new 操作符的问题,

    关于new 构构器函数的原理,参见这篇文章:

    http://www.cnblogs.com/windyfancy/p/5167266.html

    ),this并不指向当前对象,这是理解this的关键所在,this的指向取决于你是采用何种方式调用this所在的这个函数的,其实也只有四种调用模式,搞清楚了就以不变应万变。蝴蝶书(javascript语言精髓)里总结的最清楚,在javascript中一共有四种调用模式:方法调用模式,函数调用模式,构造器调用模式,apply/call调用模式。这些模式在如何初始化关键参数this上存在差异。

    1   .方法调用模式(对象名.方法名(),或对象名[“方法名”]())

    当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。如果一个调用表达式包含一个属性存取表达式(即一个.点表达式或者[subscript]下标表达式),那么它被当做一个方法来调用

    var myObject = {

    value :0,

    increment:function (inc){

    this.value += typeof inc ==='number' ? inc:1;

    }

    };

    myObject.increment();

    document.writeln(myObject.value);  //1

    myObject.increment(2);

    document.writeln(myObject.value);  //3

    方法可以使用this去访问对象,所以它能从对象中取得或修改该对象。this到对象的绑定发生在调用的时候。这个“超级”迟绑定( very late binding)使得函数可以对this高度复用。通过this可取得它们所属对象的上下文的方法称为公共方法。

    2 .函数调用模式

    当一个函数并非一个对象的属性是,那么它被当做一个函数来调用:var sum = add(3,4); //sum的值为7,当函数以此模式调用时,this被绑定到全局对象window上。这是语言设计上的一个错误,倘若语言设计正确,当内部函数被调用时,this应该仍然绑定到外部函数的this变量。这个设计错误错误的后果是方法不能利用内部函数来帮助它工作,因为内部函数的this被绑定了错误的值,所以不能共享该方法对对象的访问权。幸运的是,可以利用闭包特性保存this到一个自定义变量:如果该方法定义一个变量并给他赋值为this,那么内部函数就可以通过那个变量访问到this。

    //给myObject增加一个double方法

    myObject.double = function(){

     var self = this; //解决方案

     var doubleFn = function(){

        self.value = self.value*2;

     };

     doubleFn ();//以函数的形式调用

    };

    //以方法的形式调用double

    myObject.double();

    document.writeln(myObject.getValue()); //6

    3 . 构造器函数调用模式

    使用new 方式调用一个函数,那么这个函数被称之为构造器函数,这个构造器函数会创建出来一个新生的对象,这个新生对象的constructor指向这个构造器函数。

    Function myFun(){

             this.color=”red”;

    }

    var obj=new myFun();

    console.log(obj.color); //red;

    关于new 构构器函数的原理,参见这篇文章:

    http://www.cnblogs.com/windyfancy/p/5167266.html

    4  .apply/call 调用方式

    apply调用方式最为强大,可以指定this为任意对象,call的功能和apply一样,只是接收的参数有区别。

    var user={

    name:'windy',

    say:'hello,world'

    }

    var obj={

            test:function(){

                       alert(this.name+':'+this.say);

    }

    }

    obj.test.apply(user);

  • 相关阅读:
    引用赋值的问题
    mysql的笔记
    输入法失败
    eclipse的快捷键
    c++/c在两个文件公用一个变量
    用c++ sttring检测名字是否有空格
    QLineEdit的信号函数
    c++博客转载
    qt-博客
    QT聊天室--重大bug
  • 原文地址:https://www.cnblogs.com/windyfancy/p/5167209.html
Copyright © 2011-2022 走看看