React:JS中的this和箭头函数

JS中的this和纯面向对象(java,c++)中的this有点不大一样,其原因就是作用域不同,导致JS中的this的指向不明确,在java中的this指当前对象的this或当前类的this,在JS中function(){}里面没有特殊指定this的指向,这里的this时指向Window,但是在严格模式下,function(){return this}里面的this是undefined,箭头函数里面的this反而是Window,我们来看个例子(为了简单点,代码下面的>就是控制台的输入,<就是控制台的输出):

//在控制台先输入这个函数,
function Person(){
    this.age = 0;
    setInterval(function growUp() {//此时的this时指向window,并不指向上面的this.age
        this.age++;
    },1000)
}

>var p = new Person()
>p//因为this时指向window,并不指向上面的this.age,所以没有变
<Person {age: 0}//age是全局变量,没有给初始值,++后就变成Not a Number
>age
NaN//给age赋初值,下面就开始++le
age = 0
0
age
5
age
8
age
10
age
14
age
16

以前流行的一种解决方法

//在控制台先输入这个函数,
function Person(){
    //定义一个局部变量把当前的this放在里面,下面函数就可以使用了
    let that = this;
    this.age = 0;
    setInterval(function growUp() {
//此时的this时指向window,并不指向上面的this.age
        that.age++;
    },1000)
}
//一切正常
>let p = new Person();
>p
<Person {age: 0}
>p
<Person {age: 1}
>p
<Person {age: 2}
>p
<Person {age: 3}

只有这一种解决方法?这时候箭头函数该登场了,箭头函数不会创建自己的this;它使用封闭执行上下文的this值。因此,在下面的代码中,传递给setInterval的函数内的this与封闭函数中的this值相同,简单来说,箭头函数没有自带this,他的this是来自上一级,所以刚刚好解决这个问题:

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| 正确地指向person 对象
  }, 1000);
}
undefined
>let p = new Person();
<undefined
>p
<Person {age: 1}
>p
<Person {age: 2}
>p
<Person {age: 3}

我们再看写栗子:

function f(){console.log(this.a)}
>f()
<undefined
//此时call传入参数,这个参数可以理解为this,但对this不造成影响
>f.call({a:1})
<1
>f.apply({a:1})
<1

还有个要记的,当箭头函数要返回一个对象时,{}要用小括号括起来,比如:f = () => ({}) ,大括号表示一个对象

更多箭头函数例子:API

原文地址:https://www.cnblogs.com/doudoublog/p/8447631.html

时间: 2024-08-29 14:15:46

React:JS中的this和箭头函数的相关文章

在react jsx中,为什么使用箭头函数和bind容易出现问题

在之前的文章中,已经说明如何避免在react jsx中使用箭头函数和bind(https://medium.freecodecamp.o... 但是没有提供一个清晰的demo展示为什么要这样做. 现在来一些例子吧. 在这个例子中,我们通过使用一个箭头函数(=>)来bind用户ID到每个删除按钮中. ## index.js import React from 'react'; import { render } from 'react-dom'; import User from './User'

JS中的日期内置函数

用JS中的日期内置函数实现在页面显示:“今天是:2013年9月26日14:32:45”. var date=new Date(Date.parse('9/26/2013 14:32:45'));   写出JS中声明对象的三种方法. Var obj={ name:名字, Say:function(){ Alert(‘sssss’); } }     Var obj=new Object();     Var obj={} Obj.name=’名字’; Obj.say=function(){ Ale

JS中,子类调用超类函数

概述 JS虽然并不直接具备面向对象的特性,但仍可以通过prototype来模拟面向对象的继承和多态等特性.和大多数面向对象语言(例如C++,Java等)相比,JS来实现面向对象仍稍显繁琐和抽象,需要对JS的prototype模型有深入的理解. 在开发过程中,有时候会遇到这样一个问题:如果在子类中"覆盖"了超类的某个方法,但仍需要在子类方法中调用一次超类方法,这时候应该怎么做?如果是Java,一个简单的super关键字即可解决问题,但如果是JS呢? 解决问题的最基本方法可以是:在子类中,

js中startWith、endWith效果函数

JavaScript采用正则表达式实现startWith.endWith效果函数 String.prototype.startWith=function(str){       var reg=new RegExp("^"+str);       return reg.test(this);        } String.prototype.endWith=function(str){       var reg=new RegExp(str+"$");     

js中变量名提升和函数名提升

首先,js中变量没有块级作用域,但是有函数作用域,即只有函数可以约数变量的作用域. 并且,函数的实质也是一个变量,所以可以改变它的值,即赋值.所以变量名提升和函数名提升非常相像. 1.变量名的提升发生在函数内部.看下面的例子.说明:第一个因为弹出undefined,相当于在上面定义了var num;因为函数内部,定义了var num=20:就相当于在一开始定义了var num;这就是变量名的提升. var num = 10; function func() { alert(num); //und

JS中的循环嵌套 BOM函数

[嵌套循环特点]                           外层循环转一次,内层循环转一圈              外层循环控制行数,内层循环控制每行元素个数             [做图形题思路]              1确定图形一共几行  极为外层的循环的次数             2确定每行有几种元素,代表有几个内层循环.             3 确定每种元素的个数,即为每个内层循环的次数                 tips:通常:找出每种元素个数,与行号的关

JS中的substring和substr函数的区别

1. 在JS中, 函数声明: stringObject.substring(start,stop) start是在原字符串检索的开始位置,stop是检索的终止位置,返回结果中不包括stop所指字符. 如:"hamburger".substring(4,8) returns "urge" 2. substr(start,length) 如:当DETAIL_TYPE 的值为1111053 时,substr(DETAIL_TYPE,1,6)  = 111105 从DETA

js中的变量提升和函数提升

1在js中只有两种作用域 a:全局作用域 b:函数作用域 在ES6之前,js是没有块级作用域. 首先来解释一下什么是没有块级作用域? 所以此时 是可以打印输出变量a的值. 2:什么是变量提升? 在我们的js中,代码的执行时分两步走的,1.解析 2.一步一步执行 那么变量提升就是变量声明会被提升到作用域的最顶上去,也就是该变量不管是在作用域的哪个地方声明的,都会提升到作作用域的最顶上去. 那么上面这种写法其实等价于下面这种写法: 看几个例子: 把上面的例子稍作改动: 结果就会大不一样, 再看一个例

在js中关于同名变量和函数的地位争夺问题

先上一段让大家比较蒙圈的代码,接下来再慢慢讲解 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> console.log(f