一、关于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!!!
 

随机推荐

  1. codevs 2495 水叮当的舞步IDA*

    /* 比较简单的A* 估价函数很简单就是除了左上角的联通快之外的不同的个数 加上迭代 好像答案最多在16步之内出解 这样裸裸的交上去是50分 在考虑剪枝 每个选颜色的时候一定是选左上角联通快附近的颜色 ...

  2. python函数的使用和返回值

    #coding=utf-8 def a(): i=1a() #函数的返回值,用return语句实现 #一个返回值的情况def test(): i=7 return iprint test() #多个返 ...

  3. POJ题目细究

    acm之pku题目分类 对ACM有兴趣的同学们可以看看 DP:  1011   NTA                 简单题  1013   Great Equipment     简单题  102 ...

  4. 关于图表的JS插件

    http://echarts.baidu.com/ http://echarts.baidu.com/tutorial.html#5%20%E5%88%86%E9%92%9F%E4%B8%8A%E6% ...

  5. 分页技术之GridView控件

    GridView控件实现分页技术 第一步:设置GridView控件的属性,跟分页相关的属性设置如下: AllowPaging="true":允许分页, PageSize=" ...

  6. exp、imp简单测试

    imp 分为以下几个测试场景 imp name1/password1 file=xxxx.dmp  full=y fromuser=name2 touser=name3 场景1 name1正确.pas ...

  7. 【原】push过快的错误 (Pushing the same view controller instance more than once is not supported)

    今天在点击按钮push viewController 时,控制台报错: Terminating app due to uncaught exception 'NSInvalidArgumentExce ...

  8. iOS开发常用的第三方框架

    1. AFNetworking 在众多iOS开源项目中,AFNetworking可以称得上是最受开发者欢迎的库项目.AFNetworking是一个轻量级的iOS.Mac OS X网络通信类库,现在是G ...

  9. Swift进阶

    概述 访问控制 Swift命名空间 Swift和ObjC互相调用 Swift和ObjC映射关系 Swift调用ObjC ObjC调用Swift 扩展—Swift调用C 反射 扩展—KVO 内存管理 循 ...

  10. memset 初始化数组

    memset是初始化一段内存区域的函数,其头文件是<string.h>,以前经常使用出现错误,整理一下. C++ Reference对于memset的定义为: void * memset ...