JavaScript中的this引用(推荐)


Posted in Javascript onAugust 05, 2016

this

this是javascript的一个关键字,随着函数使用场合不同,this的值会发生变化。但是总有一个原则,那就是this指的是调用函数的那个对象。

一、定义

1、this是函数内部的一个特殊对象(或this引用)--它引用的是函数据以执行的环境对象。

2、this引用是一种在JavaScript的代码中随时都可以使用的只读变量。 this引用 引用(指向)的是一个对象,它有着会根据代码上下文语境自动改变其引用对象的特性。它的引用规则如下:

• 在最外层代码中,this引用 引用的是全局对象。

• 在函数内,this引用根据函数调用的方式的不同而有所不同。如下

1)构造函数的调用--this引用 引用的是所生成的对象

2)方法调用--this引用 引用的是接收方对象

3)apply或call调用--this引用 引用的是有apply或call的参数指定的对象

4)其他方式的调用--this引用 引用的是全局对象

二、根据以上所述及网上的相关资料,this对象(引用)的使用情况总结如下:

JavaScript是动态语言,this关键字在执行的时候才能确定是谁。所以this永远指向调用者,即对“调用对象”的引用。简单点说就是调用的方法属于哪个对象,this就指向那个对象。根据函数调用方式的不同,this可以 指向全局对象,当前对象,或其他任意对象。

1、全局函数调用,全局函数中的this会指向全局对象window。(函数调用模式)

//代码清单1
<script type="text/javascript">
var message = "this in window"; //这一句写在函数外面和里面是一样效果
function func() {
if(this == window){
alert("this == window"); 
alert(message);
this.methodA = function() {
alert("I'm a function");
}
}
}
func(); //如果不调用func方法,则里面定义的属性或方法会取不到 
methodA();
</script>

func()的调用结果为this == window, this in window

methodA()的调用结果为I'm a function

2、构造函数调用,即使用new的方式实例化一个对象,this会指向通过构造函数生成的对象。(构造器调用模式)

代码清单2

<script type="text/javascript">
function Func() {
if (this == window) {
alert("this == window");
}
else {
alert("this != window");
}
this.fieldA = "I'm a field";
alert(this);
}
var obj = new Func();
alert(obj.fieldA); //this指向的是对象obj
</script>

3、对象方法的调用,this指向当前对象。任何函数,只要该函数被当做一个对象的方法使用或赋值时,该函数内部的this都是对该对象本身的引用。也可理解为this写在一个普通对象中,this指向的就是对象本身。(方法调用模式)

(方法的定义: 作为对象属性的函数称为方法)

//代码清单3
<script type="text/javascript">
var obj = {
x: 3,
doit: function(){
if(this == window){
alert("this == window");
}else{
alert("method is called: " + this.x);
}
}
};
obj.doit(); //this指向的是对象obj
</script>

4、通过apply或call方法调用,this指向传入的对象。

apply 或call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。 (apply调用模式)

//代码清单4
<script type="text/javascript">
var obj = {
x: 3,
doit: function(){
alert("method is called: " + this.x);
}
};
var obj2 = {x: 4};
obj.doit(); //3,this指向obj
obj.doit.apply(obj2); //4,this指向obj2
obj.doit.call(obj2); //4,this指向obj2
</script>

5、原型链中的this --原型对象及构造函数中的this指向新创建的实例对象。使用prototype扩展方法可以使用this获取到源对象的实例,私有字段无法通过原型链获取。

//代码清单5
<script type="text/javascript">
function Func() {
this.fieldA = "I'm a field";
var privateFieldA = "I'm a var";
}
Func.prototype = {
ExtendMethod: function(str) {
alert(str + " :" + this.fieldA);
alert(privateFieldA); //出错,私有字段无法通过原型链获取。
}
};
var obj = new Func();
obj.ExtendMethod("From prototype"); //此时构造函数及原型链中的this指向对象obj
</script>

6、闭包中的this --闭包:写在function中的function,this指向全局对象window。

6.1 对象中的闭包

//代码清单6
<script type="text/javascript">
var name = "The window";
var obj = {
name: "My Object",
getNameFunc: function(){
return function(){
return this.name;
}
}
};
alert(obj.getNameFunc()()); //The window
</script>

此时,闭包中的this指向全局对象window,只能取到全局对象的属性。那么对象内部的属性(外部函数的变量)要想访问又怎么办呢? 把外部函数的this对象保存在一个闭包能访问的变量就可以了。看如下代码:

//代码清单7
<script type="text/javascript">
var name = "The window";
var obj = {
name: "My Object",
getNameFunc: function(){
var that = this;
return function(){
return that.name;
}
}
};
alert(obj.getNameFunc()()); //My object
</script>

将外部函数的this赋值给that变量,就能读取到外部函数的变量。

6.2 不管是直接引用function,还是实例化一个function,其返回的闭包函数里的this都是指向window。

//代码清单8
<script type="text/javascript">
function a() {
alert(this == window);
var that = this;
var func = function() {
alert(this == window);
alert(that);
};
return func;
}
var b = a();
b(); //true, true, [object Window]
var c = new a();
c(); //false, true, [object object]
</script>

