zoukankan      html  css  js  c++  java
  • 关于困惑已久的var self=this的解释--转载

    原文地址 http://skybirdzw.blog.163.com/blog/static/7257062620141605323321/

    关于困惑已久的var self=this的解释  

    首先说下this这个对象的由来(属于个人理解):
    每个函数在定义被ECMAScript解析器解析时,都会创建两个特殊的变量:this和arguments,换句话说,每个函数都有属于自己的this对象,这个this对象是在运行时基于函数的执行环境绑定的,即在全局对象中,this指向的是window对象;在自定义函数中,this对象指向的是调用这个函数的对象,
    也就是说,this指向的是调用执行环境的那个对象。
    如果是在函数嵌套环境中,this指代的是调用外部函数或者内部函数的执行环境的对象;

    (注意:可以通过使用call()或者apply()改变函数执行环境的情况下,this就会指向其他对象。)

    哎。。以上的描述还是有点啰嗦,那么就看例子吧:
     /*----- 2014-2-10 这个例子是错误的 -----*/
    function BaseType(name,age){
        //用一个变量保存当前函数执行环境中的this对象
        //这里可能会有疑问:为什么非得把this保存起来呢?这是因为,内部函数(比如本函数里面包含的两个匿名函数)
        //在搜索this变量时,只会搜索到属于它自己的this,而不会搜索到包含它的那个函数的this。
        //所以,为了在内部函数能使用外部函数的this对象,要给它赋值了一个名叫self的变量。
        var self=this; 
        this.name=name;
        this.age=age;
        this.sayHello=function(){
            console.log("My name is "+this.name+", and i'm "+this.age+"years old.");
        }
        this.saySomething=function(){
               //此处用法有点欠妥,完全可以不用self,而用this
               //self.sayHello();
               //正确的做法是:
               return function () { self.sayHello(); }
               //详见:http://skybirdzw.blog.163.com/blog/static/72570626201411032516719/  

        }
    }
    var b1=new BaseType("wede",30);
    b1.saySomething(); //My name is wede, and i'm 30years old. 

    从结果来看,是预期的结果。
    那么这里可能又会出现新的疑问:为什么在saySomething()方法中非要用self.sayHello()来调用呢,
    直接sayHello()多好?
    其实这又涉及到另一个话题:实例成员与局部成员。
    我们创建构造函数的意义就是要用它来创建实例,那么所有属于实例的成员都需要用this来定义;
    而只有那些不属于实例的成员才不会用this定义;
    当然,用this定义了方法以后,在函数作用域内部要调用此方法时,就需要加上this了。

    为了证明这一点,来看下面的代码:
    function BaseType(name,age){
        var self=this;
        this.name=name;
        this.age=age;
        this.sayHello=function (){
            console.log("My name is "+this.name+", and i'm "+this.age+"years old.");
        }
        this.saySomething=function(){
            sayHello();
        }
    }
    var b1=new BaseType("wede",30);
    b1.saySomething(); //ReferenceError: sayHello is not defined
    结果显示:sayHello方法未定义。
    就是说明,我们调用的其实是局部方法sayHello,而现在只有实例方法sayHello,所以会出现异常。

    下面来改装下(注意加粗的部分):
    function BaseType(name,age){
        var self=this;
        this.name=name;
        this.age=age;
        var sayHello=function (){
            console.log("My name is "+name+", and i'm "+age+"years old.");
        }

        this.saySomething=function(){
            sayHello();
        }
    }
    var b1=new BaseType("wede",30);
    b1.saySomething();//My name is wede, and i'm 30years old.

    可以看出,输出了预期的结果。
    而这时候,我们把sayHello方法变成了一个局部方法(对于实例不可见),然后再在saySomething方法中调用就可以了。
  • 相关阅读:
    输入输出那些事
    NYOJ 20
    NYOJ 283
    HDU 1285
    HDU 2639(第K大背包)
    HDU 4288
    对Visual Studio C++ hash_map严谨一点的测试转载
    vc6,vc.net,vc7,vc8,vc9,c,c++,c#的区别与联系
    我在南大的七年刘末鹏
    慎用Visual Studio C++默认的hash_map转载
  • 原文地址:https://www.cnblogs.com/azterzmshan/p/4705073.html
Copyright © 2011-2022 走看看