• Welcome to Journal web site.

我是 PHP 程序员

- 开发无止境 -

Next
Prev

第12章 0331-流程控制与函数参数,返回值

Data: 2022-03-12 08:45:59Form: JournalClick: 4

问题集合:

1.  函数的方法我这里用箭头函数输出undefined,用function就是输出正常,这里是不能用箭头函数么

image.png

答:箭头函数中的this与函数(对象)中的this指代的不一致,指代的是整个window对象,在这个对象中,你并未定义userName,你可以仅仅打印this,看看输出的是什么。

image.png

2.  我这里提示没有了,是那个插件的功能啊?

image.png答:ctrl+i

3.  这里是否也是改成this呢?

image.png答:你这在外面引用的,不用this,改之前先想一下this是谁?他引用是谁?当前你的代码在全局this指向window, Window对象里是没有这个方法的



demo1:流程: 分支

// 1. 默认顺序执行
        {
            console.log(100);
        } {
            console.log(200);
        } {
            console.log(300);
        }
        console.log('----------------');
        // 2. 分支
        {
            console.log(100);
        }

        // 1. 单分支: if() {}

        // 2. 双分支: if() {} else { }
        // 双分支具有默认代码块
        if (false) {
            console.log(200);
        } else {
            console.log('xxxxx');
        }

        {
            console.log(300);
        }

        // true? false ? 2个值,双分支
        // 如果需要根据多种状态进行判断,就用多分支
        let age = 72;
        if (age >= 18 && age < 65) {
            console.log('欢迎进入游戏的欢乐世界');
            // 现在还有二种情况未处理? <18, >= 65
        } else if (age >= 65) {
            console.log('少玩游戏,多跳跳广场舞,多认识几个老太太');
        } else {
            // age < 18,是第二种状态,也是最后一种状态,就是默认状态
            console.log('未成年,玩的时候不能大于2小时');
        }

        // switch: 用来简化多分支
        age = 15;
        switch (true) {
            // case 条件:
            // 语句;
            // break;

            case age >= 18 && age < 65:
                console.log('欢迎进入游戏的欢乐世界');
                break;
            case age >= 65:
                console.log('少玩游戏,多跳跳广场舞,多认识几个老太太');
                break;
            default:
                console.log('未成年,玩的时候不能大于2小时');
        }

        // 单值判断
        let error = 5;

        switch (error) {
            case 0:
                console.log('请求成功');
                break;
            case 1:
                console.log('请求超时');
                break;
            case 2:
                console.log('请求错误');
                break;
            default:
                console.log('未知错误');
        }

        let gender = 0;

        // 0: 男, 1: 女

        // console.log(Boolean(0));
        // console.log(Boolean(1));

        // if (Boolean(gender)) {
        //     console.log('女');
        // } else {
        //     console.log('男');
        // }

        // 三元表达式来简单双分支
        let res = gender ? '女' : '男';
        console.log(res);
demo2: 循环
const colors = ['red', 'green', 'blue'];
        // 0:red,1:green, 2: blue
        console.log(colors[0], colors[1], colors[2]);
        console.log(colors.length);
        // 最后一个数组元素的索引是多少? 2 = colors.length - 1
        console.log(colors[2]);
        console.log(colors[colors.length - 1]);
        // 越界访问
        console.log(colors[colors.length]);

        // 如何遍历一个数组?
        // 1. 要知道从哪开始?
        let i = 0;
        // 2. 结束条件,用数组长度colors.length
        let length = colors.length;
        // 3. 更新条件,更新语句写到分支体中

        // 第一次,访问第一个
        if (i < length) {
            console.log(colors[i]);
            // i+= 1;
            i++;
        }
        // 第二次,访问第二个
        if (i < length) {
            console.log(colors[i]);
            // i+= 1;
            i++;
        }
        // 第三次,访问第三个
        if (i < length) {
            console.log(colors[i]);
            // i+= 1;
            i++;
        }
        // 第四次,访问第四个
        if (i < length) {
            console.log(colors[i]);
            // i+= 1;
            i++;
        } else {
            console.log(i);
        }
        console.log('-------------');
        // 用循环来简化以上的遍历过程
        i = 3;
        // 入口循环
        while (i < length) {
            console.log(colors[i]);
            i++;
        }
        /**
         * * 循环三条件
         * * 1. 初始条件: 数组索引的引用 ( i = 0 )
         * * 2. 循环条件: 为真才执行循环体 ( i < arr.length )
         * * 3. 更新条件: 必须要有,否则进入死循环 ( i++ )
         */
        console.log('-------------');
        i = 3;
        //   出口循环
        do {
            console.log('xxxxx');
            console.log(colors[i]);
            i++;
        } while (i < length);

        // 使用for 来简单化while
        // for (初始条件 ; 循环条件; 更新条件)
        for (let i = 0; i < colors.length; i++) {
            console.log(colors[i]);
        }
        console.log('-------------');
        // es6中的for - of
        for (let item of colors) {
            console.log(item);
        }

        // 输出对象 : for - in

        const obj = {
            id: 1,
            username: '猪老师',
            'max salary': 123456,
        };

        for (let key in obj) {
            console.log(obj[key]);
        }
