this指向 最简单的两种!
来源:互联网 发布:网络教学的定义 编辑:程序博客网 时间:2024/06/06 20:31
原文地址:http://www.zhangyunling.com/?p=251
概述
首先有一点要先明确,那就是this是一个引用类型,也就是说,它是一个对象。OK,概述结束。
基础示例
首先,让我们先看下,this到底是指向的哪些对象呢?那就先看一些例子:
function testCallback(){ if(this === window){ console.log("this === window"); }else if(this === document){ console.log("this === document"); }else if(this === a){ console.log("this === a"); } } testCallback(); //this===window document.onclick = testCallback; //this === document var a = {}; a.callback = testCallback; a.callback(); //this === a
上述三种最简单的情况,应该也算是我们最常见的了吧。说是三种,其实也只能算是两种吧,因为document.onclick和a.callback的两种,其实质是相同的,只是对象名和属性名是不同的。
所以,我们可以先根据上面的情况,把this的指向,定义为两种:
1:一种是如果显示的在一个对象上直接调用了一个方法,那么其中的this就是指向这个显示的对象。
2:第二种是,如果没有显示的调用的话,比如之前代码中,直接使用testCallback()执行函数,那么其中的this,就是指向window对象的。
为什么没有显示的对象调用时,this是指向window对象呢?记得我们在最初学习JS时有过这样的描述吧,如果没有使用var定义一个变量,即便是在局部作用域定义,这也是一个全局变量,而全局变量是会被添加到window对象中,作为其中的一个属性的,所以,之前的testCallback方法,其实是存在于window对象中的一个方法。所以,这里不算是显示的调用,但是如果把这种调用方法写的完全的话,应该是window.testCallback()的写法,所以,按照显示调用的说法,也是正确的。
OK,上述的两种说法,只是在我们平常的一些基本的写法的,比如,在使用DOM2级事件绑定中,回调函数的内部,其this的指向,就和我们常说的有些区别。
例如:
function testCallback(){ if(this === window){ console.log("this === window"); }else if(this === document){ console.log("this === document"); } } function addEvent(obj,type,callback){ if(obj.addEventListener){ obj.addEventListener(type,callback,false); }else if(obj.attachEvent){ obj.attachEvent("on"+type,callback); }else{ var fn = obj["on"+type]; obj["on"+type] = function(){ fn && fn(); callback(); } } } addEvent(document,"click",testCallback);
这个时候,当你点击当前页的任意位置,都可以触发该事件,这时你会发现些什么问题呢?这个时候,你就会发现一个问题,在IE9+的浏览器中,当你点击时,会出现"this === document"的显示,这个时候,也就是,我们这个事件在哪个HTML对象上绑定,那么回调函数中的this就是指向这个绑定的对象的,之前的代码中,点击事件是绑定在document对象上的,所以,this等于document是很正常的了,也是我们希望的结果。
而在IE9-的浏览器中,显示的结果却是“this === window”,这就导致了一个问题,那就是,我们并不能确认自己的代码只会在IE9+的浏览器中运行,所以这个时候,就不能直接使用this进行处理,但是如果不使用this,获取到对应的触发元素,又有些麻烦(这里只考虑原生的JS,不考虑框架中的实现),所以,为了减少这种错误的情况出现,只能放弃使用this了。
前面之所以在IE9-的浏览器事件的回调函数中,this指向window的原因,也是因为,在IE9-的浏览器中,HTML的DOM元素的对象,并不是继承自Object对象的,所以和其他浏览器下,DOM元素的对象继承自Object对象,是有很大的差距的。
只需要下面的一行代码,既可以验证DOM元素的对象是否继承自Object对象。
console.log(document instanceof Object);
练习一下
基础的东西,暂时就能想到这么些了,自我感觉应该也是差不多了,现在给几个例子,看下是否能正确的理解到this的指向问题:
例子1,请看其中注释处,分别打印出的结果是什么:
var a = { name:"zhang", sayName:function(){ console.log("this.name="+this.name); } }; var name = "ling"; function sayName(){ var sss = a.sayName; sss(); //this.name = ? a.sayName(); //this.name = ? (a.sayName)(); //this.name = ? (b = a.sayName)();//this.name = ? } sayName();
例子2:
var sex = "male"; var saySex = { sex:"female", saySex:function(){ function getSex(){ console.log("this.sex="+this.sex); } getSex(); } } saySex.saySex(); //this.sex = ? var ccc = saySex.saySex; ccc();//this.sex = ?
例子3:该例和例2只有一点点变化:
var sex = "male"; var saySex = { sex:"female", saySex:function(){ function getSex(){ console.log("this.sex="+this.sex); } getSex.call(this); //与例2只有这个地方的变化 } } saySex.saySex(); //this.sex = ? var ccc = saySex.saySex; ccc();//this.sex = ?
例4:
var name = "ling"; function sayName(){ var a = { name:"zhang", sayName:getName }; function getName(){ console.log(this.name); } getName(); //this.name = ? a.sayName(); //this.name = ? getName.call(a);//this.name = ? } sayName();
例5(当点击页面时,就会触发):
var name = "ling"; var obj = { name:"zhang", sayName:function(){ console.log("this.name="+this.name); }, callback:function(){ var that = this; return function(){ var sayName = that.sayName; that.sayName(); //this.name = ? sayName();//this.name = ? } } } function addEvent(obj,type,callback){ if(obj.addEventListener){ obj.addEventListener(type,callback,false); }else if(obj.attachEvent){ obj.attachEvent("on"+type,callback); }else{ var fn = obj["on"+type]; obj["on"+type] = function(){ fn && fn(); callback(); } } } addEvent(document,"click",obj.callback());
这里,暂时就能想到这么些使用的地方,其实也可以归纳一下:
首先,不管是函数最初定义在哪里,它其中的this指向,只和这个函数的调用方法有关。
fn()这种写法的this,肯定是指向window对象的。
obj.fn();这样写法的this,肯定是指向obj对象的。
这里不考虑call和apply强行改变this指向的关系,
0 0
- this指向 最简单的两种!
- 简单的几种this指向
- JavaScript的三种this指向问题
- this指向的4种场景
- JS this的指向
- JavaScript-this的指向
- js的this指向
- this对象的指向
- this的指向
- this的指向
- javascript的this指向
- this的指向问题
- javascript this的指向
- 关于this的指向
- this对象的指向
- 关于this的指向
- this的指向
- 修改this的指向
- SCSI、FC、iSCSI三大协议概述
- RecyclerView 使用详解
- Java网络编程介绍
- 安卓动画之属性动画(Property Animation)
- mybatis
- this指向 最简单的两种!
- Oauth认证-新浪微博开发(下)
- CNN(卷积神经网络)、RNN(循环神经网络)、DNN(深度神经网络)的内部网络结构区别
- RX操作符之结合操作(startWith、merge、mergeDelayError、zip、join、groupjoin、switchOnNext)
- OpenCV学习笔记(一)——软件配置详述
- 167.Which three descriptions are correct about the effects of the TRUNCATE command on a table? (Choo
- 块级元素与内联元素的区别
- 隐藏tabwidgt 用radiogroup来实现tab的切换
- JAVA Arrays.binarySearch