【前端】JS
2016-01-02 00:44
639 查看
this详解:
以上总结:
练习:
---------------------------------------------------------------------------------------------
下文转自:
http://www.cnblogs.com/justany/archive/2012/11/01/the_keyword_this_in_javascript.html
请看下面的代码,最后alert出来的是什么呢?
this指向哪里?
一般而言,在Javascript中,this指向函数执行时的当前对象。
In JavaScript, as in most object-oriented programming languages,
——jQuery Fundamentals (Chapter 2), by Rebecca Murphey
值得注意,该关键字在Javascript中和执行环境,而非声明环境有关。
The this keyword is relative to the execution context, not the declaration context.
我们举个例子来说明这个问题:
this关键字虽然是在someone.showName中声明的,但运行的时候是other.showName,所以this指向other.showName函数的当前对象,即other,故最后alert出来的是other.name。
没有明确的当前对象时
当没有明确的执行时的当前对象时,this指向全局对象window。
By default,
为什么说是全局对象(the global object),因为非浏览器情况下(例如:nodejs)中全局变量并非window对象,而就是叫“全局变量”(the global object)。不过由于我们这片文章主要讨论的是前端开发知识,所以nodejs就被我们忽略了。
例如对于全局变量引用的函数上我们有:
你可能也能理解成show是window对象下的方法,所以执行时的当前对象时window。但局部变量引用的函数上,却无法这么解释:
setTimeout、setInterval和匿名函数
文章开头的问题的答案是Bob。
在浏览器中setTimeout、setInterval和匿名函数执行时的当前对象是全局对象window,这条我们可以看成是上一条的一个特殊情况。
所以在运行this.showName的时候,this指向了window,所以最后显示了window.name。
浏览器中全局变量可以当成是window对象下的变量,例如全局变量a,可以用window.a来引用。
我们将代码改成匿名函数可能更好理解一些:
在调用nameObj.waitShowName时候,我们运行了一个匿名函数,将nameObj.showName作为回调函数传进这个匿名函数,然后匿名函数运行时,运行这个回调函数。由于匿名函数的当前对象是window,所以当在该匿名函数中运行回调函数时,回调函数的this指向了window,所以alert出来window.name。
由此看来setTimeout可以看做是一个延迟执行的:
setInterval也如此类比。
但如果我们的确想得到的回答是Tom呢?通过一些技巧,我们能够得到想要的答案:
在执行nameObj.waitShowName函数时,我们先对其this赋给变量that(这是为了避免setTimeout中的匿名函数运行时,匿名函数中的this指向window),然后延迟运行匿名函数,执行that.showName,即nameObj.showName,所以alert出正确结果Tom。
eval
对于eval函数,其执行时候似乎没有指定当前对象,但实际上其this并非指向window,因为该函数执行时的作用域是当前作用域,即等同于在该行将里面的代码填进去。下面的例子说明了这个问题:
apply和call
apply和call能够强制改变函数执行时的当前对象,让this指向其他对象。因为apply和call较为类似,所以我们以apply为例:
apply用于改变函数执行时的当前对象,当无参数时,当前对象为window,有参数时当前对象为该参数。于是这个例子Bob成功偷走了Tom的名字。
new关键字
new关键字后的构造函数中的this指向用该构造函数构造出来的新对象:
思考题
1. 请问下面代码会alert出什么,为什么?
2. 请问下面代码会alert出什么,为什么?
3. 下面代码分别在IE和其他浏览器上运行有什么差异,可以用什么方法解决这个差异问题?
IE:
Others:
参考文献
Javascript Closures . Richard Cornford . March 2004
Javascript的this用法 . 阮一峰 . 2010.4.30
alert(this);// object window window.alert(this);//所有东西都属于window下的 function fn() { alert(this); } window.fn();//一般情况下是类似fn();这种,事实上它是window调用的,所以this指向的是window
<body> <input id="btn1" type="button" value="按钮1" /> <input id="btn2" type="button" onclick="alert('btn2:'+this);" value="按钮2" /> <input id="btn3" type="button" onclick="fn(this);" value="按钮3" /> <input id="btn4" type="button" onclick="fn();" value="按钮4" /> <!-- 这里btn2中,onclick是行间事件,这里让alert方法动的是“input”这个元素,所以,这里this指向的是input这个元素:object HTMLInputElement。btn3中,this在括号里面,是input元素让其动的,这个this也是input这个元素,btn4中,this指的是window;类似“fn();”这种,里面的this一般是指向window -->
<script> var oBtn = document.getElementById("btn1"); alert(oBtn);// object HTMLInputElement oBtn.onclick = fn;//点击按钮的时候,弹出内容是:object HTMLInputElement,说明fn()函数中this指向了这个按钮 //通俗地说,就是谁让函数动了,就指向谁 oBtn.onclick = function(){ this //这里匿名函数,指向的仍然是oBtn fn();//这里加个方法,那么这里,fn()里的this就指向window了,不再是按钮oBtn。其实这里是window.fn();所以这里this的当前对象是window,指向window } </script> </body>
以上总结:
// this: 指的是调用 当前 方法(函数)的那个对象 function fn1(){ // this } // fn1(); this => window // oDiv.onclick = fn1; this => oDiv /* oDiv.onclick = function (){ fn1(); fn1() 里的this => window }; <div onclick=" this fn1(); "></div> 第一个this是div;fn1(); 里的 this 指的是 window */
练习:
<title>this的应用</title> <script> window.onload = function(){ var oBtn = document.getElementsByTagName("input"); var that = null; for(var i = 0;i<oBtn.length;i++) { /* oBtn[i].onclick = function(){ //方法一 //this.style.background = "yellow"; //方法二 that = this; fn1(); } */ //方法三 oBtn[i].onclick = fn2; } function fn1() { //this => window that.style.background = 'yellow'; } function fn2() { this.style.background = 'red'; //这里this指的是oBtn[i],因为是点击的那个按钮调用这个方法的 } } </script> </head> <body> <input type = "button" value="按钮1" /> <input type = "button" value="按钮2" /> <input type = "button" value="按钮3" /> </body>
---------------------------------------------------------------------------------------------
下文转自:
http://www.cnblogs.com/justany/archive/2012/11/01/the_keyword_this_in_javascript.html
请看下面的代码,最后alert出来的是什么呢?
<span style="font-size:14px;">var name = "Bob"; var nameObj ={ name : "Tom", showName : function(){ alert(this.name); }, waitShowName : function(){ setTimeout(this.showName, 1000); } }; nameObj.waitShowName();</span>
this指向哪里?
一般而言,在Javascript中,this指向函数执行时的当前对象。
In JavaScript, as in most object-oriented programming languages,
thisis a special keyword that is used within methods to refer to the object on which a method is being invoked.
——jQuery Fundamentals (Chapter 2), by Rebecca Murphey
值得注意,该关键字在Javascript中和执行环境,而非声明环境有关。
The this keyword is relative to the execution context, not the declaration context.
我们举个例子来说明这个问题:
<span style="font-size:14px;">var someone = { name: "Bob", showName: function(){ alert(this.name); } }; var other = { name: "Tom", showName: someone.showName } other.showName(); //Tom</span>
this关键字虽然是在someone.showName中声明的,但运行的时候是other.showName,所以this指向other.showName函数的当前对象,即other,故最后alert出来的是other.name。
没有明确的当前对象时
当没有明确的执行时的当前对象时,this指向全局对象window。
By default,
thisrefers to the global object.
为什么说是全局对象(the global object),因为非浏览器情况下(例如:nodejs)中全局变量并非window对象,而就是叫“全局变量”(the global object)。不过由于我们这片文章主要讨论的是前端开发知识,所以nodejs就被我们忽略了。
例如对于全局变量引用的函数上我们有:
var name = "Tom"; var Bob = { name: "Bob", show: function(){ alert(this.name); } } var show = Bob.show; show(); //Tom
你可能也能理解成show是window对象下的方法,所以执行时的当前对象时window。但局部变量引用的函数上,却无法这么解释:
var name = "window"; var Bob = { name: "Bob", showName: function(){ alert(this.name); } }; var Tom = { name: "Tom", showName: function(){ var fun = Bob.showName; fun(); } }; Tom.showName(); //window
setTimeout、setInterval和匿名函数
文章开头的问题的答案是Bob。
在浏览器中setTimeout、setInterval和匿名函数执行时的当前对象是全局对象window,这条我们可以看成是上一条的一个特殊情况。
所以在运行this.showName的时候,this指向了window,所以最后显示了window.name。
浏览器中全局变量可以当成是window对象下的变量,例如全局变量a,可以用window.a来引用。
我们将代码改成匿名函数可能更好理解一些:
var name = "Bob"; var nameObj ={ name : "Tom", showName : function(){ alert(this.name); }, waitShowName : function(){ !function(__callback){ __callback(); }(this.showName); } }; nameObj.waitShowName(); //Bob
在调用nameObj.waitShowName时候,我们运行了一个匿名函数,将nameObj.showName作为回调函数传进这个匿名函数,然后匿名函数运行时,运行这个回调函数。由于匿名函数的当前对象是window,所以当在该匿名函数中运行回调函数时,回调函数的this指向了window,所以alert出来window.name。
由此看来setTimeout可以看做是一个延迟执行的:
function(__callback){ __callback(); }
setInterval也如此类比。
但如果我们的确想得到的回答是Tom呢?通过一些技巧,我们能够得到想要的答案:
var name = "Bob"; var nameObj ={ name : "Tom", showName : function(){ alert(this.name); }, waitShowName : function(){ var that = this; setTimeout(function(){ that.showName(); }, 1000); } }; nameObj.waitShowName(); //Tom
在执行nameObj.waitShowName函数时,我们先对其this赋给变量that(这是为了避免setTimeout中的匿名函数运行时,匿名函数中的this指向window),然后延迟运行匿名函数,执行that.showName,即nameObj.showName,所以alert出正确结果Tom。
eval
对于eval函数,其执行时候似乎没有指定当前对象,但实际上其this并非指向window,因为该函数执行时的作用域是当前作用域,即等同于在该行将里面的代码填进去。下面的例子说明了这个问题:
var name = "window"; var Bob = { name: "Bob", showName: function(){ eval("alert(this.name)"); } }; Bob.showName(); //Bob
apply和call
apply和call能够强制改变函数执行时的当前对象,让this指向其他对象。因为apply和call较为类似,所以我们以apply为例:
var name = "window"; var someone = { name: "Bob", showName: function(){ alert(this.name); } }; var other = { name: "Tom" }; someone.showName.apply(); //window someone.showName.apply(other); //Tom
apply用于改变函数执行时的当前对象,当无参数时,当前对象为window,有参数时当前对象为该参数。于是这个例子Bob成功偷走了Tom的名字。
new关键字
new关键字后的构造函数中的this指向用该构造函数构造出来的新对象:
function Person(__name){ this.name = __name; //这个this指向用该构造函数构造的新对象,这个例子是Bob对象 } Person.prototype.show = function(){ alert(this.name); } var Bob = new Person("Bob"); Bob.show(); //Bob
思考题
1. 请问下面代码会alert出什么,为什么?
var name = "Bob"; var nameObj ={ name : "Tom", showName : function(){ alert(this.name); }, waitShowName : function(){ var that = this; setTimeout("that.showName();", 1000); } }; nameObj.waitShowName();
2. 请问下面代码会alert出什么,为什么?
var fun = new Function("alert(this)"); fun();
3. 下面代码分别在IE和其他浏览器上运行有什么差异,可以用什么方法解决这个差异问题?
IE:
<button id = "box" name = "box">Click Me!</button> <script> var name = "window"; function showName(){ alert(this.name); } document.getElementById("box").attachEvent("onclick", showName); </script>
Others:
<button id = "box" name = "box">Click Me!</button> <script> var name = "window"; function showName(){ alert(this.name); } document.getElementById("box").addEventListener("click", showName, false); </script>
参考文献
Javascript Closures . Richard Cornford . March 2004
Javascript的this用法 . 阮一峰 . 2010.4.30
相关文章推荐
- javascript markdown 解析器
- 十步图解CSS的position
- ubuntu安装wkhtmltopdf
- React Native Android配置部署踩坑日记
- jquery实现简单的全选和反选功能
- JS Array.slice 截取数组的实现方法
- 【嘉兴东臣php】HTML5、CSS3
- 【嘉兴东臣php】HTML5和CSS3学习周总结
- jquery 基础总结
- jQuery插件
- jQuery选择器性能
- javascript window.confirm确认 取消对话框实现代码小结
- Google protocol buffer 的反射机制和应用
- 【前端】HTML基础
- HTML 字符图案
- Web前端开发实战5:导航菜单(二)
- js笔记(4)
- jquery 1.9后如何对动态生成的元素绑定事件
- $("").click与onclick的区别示例介绍
- 在JS中整段地写HTML