3

概述

函数的用法眼花缭乱,即便工作了很多年的人,熟悉各种框架的函数用法,但是未必知道为什么要这么用,为什么换一种用法就不可以。

这节思考课,就是从最简单的一个demo开始,逐渐展开思考,一步步尝试来理解它。

1. 基础实验

先上基础代码:

var variable
function showText(text) {
    console.log(text);
}

基础代码只有一个变量,一个函数。下面依据基础代码进行实验

函数调用与赋值

首先,调用函数并赋值给变量:

var variable
function showText(text) {
    console.log(text);
}
variable = showText('基础代码执行')
console.log(variable)

直接运行上面的代码,结果如下:

image.png

说明 showText 方法调用了。

结论一:

  • 变量赋值为一个函数调用时,函数会立即执行
  • 函数内没有return,相当于变量没有赋值(因为还是undefind)

稍稍变一下:

var variable
function showText(text) {
    console.log(text);
}
variable = showText
variable('变量赋值后调用')
console.log(variable)

再看运行结果:

image.png

结论二:

  • 变量赋值为一个函数名时,变量就指向了这个函数
  • 变量调用等于函数调用
变量调用没这个说法,姑且这么说是为了理解,就是变量名加一对括号:variable()

匿名函数调用与赋值

将变量赋值为一个匿名函数(也就是函数表达式)

var variable
function showText(text) {
    console.log(text);
}
variable = function () {
    showText('函数调用')
}
console.log(variable)
variable()

运行结果:

image.png

结论三:

  • 变量赋值为一个匿名函数时,变量就指向了这个函数
  • 赋值时匿名函数不会立即调用
  • 变量调用等于匿名函数调用

根据这三个结论,我们可以发现:

function showText(text) {
    console.log(text);
}
// 基本等同于
var showText = function(text) {
    console.log(text);
}
// 统一调用方式为:
showText('txt');

了解了基础,下面我们来看项目实践

2. react 中的用法

先来一段基础的 react 代码

import React from 'react'

const TestPage = (props) => {
    const testFun = ()=> {
        console.log('函数执行')
    }
    return (
        <div onClick={testFun}></div>
    )
}

export default TestPage;

点击事件等于函数名,函数正常触发。

应该有人试过写成这样:

<div onClick={testFun()}></div>

这样写就不行了,函数一开始就触发了,但是点击时候没反应。

但是写成这样就又正常了:

<div onClick={()=> testFun()}></div>

为什么会这样?结合第一节来分析一波。

写法 1 分析

为什么这样写可以:

<div onClick={testFun}></div>

因为这个写法就等于:

div.onClick = testFun

div.onClick 看做一个变量,再结合 结论二 可以得知:

div.onClick() == testFun()

所以在 div 执行 onClick() 时就调用了 testFun();

写法 2 分析

再看这个写法:

<div onClick={testFun()}></div>

和上一步一样的拆解

div.onClick = testFun()

结合 结论一 可以得知,testFun() 会立即执行,但是 div.onClick 等于 undefined 相当于未赋值,所以点击没反应。

写法 3 分析

<div onClick={()=> testFun()}></div>

拆解后:

div.onClick = ()=> testFun()
// 等于 es5 写法:
div.onClick = function() {
    testFun()
}

结合 结论三 可知:

匿名函数不会立即执行,onClick() 时触发 testFun(),所以正常运行

写法 4 分析

改造一波,给 div 加一段显示内容

const getName = ()=> {
    return '我是一个div'
}
<div onClick={testFun}>{getName()}</div>

发现了吗,这里又不一样了。

标签内 getName() 这么写是对的,光写函数名反而是错的,这与事件里使用函数的方法正好相反。

为什呢?因为标签内的内容就是要立即触发函数来得到的,不需要在指定条件下触发。


杨成功
3.9k 声望12k 粉丝

分享小厂可落地的前端工程与架构