Javascript:this用法
#Javascript:this用法整理
pingan 于 星期三, 18/12/2013 - 22:32 提交
常用Javascript的人都知道,[this这个关键字在一个函式内究竟指向谁]的这个问题很令人头大,本人在这裡整理了一下Javascript中this的指向的五种不同情况,其中前三种属于基本的情况,而后两种情况可基于前三种情况的方式来进行思考。
1.this指向于调用该函式之物件
如果你有学过C/C++,你可能会记得一个物件内的成员函式裡的this指的即是该成员函式所在之物件,但在Javascript裡则有那麽些许不同,Javascript裡的this看的是究竟是谁调用该函式,而不是看该函式被定义在哪个物件内,这个大原则抓到了,基本上就已经可以探知this的奥秘了。底下写一下这种情况的公式与范例:
公式
1 物件.函式(); //函式内的this指向该物件
范例
var obj = {
x: 20,
f: function(){ console.log(this.x); }
};
obj.f(); //由于调用f函式时,点前面物件为obj,故f内的this指向obj,则输出为20。
obj.innerobj = {
x: 30,
f: function(){ console.log(this.x); }
}
obj.innerobj.f(); //由于调用f函式时,点前面物件为obj.innerobj,故f内的this指向obj.innerobj,则输出为30。
2.this指向全域物件(浏览器:window物件、node.js:GLOBAL物件)
如果调用函式的前方并未有物件,则函式内this就指向全域物件。在浏览器内全域物件为window物件,而在node.js中全域物件则为GLOBAL物件。底下一样写一下这种情况的公式与范例:
公式
函式(); //函式内的this指向全域物件
范例
var x = 10;
var f = function(){
console.log(this.x);
};
f(); //由于调用f函式时,前方并未有[物件.]的形式,故f内的this指向全域物件,则输出全域变数的x(10)。
例外:在使用node.js时,若使用node file.js这样的方式执行js档,并不会让宣告的全域变数挂在全域物件上(意指会利用function将code整个包起来执行),故输出应为undefined。
前两种情况常见误导范例
范例一、物件之成员函式内有函式(感谢NSLin在实务读书会上的范例Code)
example1.js
var x = 10;
var obj = {
x: 20,
f: function(){
console.log(this.x);
var foo = function(){ console.log(this.x); }
foo(); // (2)
}
};
obj.f(); // (1)
这个范例会输出多少呢?别忘记大原则,在Javascript裡的this看的是究竟是谁调用该函式,故并不会输出20 20,而是输出20 10,为什麽呢?因为(1)obj.f()调用时,f前面物件为obj,故f内的this指向obj。但因为调用f内的(2)foo函式时是用foo(),调用的前方并未有物件,故foo内的this指向全域物件,所以输出会是全域变数的x的值。
若要让foo内使用obj.x的值,解法如下:
example1.js
var x = 10;
var obj = {
x: 20,
f: function(){
console.log(this.x);
var that = this; //使用that保留在这个函式内的this
var foo = function(){ console.log(that.x); } //使用that取得obj
foo();
}
};
obj.f();
范例二、借用函式
example2.js
var x = 10;
var obj = {
x: 20,
f: function(){ console.log(this.x); }
};
obj.f(); // (1)
var fOut = obj.f;
fOut(); //(2)
var obj2 = {
x: 30,
f: obj.f
}
obj2.f(); // (3)
范例中三次调用之函式的this所指向的物件为何,不知道各位能不能看得出来。虽然用的是同一个函式,但是因为调用的不同,故this所指向的物件就不同。(1)obj.f()的f所指向的是obj,这比较没有问题,输出的会是20;而(2)fOut()裡的this,则是因为调用时前方无物件,则this所指的是全域物件,输出的会是10;最后(3)obj2.f()则是obj2去呼叫f,故f内的this指向的是obj2,输出的会是30。
3.this指向利用call或apply所指派给this的物件
有个方法可以更改前两种叙述中this指派的值,就是利用call与apply。call与apply都是呼叫该函式并让该函式的this指向给予call或apply的第一个参数。至于call和apply的差别则是在于其后面给予被调用之函式的参数放入的方法不同,一个是直接摊平放在第二个以后的参数;一个是直接放入一个裡面放要给予之参数的阵列。底下一样看一下公式和范例:
公式
(A物件.)函式.call(B物件,参数1,参数2,参数3, ......); //函式的this指向B物件(若B物件为null,则指向全域物件)
(A物件.)函式.apply(B物件,[参数1,参数2,参数3, ......]); //函式的this指向B物件(若B物件为null,则指向全域物件)
范例
var obj = {
x: 20;
f: function(){ console.log(this.x); }
};
var obj2 = {
x: 30;
};
obj1.f.call(obj2); //利用call指派f的this为指向obj2,故输出为30
4.this指向new所产生之新物件
若将函式当作建构式(constructor)来用,则内部的this则指向于new所产生之新物件。
公式
new 建构式(); //建构式内之this指向new所产生之新物件
范例
function Monster(){
this.hp = 100;
};
var monster = new Monster(); //Monster的this指向new出来之新物件并回传回来,new的写法就类似于下面的写法。
var monster = (function(){
var _new = {
constructor: Monster,
__proto__: Monster.prototype
}; //在IE内可能不相似
_new.constructor(); //这也是为何说可以利用前三种情况来变化的原因,constructor呼叫时,this指向的即是_new这个物件。
return _new;
})();
5.callback函式内的this会指向于调用放入该callback的函式之this所指向之物件
先想想在jQuery中,我们若要让#button这个元素被click的时候,内容改为“Clicked”这样的字串,该如何写呢?
clicked.js
$('#button').click(function(){
this.html("Clicked");
})
此时这个this居然会指向$(‘#button’)这个物件,感觉很自然,但实际想想会觉得很神奇。假设你写一个function,它可以传入一个function,并在里面呼叫传入的function,你该怎么写呢?
function-to-function.js
var f = function(innerf){
//前面的处理
innerf(arg1, arg2, arg3, ......);
//后面的处理
}
但如果这样写的话,innerf里的this根据前述规则就应该是全域物件了!那为什么常常别人实作的callback函式可让this指向于调用放入该callback的函式之this所指向之物件呢?这表示大家实际上会遵守一个规则,会将自己的this传给callback当作它的this来用!这也是为什麽我说这个情况其实也是前三种情况的变化而已了!所以上面的code应该改成如下的形式会比较好:
function-to-function-improved.js
var f = function(innerf){
//前面的处理
innerf.call(this, arg1, arg2, arg3, ......);
//或是innerf.apply(this, [arg1, arg2, arg3, ......])
//后面的处理
}
转载于:https://www.cnblogs.com/pingan1314/p/javascript_this.html
Javascript:this用法相关推荐
- JavaScript:switch用法
JavaScript:switch用法 基本语法 switch(n){ case 1: 代码块1 break; 代码块2 语句: break; default: 代码块3 break; } 先定义一个 ...
- JavaScript setTimeout用法,js setTimeout带参数
JavaScript setTimeout用法,js setTimeout带参数 ================================ ©Copyright 蕃薯耀 2021-07-07 ...
- javascript:void(0)和javascript:;的用法
一.JavaScript:void(0) 我们经常会使用到 javascript:void(0) 这样的代码,那么在 JavaScript 中 javascript:void(0) 代表的是什么意思呢 ...
- Javascript Promise用法详解
1.约定 本文的 demo 代码有些是伪代码,不可以直接执行. 没有特殊说明,本文所有 demo 都是基于 ES6 规范. Object.method 代表是静态方法, Object#method 代 ...
- javascript call用法及好处
javascipt 中 Call的用法及好处 javascript call可以改变当前函数的作用域, 基本用法如下 function Person(name){this.name = name; } ...
- javascript opener 用法
window.opener 的用法在一般的用法中,只是用来解决关闭窗口时不提示弹出窗口, 而对它更深层的了解一般比较少. 其 实 window.opener是指调用window.open方法的窗口. ...
- javascript this用法小结
this是面向对象语言中的一个重要概念,在JAVA,C#等大型语言中,this固定指向运行时的当前对象.但是在javascript中,由于 javascript的动态性(解释执行,当然也有简单的预编译 ...
- Javascript typeof用法
在js里用到数组,比如 多个名字相同的input, 若是动态生成的, 提交时就需要判断其是否是数组. if(document.mylist.length != "undefined" ...
- 55个javascript经典用法
1. οncοntextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键 <table border οncοntextmenu ...
- javascript 基本用法
1.javascript简介*基于对象和事件驱动的语言,应用于客户端-基于对象提供了很多对象,可以直接拿过来使用-事件驱动html做网站静态效果,javascript能够呈现动态效果-客户端:专门指浏 ...
最新文章
- 对C语言程序进行编译时 针对以下情况,linux书上划的题的答案.doc
- Java黑皮书课后题第8章:**8.11(游戏:九个硬币的正反面)一个3*3的矩阵中放置了9个硬币,这些硬币有些面朝上有朝下。1表示正面0表示反面,每个状态使用一个二进制数表示。使用十进制数表示状态
- [译] Python 2.7.6 标准库——详见github
- python冒泡算法_python_冒泡算法
- STM32工作笔记003---认识了解RTOS系统
- cas5.3 使用http方式请求
- Java加载Class文件的原理机制
- 基于pytorch的transE代码详解
- 使用docker安装Jenkins教程
- JSONP解决前端跨域问题
- UI设计师必备|Web设计尺寸规范
- 日语---之百度百科
- android模拟电源按键
- 蓝牙协议栈测试,蓝牙协议栈认证:蓝牙BQB认证中End Product/Subsystem和Component的认证区别
- 内核与驱动文件的version magic匹配问题
- python x%y_Python运算符
- 二叉树的先序遍历(C++)
- adb删除软件_苹果免越狱如何安装ipa 苹果免越狱安装软件安装教程【详解】
- Zygote启动及其作用
- 安装pytorch 后torch.cuda.is_available()返回False的解决方法
热门文章
- [项目总结]在ios中使用soundtouch库实现变声
- 《Outlook时间整理术》一创建和使用自己的文件夹结构
- 使用ssh免密码登录Linux服务器
- 谈谈我对MVC的View层实现的理解
- SQLite3.8.4.2在Windows平台下的编译和使用
- 设计模式-Factory Method Pattern
- iphone-common-codes-ccteam源代码 CCTestMacros.m
- 10款优秀的跨平台免费生产力软件[转]
- 批处理文件总结(三)
- python数组替换_Python:替换数组中的值