一、前言

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声明变量将会把值赋给thiswindow

  示例:

<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等中的基础用法!的更多相关文章

  1. 详细解读-this-关键字在全局、函数、对象、jQuery中的基础用法!

    一.前言 1. Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的设计模式来实现面向对象的编程,其 ...

  2. C++ 11 - STL - 函数对象(Function Object) (中)

    我们再来看一个复杂的例子 需求: 我们需要对集合内每个元素加上一个特定的值 代码如下: AddInt.h class AddInt { private: int theValue; // the va ...

  3. 巧用函数,使Sql中in的用法更多变

    在Sql中我们经常会用到in 普遍的写法为 where xx in ('1','2','3') 通过函数写法为: IF EXISTS ( SELECT * FROM sys.objects WHERE ...

  4. Python--day12(三元表达式、函数对象、名称空间与作用域、函数嵌套定义)

    今日主要内容 1.  函数默认值细节(*) 2.  数据类型补充:三元表达式.列表推导式.字典推导式 (***) 3.  函数对象:函数名的各种应用场景 (*****) 4.  名称空间与作用域:解释 ...

  5. python第十二天, 三元表达式, 函数对象,名称空间与作用域,函数的嵌套定义

    复习 1. 字符串的比较: 2. 函数的参数:形参与实参 3. 实参的分类:位置实参与关键字实参 4. 形参分类: 1.无值位置形参 2.有值位置形参 3.可变长位置形参 4.有无值关键字形参 5.可 ...

  6. day12函数,三元表达式 ,列表推导式 ,字典推导式,函数对象,名称空间与作用域,函数的嵌套定义

    复习 # 字符串的比较 # -- 按照从左往右比较每一个字符,通过字符对应的ascii进行比较 # 函数的参数 # 1)实参与形参: # -- 形参:在函数定义时()中出现的参数 # -- 实参:在函 ...

  7. day-12函数对象

    函数默认值的细节 如果函数的默认参数的默认值为变量,在所属函数定义阶段一执行就被确定为当时变量存放的值,后面变化不会再变化 a = 100 def fn(num=a): a = 200 fn() 三元 ...

  8. day_12函数默认值,数据类型的补充,函数对象名称空间与作用域,函数的嵌套定义

    复习, 昨天讲了字符串的比较,按照从左往右比较每一个字符,通过字符对应的ASCII码进行比较 函数的参数,‘ 实参与形参 形参:在函数定义时()中出现的参数 实参,在函数调用时()中出现的参数 实参的 ...

  9. python中的函数对象与闭包函数

    函数对象 在python中,一切皆对象,函数也是对象 在python语言中,声明或定义一个函数时,使用语句: def func_name(arg1,arg2,...): func_suite 当执行流 ...

随机推荐

  1. 如何实现跨 Docker 主机存储?- 每天5分钟玩转 Docker 容器技术(73)

    从业务数据的角度看,容器可以分为两类:无状态(stateless)容器和有状态(stateful)容器. 无状态是指容器在运行过程中不需要保存数据,每次访问的结果不依赖上一次访问,比如提供静态页面的 ...

  2. tomcat部署在centos6.8上的乱码问题

    web访问经常会莫名其妙的出现各种乱码问题.按照我自己的理解,设置一个charSet的过滤器,代码如下:import java.io.IOException; import javax.servlet ...

  3. 一张图讲解对象锁和关键字synchronized修饰方法

    每个对象在出生的时候就有一把钥匙(监视器),那么被synchronized 修饰的方法相当于给方法加了一个锁,这个方法就可以进行同步,在多线程的时候,不会出现线程安全问题. 下面通过一张图片进行讲解: ...

  4. EOutOfResources EConvertError is not a valid integer value Unable to insert a line

    is not a valid integer value???project Teclaser_Single.exe raised exception class EOutOfResources wi ...

  5. 玩转 sublime3 第二弹 ES6环境

    安装node: node作为JS的运行环境必须安装 文件下载:https://nodejs.org/dist/v6.11.4/node-v6.11.4-x64.msi 备注:可以去官网 https:/ ...

  6. Python cPickle模块

    新博客地址:http://gorthon.sinaapp.com/ 持久性就是指保持对象,甚至在多次执行同一程序之间也保持对象.通过本文,您会对 Python对象的各种持久性机制(从关系数据库到 Py ...

  7. 关于JQuery全选/反选第二次失效的问题

    最近在项目中,遇到一个问题,测试全选/反选功能时,第一次对母框进行选中/非选中时,能同步子框的全选/反选状态,之后再点击母框,子框就没反应了.原代码大致结构关键如下: function selectA ...

  8. VisualStudio快捷键大全

    Ctrl+m+Crtr+o折叠所有大纲Ctrl+M+Crtr+P: 停止大纲显示Ctrl+K+Crtr+C: 注释选定内容Ctrl+K+Crtr+U: 取消选定注释内容Ctrl+J : 列出成员 智能 ...

  9. Java 中静态方法 实例方法 具体方法区别与联系

    在查阅JDK文档时,经常会看到某个类的方法汇总,一般会以如下的格式列出来: 这几个标签对应的方法类型分别是什么意思呢? 1.   Static Method,静态方法,可以在不创建类实例的情况下,访问 ...

  10. JS封装运动框架(另一种写法)

    function animate(obj, json, interval, sp, fn) { clearInterval(obj.timer); //var k = 0; //var j = 0; ...