博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js中var self=this的解释
阅读量:5971 次
发布时间:2019-06-19

本文共 2090 字,大约阅读时间需要 6 分钟。

hot3.png

每个函数在定义被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(); }

           //通常用法:将上下文this缓存到一个变量中

           //以便在本函数作用域内包含另一个函数作用域的情况下可以继续使用此上下文对象this
           //如果省略var self=this; 这行,那么在嵌套函数作用域内就无法访问到本函数作用域的成员了。         

    }

}
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方法中调用就可以了。

转载于:https://my.oschina.net/leohouse/blog/648398

你可能感兴趣的文章
html loader使用方法,webpack中loader的使用方法,以及几个常用loader的应用小实例
查看>>
网管必读的两本职业指南图书封面闪亮登场啦
查看>>
安装、部署DPM 2012 R2服务器
查看>>
84天平美女征婚【非诚勿扰】
查看>>
一个资深系统管理员的O2O实践(四)
查看>>
VMM2012应用指南之9-向VMM中添加VMware ESX Server主机
查看>>
ubuntu无法修改ROOT密码的问题解决
查看>>
【虚拟化实战】VM设计之二内存机制
查看>>
SCOM 2012系列⑧即时消息通知下
查看>>
TestLink与RedMine连接部署说明
查看>>
自动部署LNMP脚本
查看>>
Linux系统程序包管理工具-RPM
查看>>
粗浅记录Oracle RAC系统内存无法释放
查看>>
Provisioning Services 7.8 入门系列教程之十三 使用 Boot Device Management(BDM)
查看>>
Python回顾与整理5:映像和集合类型
查看>>
Redhat 与Windows下的远程桌面
查看>>
MySQL Connector/Net 句柄泄露
查看>>
MacOS Sierra升级问题小记
查看>>
python 时间模块备忘
查看>>
一致性哈希算法的理解
查看>>