大白话理解this
日常开发中,我们经常用到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的更多相关文章
- 大白话理解cookie
HTTP协议是一个无状态的协议,服务器无法区分出两次请求是否发送自同一服务器. 需要通过会话控制来解决这个问题,会话控制主要有两种方式Cookie 和 Session. Cookie就是一个头,Coo ...
- 大白话理解promise对象
Promise 代表了未来某个将要发生的事件(通常是一个异步操作) Promise 是异步编程的解决方案,能够简化多层回调嵌套,代表了未来某个将要发生的事件.Promise是一个构造函数,本身有a ...
- 大白话理解箭头函数this
var obj1={ num:4, fn:function(){ num:5; var f=() => { num:6; console.log(this.num); //4 外层非箭头函数包裹 ...
- 【Hibernate框架】关联映射(一对一关联映射)
一.整理思路: 之前,小编总结过Mybatis的关联映射,接下来,再来总结一下hibernate的相关的关联映射,直接上图: 这张图,就是小编整理总结整个Hibernate的关联映射的一个大致思路. ...
- Block、委托、回调函数原理剖析(在Object C语境)——这样讲还不懂,根本不可能!
开篇:要想理解Block和委托,最快的方法是搞明白“回调函数”这个概念. 做为初级选手,我们把Block.委托.回调函数,视为同一原理的三种不同名称.也就是说,现在,我们把这三个名词当成一回事.在这篇 ...
- Git使用教程之SSH连接方式配置(二)
什么是GitHub?这个网站就是提供Git仓库托管服务的. 什么是SSH Key?你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,大白话理解就是这两个仓库如果要进行远程同步,则我们需 ...
- Java 复习整理day05
1 package com.it.demo01_oop; 2 3 import java.util.Arrays; 4 5 /* 6 案例: 演示面向过程和面向对象代码的区别 7 8 面向过程编程思想 ...
- Java复习整理 Day02
1 package demo01; 2 3 import java.util.Scanner; 4 5 public class ScannerDemo01 { 6 public static voi ...
- pycharm的基本使用 、 Python的注释语法,变量,常量,垃圾回收机制,数据类型
1.文件路径要注意 我把文件放在了D盘,如下图:你们可以根据自身情况设置 2.python环境要选择本地下载好的 如下图: 点击本机存在的环境,如果提示NO interpr,就点击第二步 如果还是没有 ...
随机推荐
- jquery相关常用的工具函数
1.弹出提示框: function prompt(msg){ $("<div>" + msg + "</div>").css({ &qu ...
- react-draft-wysiwyg富文本
import { EditorState, convertToRaw } from 'draft-js'; import { Editor } from 'react-draft-wysiwyg' ...
- Hadoop-2.2.0集群部署时live nodes数目不对的问题
关于防火墙,hadoop本身配置都确定没任何问题,集群启动不报错,但打开50070页面,始终live nodes数目不对,于是我尝试/etc/hosts文件配置是否存在逻辑的错误: 127.0.0.1 ...
- 【第一课】kaggle初识
Evernote Export Crowdflower搜索结果相关性 文件和数据描述 train.csv训练数据集包括: id:产品ID查询:使用的搜索词 product_description:完整 ...
- 【剑指Offer】23、二叉搜索树的后序遍历序列
题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 解题思路: 对于后续遍历序列,序 ...
- for 循环的反汇编浅析
for 循环 for 循环是使用频度最高的循环结构,我们通过 C 语言反汇编实例,来分析 for 循环结构在计算机底层的原理和构造.首先,我们编写一个简单的 for 循环: 为了方便观察,我们用十六进 ...
- 突如其来的“中断异常”,我(Java)该如何处理?
3.try-catch块 try语句块中代码执行时发生三种情况: try语句块中代码正常执行完毕,没有任何异常,那么catch语句块的代码将不会被执行. import java.util.*; pub ...
- 洛谷 P1129 BZOJ 1059 cogs 660 [ZJOI2007]矩阵游戏
题目描述 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏.矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作: 行交 ...
- 对Django框架中Cookie的简单理解
概念的理解:首先Cookie和Session一样,是django中用于视图保持状态的方案之一.为什么要进行视图保留呢,这是因为浏览器在向服务器发出请求时,服务器不会像人一样,有记忆,服务器像鱼一样,在 ...
- SpringBoot中logback.xml使用application.yml中属性
教你如何使用 springProfile 与 springProperty 让你的logback.xml 配置显得更有逼格,当别人还在苦苦挣扎弄logback-{profile}.xml的时候 你一个 ...