日常开发中,我们经常用到this。一开始常会用一种感觉去判断this的指向,当遇到复杂的函数调用时,就分不清this的指向。

今天我们来由浅入深来学习下。

function family1(){
var name = "小白";
console.log(this); //Window
console.log(this.name); //undefined
}
family1(); // 等同于 window.family()

this指向的是调用它的对象,family处于全局,等同于 window.family(),此刻this等同于由window调用的, window中不存在name, 故为undefined

函数作为对象的一个属性

var family2 = {
name:"小白",
fn:function(){
console.log(this.name); //小白
}
}
family2.fn();

this指向的是对象family2,因为fn不仅作为一个对象family2的一个属性,而且是作为对象的一个属性被调用,即通过family2.fn()执行的。结果this就是对象family2。

var family2 = {
name:"小白",
fn:function(){
     console.log(this) //window
console.log(this.name); //undefined
}
}
var newfn = family2.fn();
newfn();

如果fn函数被赋值到了另一个变量newfn中,并没有作为family2的一个属性被调用,那么this的值就是window,this.name为undefined。

构造函数中this,new实例化

如果函数作为构造函数用,那么其中的this就代表它即将new出来的对象。

function Fn(){
this.name = "小白",  
   console.log(this)
}
var family3 = new Fn();
console.log(family3.name); //小白

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

    function Fn(){
this.name = "小白",
console.log(this) // window
}
Fn()

函数用call或者apply调用

当一个函数被call和apply调用时,this的值就取传入的对象的值。

我们通过几道题来练练手吧。

    var a=11
function test1(){
this.a=22;
console.log(this); //window,此时通过this修改了全局变量a的值,由11为22
let b = function(){
console.log(this); //window
console.log(this.a); //
};
b();
}
test1();
 var a=11
function test1(){
console.log(this) // function test1()
this.a=22; // 相当于给test1函数添加了 var a = 22
let b=function(){
console.log(this) //window
console.log(this.a); //
};
b();
}
var t = new test1();

以下几题进行对比

        var val = 1;
var obj = {
val: 3,
fun: function () {
console.log(val); //
this.val *= 2;
//this指向window,故window里面的window.val = val*2
console.log(val); //
val *= 2;
//指window, window.val = val * 2
console.log(val); // 4 在 this.val *= 2的基础上再 val*2
console.log(this.val); //
}
};
var objFun = obj.fun;
objFun(); // 1 2 4 4
      var val = 1;
var obj = {
val: 3,
fun: function () {
this.val *= 2; //this指向obj,故obj里面的obj.val = val*2
console.log(val); //
val *= 2; //指window, window.val = val * 2
console.log(val);// 此时val为1; 即 1*2
console.log(this.val); // this为obj; 此时val为3;即3*2
}
};
obj.fun(); // 1 2 6
        var val = 1;
var obj = {
val: 3,
fun: function () {
this.val *= 2;
console.log(val); //
val *= 2;
console.log(val);//
console.log(this.val); // this为obj; 此时val为3;即3*2
}
};
obj.fun(); // 1 2 6
var objFun = obj.fun; // 此时初始化window.val = 2; obj.val = 6
objFun(); // 4 8 8 注: 第一次调用后obj.fun影响第二次调用objFun

以下两个例子对比

      var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
console.log(this) // obj
var that = this;
return function(){
console.log(that) //obj
return that.name;
};
}
};
console.log(object.getNameFunc()()); //My Object
    var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
console.log(this) // obj
return function(){
console.log(this) //window
return this.name;
};
}
};
console.log(object.getNameFunc()()); //The Window
object.getNameFunc()返回的是一个匿名函数,匿名函数的this是window

以下是英文原文:

Anonymous functions are not bound to an object in this context, meaning the this object points to window unless executing in strict mode (where this is undefined).

翻译:在这个上下文(执行环境)中匿名函数并没有绑定到任何一个对象中,意味着this指向window

(除非这个上下文(执行环境)是在严格模式‘use strict’下执行的,而严格模式下该this指向undefined)