7、函数使用bind()方法绑定一个对象,this会指向传给bind()函数的值。

//代码清单9
<script type="text/javascript">
window.color = "red";
var obj = {color: "blue"};
function sayColor(){
alert(this.color);
}
var objSayColor = sayColor.bind(obj);
objSayColor(); //blue
</script>

8、内嵌在HTML元素中的脚本段,this指向元素本身

//代码清单10
<div onclick="test(this)" id="div">Click Me</div>
<script type="text/javascript">
function test(obj) {
alert(obj); //[object HTMLDivElement]
}
</script>

9、写在script标签中:this就是指全局对象window。这个跟第一点的全局函数调用的全局变量一样。

以上所述是小编给大家介绍的JavaScript中的this引用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
ExtJS下书写动态生成的xml(兼容火狐)
Apr 02 Javascript
详解jquery中$.ajax方法提交表单
Nov 03 Javascript
基于angular中的重要指令详解($eval,$parse和$compile)
Oct 21 Javascript
无阻塞加载js,防止因js加载不了影响页面显示的问题
Dec 18 Javascript
jquery radio 动态控制选中失效问题的解决方法
Feb 28 jQuery
Vue 配合eiement动态路由,权限验证的方法
Sep 26 Javascript
JS+CSS+HTML实现“代码雨”类似黑客帝国文字下落效果
Mar 17 Javascript
将Vue组件库更换为按需加载的方法步骤
May 06 Javascript
通过实例解析vuejs如何实现调试代码
Jul 16 Javascript
解决vue项目运行提示Warnings while compiling.警告的问题
Sep 18 Javascript
react使用antd的上传组件实现文件表单一起提交功能(完整代码)
Jun 29 Javascript
vue实现列表拖拽排序的示例代码
Apr 08 Vue.js
JS实现HTML表格排序功能
Aug 05 #Javascript
JavaScript如何实现跨域请求
Aug 05 #Javascript
JavaScript数组操作函数汇总
Aug 05 #Javascript
Jquery获取当前城市的天气信息
Aug 05 #Javascript
JavaScript蒙板(model)功能的简单实现代码
Aug 04 #Javascript
Three.js学习之Lamber材质和Phong材质
Aug 04 #Javascript
基于JavaScript实现在新的tab页打开url
Aug 04 #Javascript
You might like
使用PHP遍历文件目录与清除目录中文件的实现详解
2013/06/24 PHP
10款实用的PHP开源工具
2015/10/23 PHP
php基于websocket搭建简易聊天室实践
2016/10/24 PHP
jQuery+PHP实现图片上传并提交功能
2020/07/27 PHP
利用json获取字符出现次数的代码
2012/03/22 Javascript
html5 canvas js(数字时钟)实例代码
2013/12/23 Javascript
JavaScript使用concat连接数组的方法
2015/04/06 Javascript
js图片翻书效果代码分享
2015/08/20 Javascript
原生JS实现图片轮播效果
2016/12/26 Javascript
ES6中Proxy与Reflect实现重载(overload)的方法
2017/03/30 Javascript
Node.js之网络通讯模块实现浅析
2017/04/01 Javascript
微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
2017/04/18 Javascript
基于JavaScript实现弹幕特效
2020/08/27 Javascript
利用Vue实现移动端图片轮播组件的方法实例
2017/08/23 Javascript
Node使用Sequlize连接Mysql报错:Access denied for user ‘xxx’@‘localhost’
2018/01/03 Javascript
vue中引用阿里字体图标的方法
2018/02/10 Javascript
vue 实现axios拦截、页面跳转和token 验证
2018/07/17 Javascript
jQuery实现数字自动增加或者减少的动画效果示例
2018/12/11 jQuery
微信小程序如何修改本地缓存key中单个数据的详解
2019/04/26 Javascript
element-ui 实现响应式导航栏的示例代码
2020/05/08 Javascript
Vue使用路由钩子拦截器beforeEach和afterEach监听路由
2020/11/16 Javascript
10种检测Python程序运行时间、CPU和内存占用的方法
2015/04/01 Python
Python遍历numpy数组的实例
2018/04/04 Python
pycharm 将django中多个app放到同个文件夹apps的处理方法
2018/05/30 Python
python实现AES加密与解密
2019/03/28 Python
pandas将多个dataframe以多个sheet的形式保存到一个excel文件中
2019/10/10 Python
python  ceiling divide 除法向上取整(或小数向上取整)的实例
2019/12/27 Python
Python如何输出警告信息
2020/07/30 Python
浅谈对python中if、elif、else的误解
2020/08/20 Python
使用CSS3配合IE滤镜实现渐变和投影的效果
2015/09/06 HTML / CSS
结婚典礼证婚词
2014/01/11 职场文书
预备党员的自我评价
2014/03/12 职场文书
村居抓节水倡议书
2014/05/19 职场文书
董事长年会致辞
2015/07/29 职场文书
你真的了解redis为什么要提供pipeline功能
2021/06/22 Redis
简单总结SpringMVC拦截器的使用方法
2021/06/28 Java/Android