转自:https://www.cnblogs.com/pssp/p/5216085.html

例子1:

 function a(){

    var user = "追梦子";
console.log(this.user); //undefined
console.log(this); //Window
}
a();

按照我们上面说的this最终指向的是调用它的对象,这里的函数a实际是被Window对象所点出来的,下面的代码就可以证明。

function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this);  //Window
}
window.a();

和上面代码一样吧,其实alert也是window的一个属性,也是window点出来的。

例子2:

var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
o.fn();

  这里的this指向的是对象o,因为你调用这个fn是通过o.fn()执行的,那自然指向就是对象o,这里再次强调一点,this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁,一定要搞清楚这个。其实例子1和例子2说的并不够准确,下面这个例子就可以推翻上面的理论。如果要彻底的搞懂this必须看接下来的几个例子

例子3:

var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
window.o.fn();

  这段代码和上面的那段代码几乎是一样的,但是这里的this为什么不是指向window,如果按照上面的理论,最终this指向的是调用它的对象,这里先说个而外话,window是js中的全局对象,我们创建的变量实际上是给window添加属性,所以这里可以用window点o对象。

  这里先不解释为什么上面的那段代码this为什么没有指向window,我们再来看一段代码。

var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();

  这里同样也是对象o点出来的,但是同样this并没有执行它,那你肯定会说我一开始说的那些不就都是错误的吗?其实也不是,只是一开始说的不准确,接下来我将补充一句话,我相信你就可以彻底的理解this的指向的问题。

  情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题,你想了解可以自行上网查找。

  情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。

  情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象,例子3可以证明,如果不相信,那么接下来我们继续看几个例子。