demo3:函数的参数与返回值
let f = (a, b) => a + b;
        console.log(f(10, 20));
        console.log(f(10));
        // NaN: not a number

        // 1. 参数不足: 默认参数
        f = (a, b = 0) => a + b;
        console.log(f(10, 5));

        // 2. 参数过多: ...剩余参数
        f = (a, b) => a + b;
        console.log(f(1, 2, 3, 4, 5));
        // 如何将全部参数接收到? 剩余参数 ...
        // ...rest: 用在函数的形参中,归并
        f = (a, b, ...c) => console.log(a, b, c);
        // 将多出来的3,4,5压入到数组c中
        console.log(f(1, 2, 3, 4, 5));

        let arr = [1, 2, 3, 4, 5];
        // 将一个数组打散,变成一个个离散的值
        console.log(...arr);
        console.log(f(...arr));
        // 与下面这条语句功能一样
        console.log(f(1, 2, 3, 4, 5));
        // ...用在参数调用时的实参中,是解包,打散
        // f = (a, b, c, d, e, f) => a + b + c + d + e + f;
        f = (...arr) => arr.reduce((a, c) => a + c);
// 类似循环累加计数
        console.log(f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

        // 返回值: 函数只能有一个返回值,默认单值返回
        // 需要返回多个值怎么办? 数组,对象
        // 本质 上仍然返回一个值,只不过这是一个引用类型的复合值
        // function fn() {
        //     return [1, 2, 3];
        // }

        let fn = () => [1, 2, 3];

        let res = fn();
        console.log(res);

        fn = () => ({
            id: 2,
            name: 'admin',
            age: 28,
        });

        // function ssss() {
        //     return {
        //         id: 2,
        //         name: 'admin',
        //         age: 28,
        //     };
        // }

        res = fn();
        console.log(res);
demo4:对象字面量的简化
// 1. 属性简化
        let user = {
            name: '猪老师',
        };
        console.log(user.name);

        let name = '王老师';
        user = {
            // name: name,
            name,
        };
        console.log(user.name);

        // 1. 变量name与对象属性同名
        // 2. 并处于相同作用域,彼此可见,可以不写变量名

        // 2. 方法简化
        user = {
            name,
            // getName: function() {
            //     return 'Hello, ' + this.name;
            // },

            // 简化方案: 直接将 ": function"删除
            getName() {
                return 'Hello, ' + this.name;
            },
        };

        console.log(user.getName());
demo5:模板字面量与模板函数
//1 模板字面量
        console.log('Hello world');
        // 反引号:模板字面量,  支持在字符串插入变量/表达式: 插值
        console.log(`Hello world`);
        let name = '猪老师';
        console.log('hello ' + name);
        // 变量/表达式: 在模板字面量,使用 '${xxx}'来引用,就是一个占位符
        console.log(`hello ${name}`);
        let gender = 1;
        console.log(`${gender ? `男:${name}` : `女`}`);

      // 2. 模板函数
      // 使用模板字面量为参数的参数
      //   alert('Hello php.cn');
      //   alert`Hello php.cn`;

      calc`数量: ${10}单价: ${500}`;

      // 模板函数的参数:
      // 第一个参数: 模板字面量中的"字符串字面晨"
      // 第二个参数: 模板字面量中的"插值"数组
      function calc(strings, ...args) {
        console.log(strings);
        console.log(args);
        console.log(args[0] * args[1]);
      }
      /**
       * * 模板字面量: 可以使用插值表达式的字符串
       * * 模板函数: 可以使用"模板字面量"为参数的函数
       * * 模板函数,就是在"模板字面量"之前加一个标签/标识符,而这个标签,就是一个函数名
       * * 模板函数的参数是有约定的, 不能乱写, 第一个是字面量数组,从第二起才是内部的占位符参数
       */

      // * 模板字面量, 也叫"模板字符串" , 是同义词,我觉得用"模板字面量"更直观,准确
      // * 模板函数, 有的书也翻译与"标签函数", 因为 它使用"模板字面量"做参数,称为"模板函数"更直观, 一看知识必须传一个模板字面量当参数
模板字面量 拓展知识:

大量输出文本变量时,使用模板字面量会 使代码变得更简洁。

let count=1;
let price=2;
alert(`商品数量:${count},单价:${price},总计:${price*count}`)

模板字面量,是允许嵌入表达式的字符串字面量。

他的语法结构是:`string ${expression} string`

  1. 反引号包括住整个模板字面量。

  2. 表达式要用${}包括。

  3. 要在模板字面量内使用反引号,需要用斜杠转义输出。

  4. 支持输出多行模板字面量

  5. 支持表达式



    var name = '李华';
    var age = 19;
    alert(`${name} 已经 ${age} 岁了 `);

    alert(`这里要输出一个反引号\``);

 
 

在这里插入图片描述



    alert(`这里要输出一个反引号:\``);

在这里插入图片描述


    alert(`
        hello!
        goodbye!
        nice to meet u!
    `);
 

在这里插入图片描述

输出多行模板字面量时,换行处不需要手动输入\n转义符进行换行,编译器会自动识别字面量中的换行。

这有什么用呢?

当然你需要输入一大段json或者写一段html代码的时候,用多行模板字面量会非常的方便。


    /*输出一段html*/
    //注意:模板字符串内的正常单引号、双引号不需要转义
    const html=`
   <a href="">
        <img src="https://m15.360buyimg.com/mobilecms/jfs/t1/175540/24/19329/6842/60ec0b0aEf35f7384/ec560dbf9b82b90b.png!q70.jpg" alt=""><span>京东超市</span>
   </a>
    `
    document.body.innerHTML=html;




在这里插入图片描述


除了常规变量以外,模板字面量还支持插入表达式。

    var a = 5;
    var b = 10;
    console.log(`十五 是 ${a + b}
    不是 ${2 * a + b}.`);
 

在这里插入图片描述

模板字面量不仅支持简单运算符,还支持三目运算符

    var a = 5;
    var b= 10;
    alert(`最大的是:${a>b? a:b}`);
 

在这里插入图片描述

将普通参数传入函数时,我们用圆括号包裹;

将模板字面量传入函数时,我们用反引号包裹。

function add(){}

add(1,2);
add`1,2`
 

当我们将一个模板字面量传入一个函数,且这个函数有两个以上
参数时,这两个参数会有默认意义。

在这里插入图片描述

第一个参数

第一个参数(非占位符):

是以模板字面量中的${}即表达式为分隔符,分割模板字符串,只取字符串而不取表达式或者参数而构成的数组。

如:


    const template =`你好!${name}!`;

将template传入函数,那么函数的第一个参数就默认是['你好!','!',raw:Array(2)]

可以看见,除了&ldquo;你好!&rdquo;和&ldquo;!&rdquo;还有一个特殊的属性raw,这个raw并不是数组的成员,也就是说,你不能用arr[2]去访问到它。

把raw属性展开:

在这里插入图片描述

可以看到对转义符的处理,raw的属性跟arr1是不一样的。

string会识别转换转义符,而raw会将转义符再次转义成普通字符串,最后输出原样的字符串。

在这里插入图片描述

其他参数

第二个及以后的参数(占位符)

如果函数只有2个参数,而传入的模板字面量有多个占位符(表达式)时,
那么,第二个参数只能对应模板字面量中的第一个占位符(表达式)

    const name = '小明';
    const greet = '你好呀!';

    function show(arr, holder){
        console.log(holder);
    }

    show`${name} 给小红打招呼,说:&ldquo;${greet}&rdquo;`
Name:
<提交>