Blogger Information
Blog 29
fans 1
comment 0
visits 35395
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
JS 中的函数提升和重写问题以及四种高阶函数的分析
祥子弟弟
Original
1104 people have browsed it

一、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 始终与上下文绑定

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post