详细解读-this-关键字在全局、函数、对象、jQuery等中的基础用法!
一、前言
1、 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象。Javascript可以通过一定的设计模式来实现面向对象的编程,其中this “指针”就是实现面向对象的一个很重要的特性。但是this也是Javascript中一个非常容易理解错,进而用错的特性。
2、this是Javascript语言的一个关键字。 它代表函数运行时,自动生成的一个内部对象。
二、进入正题
1、全局代码中的——this
1、 浏览器宿主的全局环境中,this指的是window对象。在全局代码中,this始终是全局对象本身,这样就有可能间接的引用到它了。
示例:
<script type="text/javascript">
console.log(this); //window
console.log(this == window);//true
</script>
2、 浏览器中在全局环境下,使用var声明变量将会把值赋给this或window。
示例:
<script type="text/javascript">
var name = "Jack" ;
console.log(this.name);//Jack
console.log(window.name);//Jack
</script>
3、任何情况下,即使创建变量时没有使用var,也是在操作全局this。而在函数里面创建变量时,结果为undefined。
示例:
<script type="text/javascript">
name = "Jack";
function testThis() {
age = 20;
console.log(this.age); // 20
}
console.log(this.age); // undefined
console.log(this.name);// Jack
testThis();
console.log(this.name);// Jack
</script>
二、函数代码中的——this
1、先来看一个最简单的例子
<script type="text/javascript">
var name = "Jack";
function sayHi(){
console.log("你好,我的名字叫" + name);// "你好,我的名字叫Jack"
console.log("你好,我的名字叫" + this.name);// "你好,我的名字叫Jack"
}
sayHi();
</script>
首先,我们定义了一个全局字符串对象name和函数对象sayHi。运行都会打印出,“你好,我的名字叫Jack”。全局变量name将值赋给this。
2、我们把上面的代码改一改:
<script type="text/javascript">
name = "Jack";
function testThis() {
this.name = "Alice";
}
console.log("你好,我的名字叫"+this.name); // "你好,我的名字叫Jack"
testThis();
console.log("你好,我的名字叫"+this.name); // "你好,我的名字叫Alice"
</script>
运行结果为Jack中的this为函数调用之前的全局变量name=Jack将值赋给this,此时textThis函数未将Alice赋值给this;运行结果为Alice为函数调用之后testThis函数将Alice值赋值给了全局变量name,此时name = "Alice" this.name = "Alice"。
3、函数也是普通的对象,可以将其当作一个普通变量使用。我们再把上面的代码改一改:
<script type="text/javascript">
var name = "Jack";
function sayHi(){
console.log("你好,我的名字叫" + this.name);// undefined
}
var person = {};
person.sayHello = sayHi;
person.sayHello();
</script> //而定义 person = {name:Alice} ,则:
<script type="text/javascript">
var name = "Jack";
function sayHi(){
console.log("你好,我的名字叫" + this.name);// "你好,我的名字叫Alice"
}
var person = {name:Alice};
person.sayHello = sayHi;
person.sayHello();
</script>
第一,我们定义了一个全局函数对象sayHi并执行了这个函数,函数内部使用了this关键字,那么执行this这行代码的对象是sayHi(一切皆对象的体现),sayHi是被定义在全局作用域中。其实在Javascript中所谓的全局对象,无非是定义在window这个根对象下的一个属性而已。因此,sayHi的所有者是window对象。也就是说,在全局作用域下,你可以通过直接使用name去引用这个对象,你也可以通过window.name去引用同一个对象。因而this.name就可以翻译为window.name。
第二,我们定义了一个person的对象,并定义了它的sayHello属性,使其指向sayHi全局对象。那么这个时候,当我们运行person.sayHello的时候,this所在的代码所属对象就是sayHello了(其实准确来说,sayHi和sayHello是只不过类似两个指针,指向的对象实际上是同一个),而sayHello对象的所有者就是person了。第一次,person里面没有name属性,因此弹出的对话框就是this.name引用的就是undefined对象(Javascript中所有只声明而没有定义的变量全都指向undefined对象);而第二次我们在定义person的时候加了name属性了,那么this.name指向的自然就是我们定义的字符串了。
参考上面解释,我们将上面示例改造成面向对象式的代码:
<script type="text/javascript">
var name = "Jack";
function sayHi(){
console.log("你好,我的名字叫" + this.name);//两次函数调用均成功,打印两次:"你好,我的名字叫Marry" "你好,我的名字叫Alice"
}
function Person(name){
this.name = name;
}
Person.prototype.sayHello = sayHi;
var marry = new Person("Marry");
marry.sayHello();
var alice = new Person("Alice");
alice.sayHello();
</script>
在上面这段代码中,我们定义了一个Person的“类”(实际上还是一个对象),然后在这个类的原型(类原型相当于C++中的静态成员变量的概念)中定义了sayHello属性,使其指向全局的sayHi对象。运行代码我们可以看到,marry和kevin都成功打印出来。
4、当用调用函数时使用了new关键字,此刻this指代一个新的上下文,不再指向全局this。通常我将这个新的上下文称作实例。
<script type="text/javascript">
name = "Jack";
function testThis() {
this.name = "Alice";
}
console.log(this.name); // "Jack"
new testThis();
console.log(this.name); // "Jack"
console.log(new testThis().name); // "Alice"
</script>
三、对象代码中的——this
1、可以在对象的任何方法中使用this来访问该对象的属性。这与用new得到的实例是不一样的。
var obj = {
name: "Jack",
func: function () {
console.log(this.name); // "Jack"
}
};
obj.func();
2、可以将函数绑定到对象,就好像这个对象是一个实例一样。
var obj = {
name: "Jack"
};
function logName() {
console.log(this.name); //logs "Jack"
}
logName.apply(obj);
3、也可以不通过this,直接访问对象的属性。
var obj = {
name: "Jack",
deeper: {
logName: function () {
console.log(obj.name);// "Jack"
}
}
};
obj.deeper.logName();
四、jQuery代码中的——this
1、jQuery库中大多地方的this也是指代的DOM元素。页面上的事件回调和一些便利的静态方法比如$.each 都是这样的。
<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script src="../05-JQuery/JS/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
$(function(){ $(".foo").each(function () {
console.log(this); // <div class="foo bar1"></div> <div class="foo bar2"></div>
});
$(".foo").on("click", function () {
console.log(this); // <div class="foo bar1"> <div class="foo bar2"></div>
}); }) </script>
五、DOM事件中的——this
在DOM事件的处理函数中,this指代的是被绑定该事件的DOM元素。
function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick);
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs "<div id="foo"></div>"
}
var listener = new Listener();
document.getElementById("foo").click();
六、使用with时的——this
使用with可以将this人为添加到当前执行环境中而不需要显示地引用this。
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
with (this) {
console.log(foo);
foo = "foo";
}
}
var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
结束:
上面,就是博主自己在实践的过程中,总结的一点经验,希望对大家能否有所帮助,欢迎大家能够提出高贵意见,博主定当补充改正。
详细解读-this-关键字在全局、函数、对象、jQuery等中的基础用法!的更多相关文章
- 详细解读-this-关键字在全局、函数、对象、jQuery中的基础用法!
一.前言 1. Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的设计模式来实现面向对象的编程,其 ...
- C++ 11 - STL - 函数对象(Function Object) (中)
我们再来看一个复杂的例子 需求: 我们需要对集合内每个元素加上一个特定的值 代码如下: AddInt.h class AddInt { private: int theValue; // the va ...
- 巧用函数,使Sql中in的用法更多变
在Sql中我们经常会用到in 普遍的写法为 where xx in ('1','2','3') 通过函数写法为: IF EXISTS ( SELECT * FROM sys.objects WHERE ...
- Python--day12(三元表达式、函数对象、名称空间与作用域、函数嵌套定义)
今日主要内容 1. 函数默认值细节(*) 2. 数据类型补充:三元表达式.列表推导式.字典推导式 (***) 3. 函数对象:函数名的各种应用场景 (*****) 4. 名称空间与作用域:解释 ...
- python第十二天, 三元表达式, 函数对象,名称空间与作用域,函数的嵌套定义
复习 1. 字符串的比较: 2. 函数的参数:形参与实参 3. 实参的分类:位置实参与关键字实参 4. 形参分类: 1.无值位置形参 2.有值位置形参 3.可变长位置形参 4.有无值关键字形参 5.可 ...
- day12函数,三元表达式 ,列表推导式 ,字典推导式,函数对象,名称空间与作用域,函数的嵌套定义
复习 # 字符串的比较 # -- 按照从左往右比较每一个字符,通过字符对应的ascii进行比较 # 函数的参数 # 1)实参与形参: # -- 形参:在函数定义时()中出现的参数 # -- 实参:在函 ...
- day-12函数对象
函数默认值的细节 如果函数的默认参数的默认值为变量,在所属函数定义阶段一执行就被确定为当时变量存放的值,后面变化不会再变化 a = 100 def fn(num=a): a = 200 fn() 三元 ...
- day_12函数默认值,数据类型的补充,函数对象名称空间与作用域,函数的嵌套定义
复习, 昨天讲了字符串的比较,按照从左往右比较每一个字符,通过字符对应的ASCII码进行比较 函数的参数,‘ 实参与形参 形参:在函数定义时()中出现的参数 实参,在函数调用时()中出现的参数 实参的 ...
- python中的函数对象与闭包函数
函数对象 在python中,一切皆对象,函数也是对象 在python语言中,声明或定义一个函数时,使用语句: def func_name(arg1,arg2,...): func_suite 当执行流 ...
随机推荐
- Vuex 学习笔记
Vuex 是什么? Vuex 是一个专为 Vue.js应用程序开发的状态管理模式.由于SPA应用的模块化,每个组件都有它各自的数据(state).视图(view)和方法(actions),当项目内容越 ...
- Linux学习——shell编程之变量
shell编程之变量:Linux shell编程基础中的变量. 包括Bash变量的分类和各变量的详细使用,如:用户自定义变量.环境变量.语系变量.位置参数变量和预定义变量. 1:什么是Bash变量? ...
- java集合系列——Set之HashSet和TreeSet介绍(十)
一.Set的简介 Set是一个不包含重复元素的 collection.更确切地讲,set 不包含满足 e1.equals(e2) 的元素.对 e1 和 e2,并且最多包含一个为 null 的元素. S ...
- 第4章 同步控制 Synchronization ----死锁(DeadLock)
Jeffrey Richter 在他所主持的 Win32 Q&A 专栏(Microsoft Systems Journal,1996/07)中曾经提到过,Windows NT 和 Window ...
- Cow Sorting hdu 2838
Cow Sorting Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- Kotlin实现《第一行代码》案例“酷欧天气”
看过<第一行代码>的朋友应该知道“酷欧天气”,作者郭神用整整一章的内容来讲述其从无到有的过程. 最近正好看完该书的第二版(也有人称“第二行代码”),尝试着将项目中的Java代码用Kotli ...
- input输入中文时,拼音在输入框内会触发input事件的问题。
问题描述: 监听文本输入框的input事件,在拼写汉字(输入法)但汉字并未实际填充到文本框中(选词)时会触发input事件,如图: 需要完成的需求就是在输入阶段不触发input中的事件,选词之后文字落 ...
- PowerBI开发 第七篇:数据集和数据刷新
PowerBI报表是基于数据分析的引擎,数据真正的来源(Data Source)是数据库,文件等数据存储媒介,PowerBI支持的数据源类型多种多样.PowerBI Service(云端)有时不直接访 ...
- jdk8与jdk9的共存
以前安装JDK,需要手动配置环境变量.JDK8多了自动配置环境变量,所以可以不用手动配置. 如果我已经装了JDK8,还想再装一个JDK9,安装完,自动配置的环境变量会指向JDK9版本. 解决方法 删除 ...
- 【转】python time模块详解
python 的内嵌time模板翻译及说明 一.简介 time模块提供各种操作时间的函数 说明:一般有两种表示时间的方式: 第一种是时间戳的方式(相对于1970.1.1 00:00:0 ...