关于this的使用
一、关于this的使用
javaScript的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境
二、具体到实际应用中,this指向大致可以分为以下4种:
1、作为对象的方法调用
2、作为普通函数调用
3、构造器调用
4、Function.prototype.call和Function.prototype.apply调用
三、闭包中使用this对象会导致的一些问题
this对象是在运行时基于函数的执行环境绑定的,
1、在全局环境中,this 等于 window
2、当函数被作为某个对象的方法调用时,this 等于 (那个对象)
3、匿名函数的执行环境具有全局性,因此其this对象通常指向window
//1作为对象的方法调用
//当函数作为对象的方法被调用时,this指向该对象
var obj = {
a:1,
getA:function(){
console.log(this); // 输出 Object
console.log(this.a); //输出 1
}
};
obj.getA(); //2.作为普通函数调用
//当函数不作为对象的属性被调用时,此时的this总是指向全局对象。在javaScript中这个全局对象是window对象
window.name = "globalName";
var getName1 = function (){
return this.name;
};
console.log(getName1()); // 输出 globalName //有时候我们会遇到一些困扰,比如在div节点的事件函数内部,
//有一个局部的callback方法,callback被作为普通函数的调用时,
//callback内部的this指向了window,但我们往往是想让它指向该div节点 window.id = "windowId";
document.getElementById("div1").onclick = function (){
console.log(this.id);//div1
var callback = function(){
console.log(this.id);//输出windowId,指向全局window对象----???
};
callback();// 自执行函数中的this指向window
}; //一种简单的解决方案,用一个变量保存div节点的引用
window.id = 'windowId';
document.getElementById("div1").onclick = function(){
var that = this; //保存div的引用
var callback = function(){
console.log(that.id); // 输出div1
};
callback();
}; /*ES5下的严格模式下,这种情况下的this已经被规定为不会指向全局对象,而是undefined*/
function func(){
"use strict";
console.log(this);//注意为undefined
}
func(); //3.构造器的调用
//当用new操作符调用函数时,该函数总会返回一个对象,通常情况下,构造器里的this指向返回的那个对象 var MyClass = function (){
this.name = "six";
}; var obj = new MyClass();//大部分js函数都可以当做构造器使用 console.log(obj.name);//six /*
* 注意:使用new调用构造器时,还要注意一个问题,如果构造器显示的返回了一个object类型的对象,
* 此次的运算结果最终会返回这个对象,而不是我们之前期待的this
*
* */
var MyClass = function(){
this.name = "GoUp";
return {//构造器显示的返回了一个object类型的对象
name:"lalala"
};
}; var obj = new MyClass();
console.log(obj.name);//lalala /*
* 注意:如果构造器不显示任何类型数据,或者返回一个非对象类型的数据,就不会造成上述问题
*
* */
var MyClass = function(){
this.name = "GoUp";
return 'kakaka';//返回string类型
}; var obj = new MyClass();
console.log(obj.name);//GoUp //4.用call()和apply()方法可以修改this的指向
var obj1 = {
name:'seven',
getName:function(){
return this.name;
}
};
var obj2 = { name:'anne'};
console.log(obj1.getName()); // 'seven'
console.log(obj1.getName.call(obj2));// 'anne' /*
注意:经常遇到问题:丢失this
* */ var obj = {
myName:'seven',
getName:function(){
return this.myName;
}
};
console.log(obj.getName());//seven
var getName2 = obj.getName;
console.log(getName2);//function (){return this.myName;}
console.log(getName2());//undefined
/* 当调用obj.getName时,getName方法是作为obj对象的属性被调用的,此时的this指向obj对象,所以obj.getName()输出'seven'
当用另外一个变量getName2来引用obj.getName,并且调用getName2时,此时是普通函数调用方式,this指向全局window,所以执行结果是undefined
*/ //闭包中出现的问题
var name = "The Window"; //全局变量
var object = {
name : "My Object",
getNameFunc : function(){
return function(){ // 返回匿名函数
return this.name; //this指向全局对象window
};
}
};
console.log(object.getNameFunc()());//The Window var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;//把外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了
return function(){
return that.name;
};
}
};
console.log(object.getNameFunc()());//My Object!!!
随机推荐
- servlet 配置到服务器
最近写了个安卓项目,服务端用的servlet.因为第一次写java项目,写完如何发布不是太清除,于是把这回经理写出来,一来做个记录,二来也给和我同样经历的朋友一点启示. 首先配置你的java主机和你的 ...
- 把C#对象转换为json字符串
下面的代码写在ashx一般处理程序中 声明context.Response.ContentType = "application/json";代表服务器端返回的数据为json字符串 ...
- 转载:C# HashSet 用法
原文地址:http://www.cnblogs.com/xiaopin/archive/2011/01/08/1930540.html 感谢博主分享! NET 3.5在System.Collect ...
- 如何做高大上的网站布局 -------------------->>转至(卧牛SEO/武汉SEO http://blog.sina.com.cn/zhengkangseo )
SEO开始做,最重要的是网站布局,一个网站布局决定了用户在网站的停留时间,在网站中放入用户想要的内容之外,更重要的是要让用户看到网站之后,一目了然,视觉和感官上良好的体验.那新手该如何做网站布局呢? ...
- [转] iOS SDK:iOS调试技巧
原文: http://www.cocoachina.com/ios/20130517/6225.html 为什么你的数组包含3个项目而不是5个?为什么你的游戏运行缓慢?这些都跟调试有关,调试是开发过 ...
- 本地代码上传 -> Github
首先在控制台cd到你的本地项目,这里以teat为例 1.执行命令: git init 2.将项目文件添加到仓库中: git add . (可以是指定文件,将“.”转换为指定文件) 3.接下来com ...
- PHP MySQL 预处理语句
PHP MySQL 预处理语句 预处理语句对于防止 MySQL 注入是非常有用的. 预处理语句及绑定参数 预处理语句用于执行多个相同的 SQL 语句,并且执行效率更高. 预处理语句的工作原理如下: 预 ...
- protobuf的反射机制
反射机制 java在运行状态时,能够知道任意类的所有属性和方法,都能够调用任意对象的任意方法和属性.这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. C++本身没有反射机制. ...
- 每日一算法【one】
//有一个数组 {1,2,3,4,5,6,7,8,9,12,13,45,67,89,99,101,111,123,134,565,677} 查找数组中是否有指定的某一个数. /** *------- ...
- fedora 安装nginx+php+mysql
环境 fedora 最新版 20 参考:http://www.cnblogs.com/beceo/archive/2012/08/21/2648378.html ------------------- ...