Javascript this理解
来源:互联网 发布:js 99乘法表的思路 编辑:程序博客网 时间:2024/06/05 08:29
this
关键字
谈到作用域和闭包就不得不说 this
关键字,虽然它们之间关联不大,但是它们一起使用却容易让人产生疑惑。下面列出了使用 this
的大部分场景,带大家一探究竟。
this
是 JavaScript 的关键字,指函数执行时的上下文,跟函数定义时的上下文无关。随着函数使用场合的不同,this
的值会发生变化。但是有一个总的原则,那就是 this
指代的是调用函数的那个对象。
全局上下文
在全局上下文中,也就是在任何函数体外部,this
指代全局对象。
// 在浏览器中,this 指代全局对象 windowconsole.log(this === window); // true
函数上下文
在函数上下文中,也就是在任何函数体内部,this
指代调用函数的那个对象。
函数调用中的 this
function f1(){ return this;}console.log(f1() === window); // true
如上代码所示,直接定义一个函数 f1()
,相当于为 window
对象定义了一个属性。直接执行函数 f1()
,相当于执行 window.f1()
。所以函数 f1()
中的 this
指代调用函数的那个对象,也就是 window
对象。
function f2(){ "use strict"; // 这里是严格模式 return this;}console.log(f2() === undefined); // true
如上代码所示,在「严格模式」下,禁止 this
关键字指向全局对象(在浏览器环境中也就是 window
对象),this
的值将维持 undefined
状态。
对象方法中的 this
var o = { name: "stone", f: function() { return this.name; }};console.log(o.f()); // "stone"
如上代码所示,对象 o
中包含一个属性 name
和一个方法 f()
。当我们执行 o.f()
时,方法 f()
中的 this
指代调用函数的那个对象,也就是对象 o
,所以 this.name
也就是 o.name
。
注意,在何处定义函数完全不会影响到 this
的行为,我们也可以首先定义函数,然后再将其附属到 o.f
。这样做 this
的行为也一致。如下代码所示:
var fun = function() { return this.name;};var o = { name: "stone" };o.f = fun;console.log(o.f()); // "stone"
类似的,this
的绑定只受最靠近的成员引用的影响。在下面的这个例子中,我们把一个方法 g()
当作对象o.b
的函数调用。在这次执行期间,函数中的 this
将指向 o.b
。事实上,这与对象本身的成员没有多大关系,最靠近的引用才是最重要的。
o.b = { name: "sophie" g: fun,};console.log(o.b.g()); // "sophie"
eval()
方法中的 this
eval()
方法可以将字符串转换为 JavaScript 代码,使用 eval()
方法时,this
指向哪里呢?答案很简单,看谁在调用 eval()
方法,调用者的执行环境中的 this
就被 eval()
方法继承下来了。如下代码所示:
// 全局上下文function f1(){ return eval("this");}console.log(f1() === window); // true// 函数上下文var o = { name: "stone", f: function() { return eval("this.name"); }};console.log(o.f()); // "stone"
call()
和 apply()
方法中的 this
call()
和 apply()
是函数对象的方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this
指代的就是这两个方法的第一个参数。
var x = 0; function f() { console.log(this.x); } var o = {}; o.x = 1;o.m = f; o.m.apply(); // 0
call()
和 apply()
的参数为空时,默认调用全局对象。因此,这时的运行结果为 0
,证明 this
指的是全局对象。如果把最后一行代码修改为:
o.m.apply(o); // 1
运行结果就变成了 1
,证明了这时 this
指代的是对象 o
。
bind()
方法中的 this
ECMAScript 5 引入了 Function.prototype.bind
。调用 f.bind(someObject)
会创建一个与 f
具有相同函数体和作用域的函数,但是在这个新函数中,this
将永久地被绑定到了 bind
的第一个参数,无论这个函数是如何被调用的。如下代码所示:
function f() { return this.a;}var g = f.bind({ a: "stone"});console.log(g()); // stonevar o = { a: 28, f: f, g: g};console.log(o.f(), o.g()); // 28, stone
DOM 事件处理函数中的 this
一般来讲,当函数使用 addEventListener
,被用作事件处理函数时,它的 this
指向触发事件的元素。如下代码所示:
<!DOCTYPE HTML><html><head> <meta charset="UTF-8"> <title>test</title></head><body> <button id="btn" type="button">click</button> <script> var btn = document.getElementById("btn"); btn.addEventListener("click", function(){ this.style.backgroundColor = "#A5D9F3"; }, false); </script></body></html>
但在 IE 浏览器中,当函数使用 attachEvent
,被用作事件处理函数时,它的 this
却指向 window
。如下代码所示:
<!DOCTYPE HTML><html><head> <meta charset="UTF-8"> <title>test</title></head><body> <button id="btn" type="button">click</button> <script> var btn = document.getElementById("btn"); btn.attachEvent("onclick", function(){ console.log(this === window); // true }); </script></body></html>
内联事件处理函数中的 this
当代码被内联处理函数调用时,它的 this
指向监听器所在的 DOM 元素。如下代码所示:
<button onclick="alert(this.tagName.toLowerCase());"> Show this</button>
上面的 alert
会显示 button
,注意只有外层代码中的 this
是这样设置的。如果 this
被包含在匿名函数中,则又是另外一种情况了。如下代码所示:
<button onclick="alert((function(){return this})());"> Show inner this</button>
在这种情况下,this
被包含在匿名函数中,相当于处于全局上下文中,所以它指向 window
对象。
关卡
仔细想想,下面代码块会输出什么结果呢?
// 挑战一function func1() { function func2() { console.log(this) } return func2;}func1()(); // ???
// 挑战二scope = "stone";function Func() { var scope = "sophie"; function inner() { console.log(scope); } return inner;}var ret = Func();ret(); // ???
// 挑战三scope = "stone";function Func() { var scope = "sophie"; function inner() { console.log(scope); } scope = "tommy"; return inner;}var ret = Func();ret(); // ???
// 挑战四scope = "stone";function Bar() { console.log(scope);}function Func() { var scope = "sophie"; return Bar;}var ret = Func();ret(); // ???
// 挑战五var name = "The Window"; var object = { name: "My Object", getNameFunc: function() { return function() { return this.name; }; } }; console.log(object.getNameFunc()()); // ???
// 挑战六var name = "The Window"; var object = { name: "My Object", getNameFunc: function() { var that = this; return function() { return that.name; }; } }; console.log(object.getNameFunc()());
- 理解 JavaScript 中的 this
- JavaScript this 深入理解
- 理解JavaScript 中的 this
- JavaScript this个人理解
- Javascript this的理解
- 理解JavaScript中的this
- JavaScript 理解this对象
- JavaScript-this理解
- Javascript this理解
- JavaScript this 的理解
- javascript中的关键字this理解
- 理解 JavaScript 的 this 关键字
- 理解 JavaScript 的 this 关键字
- coffeescript(javascript) this 的理解
- 对javascript的this理解
- JavaScript 对this的理解
- 深入理解javascript之this
- javascript对this的理解
- Linux-重要快捷键
- Xcode 模板路径
- JavaScript或MyEclipse—如何解决js文件导入到MyEclipse工程后出错?
- hdu 2444 二分图匹配 + dfs染色
- Java实现(12)——轻量级模式(FlyWeight Pattern)
- Javascript this理解
- JDK源码学习之String篇
- CentOS 7环境配置tomcat7开机启动
- JS全局变量和局部变量
- 企业网站打不开,自检步骤
- Mac:protobuf proto文件编译为Java文件
- eclipse快捷键、java继承、枚举相关
- 登陆注册的基础知识
- JAVA之小常识