大白话理解this的更多相关文章

  1. 大白话理解cookie

    HTTP协议是一个无状态的协议,服务器无法区分出两次请求是否发送自同一服务器. 需要通过会话控制来解决这个问题,会话控制主要有两种方式Cookie 和 Session. Cookie就是一个头,Coo ...

  2. 大白话理解promise对象

    Promise  代表了未来某个将要发生的事件(通常是一个异步操作)  Promise 是异步编程的解决方案,能够简化多层回调嵌套,代表了未来某个将要发生的事件.Promise是一个构造函数,本身有a ...

  3. 大白话理解箭头函数this

    var obj1={ num:4, fn:function(){ num:5; var f=() => { num:6; console.log(this.num); //4 外层非箭头函数包裹 ...

  4. 【Hibernate框架】关联映射(一对一关联映射)

    一.整理思路: 之前,小编总结过Mybatis的关联映射,接下来,再来总结一下hibernate的相关的关联映射,直接上图: 这张图,就是小编整理总结整个Hibernate的关联映射的一个大致思路. ...

  5. Block、委托、回调函数原理剖析(在Object C语境)——这样讲还不懂,根本不可能!

    开篇:要想理解Block和委托,最快的方法是搞明白“回调函数”这个概念. 做为初级选手,我们把Block.委托.回调函数,视为同一原理的三种不同名称.也就是说,现在,我们把这三个名词当成一回事.在这篇 ...

  6. Git使用教程之SSH连接方式配置(二)

    什么是GitHub?这个网站就是提供Git仓库托管服务的. 什么是SSH Key?你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,大白话理解就是这两个仓库如果要进行远程同步,则我们需 ...

  7. Java 复习整理day05

    1 package com.it.demo01_oop; 2 3 import java.util.Arrays; 4 5 /* 6 案例: 演示面向过程和面向对象代码的区别 7 8 面向过程编程思想 ...

  8. Java复习整理 Day02

    1 package demo01; 2 3 import java.util.Scanner; 4 5 public class ScannerDemo01 { 6 public static voi ...

  9. pycharm的基本使用 、 Python的注释语法,变量,常量,垃圾回收机制,数据类型

    1.文件路径要注意 我把文件放在了D盘,如下图:你们可以根据自身情况设置 2.python环境要选择本地下载好的 如下图: 点击本机存在的环境,如果提示NO interpr,就点击第二步 如果还是没有 ...

随机推荐

  1. codevs 2602 最短路径问题——良心题解

    2602 最短路径问题 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 平面上有n个点(n<=100),每个点的坐标均在- ...

  2. OBS直播和相关操作

    OBS Studio(Open Broadcaster Software)是一个免费的开源的视频录制和视频实时流软件.其有多种功能并广泛使用在视频采集,直播等领域. https://obsprojec ...

  3. 1.2、使用pip安装Python包

    大多数 Python 包都使用 pip 实用工具安装,使用 virtualenv 创建虚拟环境时会自动安装 pip.激活虚拟环境后,pip 所在的路径会被添加进 PATH. 注:如果你在 Python ...

  4. str使用注意点(未完待续)

    1.(切片)str[num1,num2],是指截取 str[num1] 到 str[num2-1] 直接的元素

  5. poj 3041 最小点覆盖=最大匹配

    #include<stdio.h> #include<string.h> #define  N  510 int map[N][N],n,mark[N],link[N]; in ...

  6. POJ 3608

    1.计算P上y坐标值最小的顶点(称为 yminP )和Q上y坐标值最大的顶点(称为 ymaxQ). 2.为多边形在 yminP 和 ymaxQ 处构造两条切线 LP 和 LQ 使得他们对应的多边形位于 ...

  7. jplogic v1.0案例开发之知识库管理(文档管理等)(二)

    jplogic v1.0开发陆续更新,意在和广大网友分享交流.通过寻求合作伙伴,交流群.以下是jplogic的关于知识库模块的部分功能,例如以下进行功能展示: 知识库主界面: 新增知识类别: wate ...

  8. Dagger2使用攻略

    Dagger2使用攻略 Dagger 2 是 Square 的 Dagger 分支,是一种依赖注入框架.眼下由 Google 接手进行开发,Dagger2是使用代码自己主动生成和手写代码来实现依赖注入 ...

  9. 《随笔》pyqt 获取 TreeWidget 选中项的内容

    感谢朋友支持本博客,欢迎共同探讨交流.因为能力和时间有限,错误之处在所难免.欢迎指正! 假设转载,请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167 原博文地 ...

  10. 用hadoop实现SimRank++算法(1)----权值转移矩阵的计算

    本文主要针对广告检索领域的查询重写应用,依据查询-广告点击二部图,在MapReduce框架上实现SimRank++算法.关于SimRank++算法的背景和原理请參看前一篇文章<基于MapRedu ...