博客列表 >JS 中的函数提升和重写问题以及四种高阶函数的分析

JS 中的函数提升和重写问题以及四种高阶函数的分析

祥子弟弟
祥子弟弟原创
2021年01月11日 15:55:351099浏览

一、js 中的基本数据的类型转换问题

js 中的变量类型分为原始类型和引用类型,其中原始类型包括:1.数值,2.字符串,3.布尔类型,4.undefined 类型,5.null(空对象)类型,6.符号(Symbol)类型;引用类型包括:1.对象,2.数组,3.函数

类型转换问题

通常只有相同类型的数据在一起运算,它的结果才会有意义
比如说:

  1. let a = 10;
  2. let b = 10;
  3. let c = a + b;
  4. // 输出结果当然是c = 20;
  5. // 但是如果是字符串和数字运算
  6. a = "10";
  7. c = a + b;
  8. // 输出结果是c = 1010;
  9. // 这是因为“+”在字符串的运算中,它表示的是两个字符串的连接,
  10. // 此时会自动的触发字符转换(当运算符两边的类型不一致时,就会发生类型转换)
  11. // 并不是只有运算时会产生类型转换,当进行“==”匹配时,也会发生类型转换
  12. // 例如
  13. c = a == b;
  14. // 输出的是c = true,此时的a是一个字符串,而b是一个数值,不应该是相等的结果
  15. // 这是因为“==”属于非严格匹配,只检查值,而不检查类型
  16. // 所以在进行匹配时,一定不要使用“==”,而应该使用“===”匹配,它属于严格匹配,既检查值也检查类型(建议平时用这个)
  17. c = a === b;
  18. // 这时c = false;

二、js 中的函数提升与重写问题

在 js 中有一个很有意思的现象:不管你的函数创建在哪块,只要是创建了,然后你在代码区的任何位置都能调用到它,它默认的将一个函数的位置给提升到了代码区的最顶层,也就是说,哪怕是你的调用写在函数声明之前都是没有问题的,这就是 js 中的函数提升问题。当然变量和常量是不存在这种问题的。

  1. console.log(getName("an"));
  2. // 声明一个函数
  3. function getName(name) {
  4. return "Welcome to" + name;
  5. }
  6. // 可以看到的是,当前的调用是在声明前的,但是代码是可以执行的

而且很奇葩的是你可以取将这个函数进行重写,也就是说,你在上边声明的函数,原函数可以被后来的函数重写覆盖掉。

  1. function getName(name) {
  2. return "Welcome to" + name;
  3. }
  4. function getName(name) {
  5. return "欢迎 " + name;
  6. }
  7. console.log(getName("an"));
  8. // 此时对getName()进行调用,此时的结果就是: “欢迎 an”

所以在 js 函数中就存在两种问题:

  • 函数声明提升

  • 函数重写

解决方案:

解决函数声明提升问题:在 js 中变量是不可以在它被声明之前引用的,所以,我们可以使用匿名函数的方式去让它不在被提升。

  1. // 使用匿名函数/匿名表达式的方式。解决函数声明提升问题
  2. console.log(myName("an"));
  3. // 无法被调用
  4. let myName = function (name) {
  5. return "My name is " + name;
  6. };
  7. console.log(myName("an"));

解决函数重写问题:在 js 中常量是不能够被重新定义的,所以,我们可以将函数当成一个值赋给一个常量。同样是利用匿名函数的方式。

  1. const myName = function (name) {
  2. return "My name is " + name;
  3. };
  4. myName = function (name) {
  5. return "My name is " + name;
  6. };
  7. console.log(myName("an"));
  8. // 这时候就会发现报错信息,因为常量不允许被重新定义

三、函数参数和返回值

js 函数在 ES6 之后是支持函数设置默认参数的。在一个函数中,如果传递的参数非常多的话,就会显得很长,这时候,可以使用...rest 归并参数方法,来简化函数参数声明。

  1. let sum = function (a, b, c, d) {
  2. return a + b + c + d;
  3. };
  4. sum = function (...arr) {
  5. // return a + b + c + d;
  6. // arr是一个数组类型的数据
  7. console.log(arr);
  8. // 参数求和
  9. return arr.reduce(function (p, c) {
  10. return p + c;
  11. });
  12. };

同样的,一个函数的参数很多的话,调用它的话,传参也会很麻烦,也可以使用...扩展参数方法,来简化函数的调用参数。

  1. let arr = [1, 2, 3, 4];
  2. console.log(sum(...arr));
  3. // 可以看到的是,数组直接被转换成了单个元素传参

函数的返回值都是单值返回的,如果想要返回多个值可以将结果封装到数组或者对象中

  1. let Arr = function () {
  2. return [1, 2, 3, 4];
  3. };
  4. console.log(Arr());
  5. console.table("-------------------");
  6. // 返回值是对象的
  7. Arr = function () {
  8. return {
  9. name: "mimi",
  10. age: 18,
  11. gender: "男",
  12. };
  13. };

四、四种高阶函数

高阶函数:使用函数作为参数或将函数作为返回值的函数

1.回调函数

  1. // 给文档对象添加一个点击事件,使用函数作为参数
  2. document.addEventListener("click", function () {
  3. alert("Hello world!");
  4. });

2.偏函数:将函数中的必须参数先固定下来,其他参数交给子函数去处理

函数的闭包实现偏函数,这就有点像是定义了一个含有参数的类,里边写了一个含有参数的方法。你想要使用这个方法,你就必须先给这个类传参,然后调用这个函数的时候也得传参.

  1. let sum = function (a, b) {
  2. return function (c, d) {
  3. return a + b + c + d;
  4. };
  5. };
  6. // 调用偏函数
  7. let li = sum(1, 2);
  8. console.log(li(3, 4));

3.柯里化:每个函数只传递一个参数,最后一个函数对于参数进行处理,相当于是细致化的一个偏函数

  1. // 柯里化示例
  2. sum = function (a) {
  3. return function (b) {
  4. return function (c) {
  5. return function (d) {
  6. return a + b + c + d;
  7. };
  8. };
  9. };
  10. };
  11. // 调用这个函数
  12. let ke = sum(1)(2)(3)(4);
  13. console.log(ke);

4.纯函数:完全独立于调用上下文,返回值只受到参数影响

  1. // 纯函数示例
  2. function add(a, b) {
  3. return a + b;
  4. }
  5. console.log(add(1, 2));

五、箭头函数

箭头函数用来简化“匿名函数”的声明,箭头函数的结构:(参数) => {…};
一个简单的箭头函数示例:

  1. let sum = function (a, b) {
  2. return a + b;
  3. };
  4. // 改写成箭头函数
  5. sum = (a, b) => {
  6. return a + b;
  7. };
  8. console.log(sum(1, 2));

箭头函数的特点:
1.如果函数体只有一条语句,可以不写 return;
例如:sum = (a, b) => a + b;
2.如果函数只有一个参数,小括号也不用写;
例如:sum = a => a + 1;
3.如果没有参数,小括号不能省略
例如:sum = () => 1 + 2;
4.箭头函数没有原型属性,不能当构造函数用
5.箭头函数中的 This 始终与上下文绑定

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议