this 的指向
使用 JavaScript 开发的时候,很多开发者多多少少会被 this 的指向搞蒙圈,但是实际上,关于 this 的指向,记住最核心的一句话:哪个对象调用函数,函数里面的this指向哪个对象。
下面分几种情况谈论下
1、普通函数调用
这个情况没特殊意外,就是指向全局对象-window。
let username='cn'
function fn(){
alert(this.username);//undefined
}
fn();
可能大家会困惑,为什么不是输出守候,但是在细看一看,我声明的方式是let,不会是window对象
如果输出守候,要这样写
var username='cn'
function fn(){
alert(this.username);//cn
}
fu();
//---------------
window.username='cn'
function fn(){
alert(this.username);//cn
}
fn();
//可以理解为
//window.fn();
2、对象函数调用
这个相信不难理解,就是那个函数调用,this指向哪里
window.b=2222
let obj={
a:111,
fn:function(){
alert(this.a);//111
alert(this.b);//undefined
}
}
obj.fn();
很明显,第一次就是输出obj.a,就是111。而第二次,obj没有b这个属性,所以输出undefined,因为this指向obj。
但是下面这个情况得注意
let obj1={
a:222
};
let obj2={
a:111,
fn:function(){
alert(this.a);
}
}
obj1.fn=obj2.fn;
obj1.fn();//222
这个相信也不难理解,虽然obj1.fn是从obj2.fn赋值而来,但是调用函数的是obj1,所以this指向obj1。
3、构造函数调用
let TestClass=function(){
this.name='111';
}
let subClass=new TestClass();
subClass.name='cn';
console.log(subClass.name);//cn
let subClass1=new TestClass();
console.log(subClass1.name)//111
这个也是不难理解,回忆下(new的四个步骤)就差不多了!
但是有一个坑,虽然一般不会出现,但是有必要提一下。
在构造函数里面返回一个对象,会直接返回这个对象,而不是执行构造函数后创建的对象
apply和call调用
apply和call简单来说就是会改变传入函数的this。
let obj1={
a:222
};
let obj2={
a:111,
fn:function(){
alert(this.a);
}
}
obj2.fn.call(obj1);
此时虽然是 obj2 调用方法,但是使用 了call,动态的把 this 指向到 obj1。相当于这个 obj2.fn 这个执行环境是 obj1 。apply 和 call 详细内容在下面提及。
5、箭头函数调用
首先不得不说,ES6 提供了箭头函数,增加了我们的开发效率,但是在箭头函数里面,没有 this ,箭头函数里面的 this 是继承外面的环境。
一个例子
let obj={
a:222,
fn:function(){
setTimeout(function(){console.log(this.a)})
}
};
obj.fn();//undefined
不难发现,虽然 fn() 里面的 this 是指向 obj ,但是,传给 setTimeout 的是普通函数, this 指向是 window , window 下面没有 a ,所以这里输出 undefined。
换成箭头函数
let obj={
a:222,
fn:function(){
setTimeout(()=>{console.log(this.a)});
}
};
obj.fn();//222
这次输出 222 是因为,传给 setTimeout 的是箭头函数,然后箭头函数里面没有 this ,所以要向上层作用域查找,在这个例子上, setTimeout 的上层作用域是 fn。而 fn 里面的 this 指向 obj ,所以 setTimeout 里面的箭头函数的 this ,指向 obj 。所以输出 222 。
call和apply
call 和 apply 的作用,完全一样,唯一的区别就是在参数上面。
call 接收的参数不固定,第一个参数是函数体内 this 的指向,第二个参数以下是依次传入的参数。
apply接收两个参数,第一个参数也是函数体内 this 的指向。第二个参数是一个集合对象(数组或者类数组)
let fn=function(a,b,c){
console.log(a,b,c);
}
let arr=[1,2,3];
如上面这个例子
let obj1={
a:222
};
let obj2={
a:111,
fn:function(){
alert(this.a);
}
}
obj2.fn.call(obj1);
call 和 apply 两个主要用途就是
1.改变 this 的指向(把 this 从 obj2 指向到 obj1 )
2.方法借用( obj1 没有 fn ,只是借用 obj2 方法)
原文:https://blog.csdn.net/weixin_37722222/article/details/81625826
this 的指向的更多相关文章
- C语言中 指向函数的指针 简介
引子:在学习CPrimerPlus的第十四章的14.13节中,遇到了如下三行文字,是有关指向函数的指针的,把我搞晕了. char * fump(); //返回指向char的指针的函数 char (* ...
- JS this指向
正常模式 在正常模式下独立函数的的 this 指向 undefined 或 window. <script type="text/javascript"> functi ...
- java多态性,父类引用指向子类对象
父类引用指向子类对象指的是: 例如父类Animal,子类Cat,Dog.其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类. Animal animal = new C ...
- 【javascript 技巧】谈谈setTimeout的作用域以及this的指向问题
setTimeout的用法详见:http://www.w3school.com.cn/htmldom/met_win_settimeout.asp 是的,setTimeout的常见用法是让某个方法延迟 ...
- what's this? 浅谈js中this的指向问题
刚刚学习js的朋友可能和我一样,看到代码中的this总是一脸懵逼,不知道this到底指向谁.经过一段时间的了解,我想跟大家分享下自己的理解. 何时出现this 函数在调用的时候,会自动获得两个特殊变量 ...
- EC笔记,第二部分:10.让=返回指向*this的引用
Effective C++ 学习笔记 10 让=返回指向*this的引用 Table of Contents 1. 原因 2. 建议:在没有充分理由标新立异前,最好的做法是遵从传统. –by SkyF ...
- JavaScript中this指针指向的彻底理解
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象 这一点与函数中自由变量Action-varibal不同 var ...
- JavaScript中this指向的简单理解
首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...
- 12-返回指针的函数&&指向函数的指针
前言 接下来我只讲指针的最常见用法,比如这一章的内容----返回指针的函数 与 指向函数的指针 一.返回指针的函数 指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的. 返回 ...
- 彻底理解js中this的指向,不必硬背。
首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...
随机推荐
- 对C语言指针的理解
一个小程序引发对于C语言指针的思考: #include <bits/stdc++.h> using namespace std; void my_swap (int* a,int* b) ...
- tp3.2 D 和 M 的区别
ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 M方法: 对数据表进 ...
- day11.2lambda函数表达式 及其返回值注意事项
lambda表达式 用于表示简单的函数 func1=lambda 参数:一句话函数体(默认返回函数体内执行的内容) 1.1结构 func=lambda a1,a2 : a1+100 val=func( ...
- 学习笔记CB005:关键词、语料提取
关键词提取.pynlpir库实现关键词提取. # coding:utf-8 import sys import importlib importlib.reload(sys) import pynlp ...
- REST SOAP Thrift 对比
别人的REST SOAP Thrift对比: 单项分数越高越好 项目 REST SOAP Thrift Extensibility 5 3 1 Neutrality 2 4 3 Independenc ...
- Java_04循环结构
1.while 循环结构 格式: while(循环条件){ } 关键字 while 后的小括号中的内容是循环条件.循环条件是一个表达式,值为布尔类型. { }大括号中的语句统称为循环操作,又称为循环体 ...
- 3-Longest Substring Without Repeating Characters @LeetCode
3-Longest Substring Without Repeating Characters @LeetCode 题目 题目中得到的信息有: 一段字符串找出不重复子串的最大长度,只需要长度信息. ...
- rsync命令简单用法介绍
rsync有两种常用的认证方式,一种为rsync-daemon方式,另外一种则是ssh.在一些场合,使用rsync-daemon方式会比较缺乏灵活性,ssh方式则成为首选.但是今天实际操作的时候发现当 ...
- IOS屏幕旋转思路和实践
这段时间同事在做一个直播项目,项目有个需求:一个界面需要手动设置屏幕的方向,设置好之后方向不能变化.完成这个需求花了特别大的精力,归因是网上关于屏幕旋转的知识比较凌乱,解决问题花费不少时间,最后决定把 ...
- java 通信
UDP package com.le; import org.junit.Test; import java.io.IOException; import java.net.DatagramPacke ...