var o = {
a:10,
b:{
// a:12,
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();

尽管对象b中没有属性a,这个this指向的也是对象b,因为this只会指向它的上一级对象,不管这个对象中有没有this要的东西。

还有一种比较特殊的情况,例子4:

var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();

这里this指向的是window,是不是有些蒙了?其实是因为你没有理解一句话,这句话同样至关重要。

  this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,例子4中虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window,这和例子3是不一样的,例子3是直接执行了fn。

  this讲来讲去其实就是那么一回事,只不过在不同的情况下指向的会有些不同,上面的总结每个地方都有些小错误,也不能说是错误,而是在不同环境下情况就会有不同,所以我也没有办法一次解释清楚,只能你慢慢地的去体会。

构造函数版this:

 function Fn(){

    this.user = "追梦子";
}
var a = new Fn();
console.log(a.user); //追梦子

  这里之所以对象a可以点出函数Fn里面的user是因为new关键字可以改变this的指向,将这个this指向对象a,为什么我说a是对象,因为用了new关键字就是创建一个对象实例,理解这句话可以想想我们的例子3,我们这里用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象a,那么为什么对象a中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份。

  除了上面的这些以外,我们还可以自行改变this的指向,关于自行改变this的指向请看JavaScript中call,apply,bind方法的总结这篇文章,详细的说明了我们如何手动更改this的指向。

更新一个小问题当this碰到return时

function fn()
{
this.user = '追梦子';
return {};
}
var a = new fn;
console.log(a.user); //undefined

再看一个

function fn()
{
this.user = '追梦子';
return function(){};
}
var a = new fn;
console.log(a.user); //undefined

再来

function fn()
{
this.user = '追梦子';
return 1;
}
var a = new fn;
console.log(a.user); //追梦子
function fn()
{
this.user = '追梦子';
return undefined;
}
var a = new fn;
console.log(a.user); //追梦子

什么意思呢?

  如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。

function fn()
{
this.user = '追梦子';
return undefined;
}
var a = new fn;
console.log(a); //fn {user: "追梦子"}

  还有一点就是虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊。

function fn()
{
this.user = '追梦子';
return null;
}
var a = new fn;
console.log(a.user); //追梦子

javascript学习之this的更多相关文章

  1. JavaScript学习(一) —— 环境搭建与JavaScript初探

    1.开发环境搭建 本系列教程的开发工具,我们采用HBuilder. 可以去网上下载最新的版本,然后解压一下就能直接用了.学习JavaScript,环境搭建是非常简单的,或者说,只要你有一个浏览器,一个 ...

  2. Web编程基础--HTML、CSS、JavaScript 学习之课程作业“仿360极速浏览器新标签页”

    Web编程基础--HTML.CSS.JavaScript 学习之课程作业"仿360极速浏览器新标签页" 背景: 作为一个中专网站建设出身,之前总是做静态的HTML+CSS+DIV没 ...

  3. JavaScript学习(3):函数式编程

    在这篇文章里,我们讨论函数式编程. 什么是函数式编程?根据百度百科的描述,“函数式编程是种编程典范,它将电脑运算视为函数的计算.函数编程语言最重要的基础是 λ 演算(lambda calculus). ...

  4. JavaScript学习(2):对象、集合以及错误处理

    在这篇文章里,我们讨论一下JavaScript中的对象.数组以及错误处理. 1. 对象 对象是JavaScript中的一种基本类型,它内部包含一些属性,我们可以对这些属性进行增删操作. 1.1 属性 ...

  5. JavaScript学习13 JavaScript中的继承

    JavaScript学习13 JavaScript中的继承 继承第一种方式:对象冒充 <script type="text/javascript"> //继承第一种方式 ...

  6. JavaScript学习12 JS中定义对象的几种方式

    JavaScript学习12 JS中定义对象的几种方式 JavaScript中没有类的概念,只有对象. 在JavaScript中定义对象可以采用以下几种方式: 1.基于已有对象扩充其属性和方法 2.工 ...

  7. JavaScript学习11 数组排序实例

    JavaScript学习11 数组排序实例 数组声明 关于数组对象的声明,以前说过:http://www.cnblogs.com/mengdd/p/3680649.html 数组声明的一种方式: va ...

  8. JavaScript学习10 JS数据类型、强制类型转换和对象属性

    JavaScript学习10 JS数据类型.强制类型转换和对象属性 JavaScript数据类型 JavaScript中有五种原始数据类型:Undefined.Null.Boolean.Number以 ...

  9. JavaScript学习09 函数本质及Function对象深入探索

    JavaScript学习09 函数本质及Function对象深入探索 在JavaScript中,函数function就是对象. JS中没有方法重载 在JavaScript中,没有方法(函数)重载的概念 ...

  10. JavaScript学习08 Cookie对象

    JavaScript学习08 Cookie对象 JavaScript Cookie Cookie对象: Cookie是一种以文件的形式保存在客户端硬盘的Cookies文件夹中的用户数据信息(Cooki ...

随机推荐

  1. 刚看完了一本关于javascript的书感觉受益匪浅,原来不懂的东西这么多,想问问怎么成为大神?求教!!!!!!

    刚看完了一本关于javascript的书感觉受益匪浅,原来不懂的东西这么多,想问问怎么成为大神?求教!!!!!!

  2. MVC阻止用户注入JavaScript代码或者Html标记

    使用HttpUtility.HtmlEncode("")将字符串进行过滤处理

  3. mysql中,什么是视图,视图的作用是什么?

    需求描述: 在看mysql的视图,对于视图的定义,进行基本的了解,在此记录下. 概念解释: 视图:存储的查询语句,当调用的时候,产生结果集,视图充当的是虚拟表的角色. 测试过程: 说明: 如果要对一张 ...

  4. [原]unity3d 纹理旋转

    纹理旋转实现思路:纹理坐标*平移矩阵*旋转矩阵(类似顶点旋转): 矩阵一般要求中心点为(0,0) 而纹理中心点默认(0.5,0.5);所以先得平移到(0,0):可以考虑乘以平移矩阵[1,0,0,0,1 ...

  5. 【原】list<T>排序

    继承IComparable #region IComparable        public int CompareTo(object  obj)    {        if(obj is Sce ...

  6. 【scala】 scala 基础(一)

    至于什么是scala,摘录一段 维基百科的解释: scala 下载 安装 省略 1.环境变量配置完成后 命令行报错,因为scala 的安装路径里边包含空格 修改后即可.由于我的本地包含空格,此处CLI ...

  7. Get started with ros -- 1

    原创博文:转载请标明出处(周学伟):http://www.cnblogs.com/zxouxuewei/tag/ 一.Introduction: 机器人操作系统(ROS)是使机器人系统的不同部分能够发 ...

  8. 虚拟机安装linux系统无法上网的解决方法

    原文:https://www.jb51.net/article/118267.htm 周末闲来无事,用虚拟机安装了centos6.5系统,安装成功后发现不能连接网络,然后我就一脸蒙蔽了,无奈之下,只能 ...

  9. hdu5289 2015多校联合第一场1002 Assignment

    题意:给出一个数列.问当中存在多少连续子区间,当中子区间的(最大值-最小值)<k 思路:设dp[i]为从区间1到i满足题意条件的解.终于解即为dp[n]. 此外 如果对于arr[i] 往左遍历 ...

  10. CentOS 6.3 + Subversion + Usvn 搭建版本管理服务器

    一. Subversion 简介 Subversion是一个自由,开源的版本控制系统.在Subversion管理下,文件和目录可以超越时空.Subversion将文件存放在中心版本库里.这个版本库很像 ...