日常开发中,我们经常用到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. SQL基本概述

    DBMS的种类: 层次数据库HDB 面向对象数据库OODB XML数据库XMLDB 键值存储系统KVS 关系数据库RDB RDBMS(关系数据库管理系统),主要5有种: Oracle Database ...

  2. H5网页涂鸦canvas

    最近做了个播放页面,标题和一个iframe;需要对这个iframe可以进行网页涂鸦.网页涂鸦肯定是canvas了.网上找了个差不多的,实验下来问题很多,干脆自己一步步修改,学习. 效果: 本项目没有引 ...

  3. echarts在地图上绘制散点图(任意点)

    项目需求:在省份地图上绘制散点图,散点位置不一定是哪个城市或哪个区县,即任意点 通过查询官网文档,找到一个与需求类似的Demo:https://www.echartsjs.com/gallery/ed ...

  4. 51nod1126 求递推序列的第N项【递推】

    有一个序列是这样定义的:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. 给出A,B和N,求f(n)的值. Input 输 ...

  5. Oralce导入数据库出现某一列的值太大

    这是由于导出的文件所运行的Oracle,和导入所运行的Oracle机器字符集不相同导致的,在UTF-8中有的汉字占三个字节, 并不是所有的都占两个字节,

  6. 在eclipse中运行maven命令没有反应,console也不打印信息

    eclipse的maven项目中,在run as  执行maven命令的时候发现毫无反应,console也不打印信息,原因是因为没有传参数,解决办法如下:①打开eclipse的window菜单: ②接 ...

  7. cxdbImage以及图像显示

    把pdf以及图像存入数据库,然后根据需要显示出来.在处理的过程中,不同类型的图像格式有其不同的类,如果这个概念不清楚,就会绕一个很大的圈子. MyJPEG : TJPEGImage ; mypng : ...

  8. java陷阱之spring事物管理导致锁无效

    模拟锁情况无效 1.创建一个表 SET NAMES utf8mb4; ; DROP TABLE IF EXISTS `demo`; CREATE TABLE `demo` ( `id` ) NOT N ...

  9. java.lang.Object 方法解析

    1.clone() a.是一个native方法,效率比非native高 b.是protected 修饰的,要用他必须继承object,默认都是继承object的 c.返回是一个object 对象,需要 ...

  10. ExtJs之Ajax模式的表单数据加载

    简单: <!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-e ...