实例演示流程的分支循环和函数参数的返回值,并对对象字面量和模板字面量进行了演示,分析了模板字面量和模板函数的参数功能
以防以后代码不会,今日代码学习部分又很长,将自己写的整体代码部分,放到文章的最后.
流程控制
流程控制分支
- 默认分支
- 顺序分支,顺序分支又分为单分支, 双分支,多分支
- 循环分支
默认分支
代码示例:
{
console.log("我爱你");
}
// 分支的意思就是有条件的时候,执行
// 单分支,就是执行的时候判断一次,只有一个分支结果
// 声明一个变量
let love = 10;
if (love >= 10) {
console.log("我爱你十分");
}
运行示例图:
双分支
语法:
if(条件){
成立结果
}else{
不成立结果
}
//简化方案语法
let ai = love <= 15 ? "成立" : "不成立";
//前面我用let 声明了一个ai变量,把结果储存里面了
代码示例:
// 双分支
// 有一个默认分支,除了判断的那个分支外,当找不到当前匹配的结果时,默认的那个分支
love = 16;
if (love <= 15) {
console.log("你对我的爱还没有十五分");
} else {
console.log("还是你比较爱我,都超过15分了");
}
// 双分支的简化
// 需要用一个变量声明来做,下面是简化方案:
let ai = love <= 15 ? "你对我的爱还没有十五分" : "还是你厉害,爱死我了,对我的爱都超过15分了";
console.log(ai);
// 语法请记住,双支判断的时候,是 判断语法 ? true : false;
示例截图:
多分支:
示例代码:
语法:
if (条件) {
结果
} else if (条件) {
结果
} else if (条件) {
结果
}
//简写switch版本
switch (传入的值或表达式进入) {
case 条件判断:
//需要输出的值
break;
case 条件判断:
//需要输出的值
break;
default:
//默认值
break;
}
// 多分支
love = 55;
if (love <= 10) {
console.log("我还没超过十岁拉");
} else if (love > 10 && love <= 20) {
console.log("我在10到20岁之间");
} else if (love >= 21 && love <= 35) {
console.log("我还是青春期吗???");
} else if (love >= 36 && love <= 50) {
console.log("我现在是青壮年??");
} else if (love >= 51 && love <= 60) {
console.log("我这年级上不了班了,在家待业吧,要不就看个大门吧");
} else if (love >= 60) {
console.log("超过60啦,在家哄小孩啦");
}
// 多分支优化简写版本
love = 50;
switch (true) {
case love > 10 && love <= 20:
console.log("我在十岁到20岁之间");
break;
case love >= 21 && love <= 35:
console.log("我还是青春期吗???");
default:
console.log("你猜猜我几岁");
}
// love = 10;
// switch (true) {
// case love > 10 && love <= 20:
// console.log ("我还没超过十岁拉");
// break;
// default:
// console.log("我在10到20岁之间");
// }
代码示例截图:
单值判断变量
单值条件判断,其实我还是用的是多分支,只不过用swith传入了一个值
使用了一个方法.toLocaleLowerCase() //对字母大小写进行格式化
let zhan = "dedecms";
// 还可以对字符格式化处理,比如别人提供的api是大小写字母等操作,我们需要对大小写进行格式化
zhan = "Diguocms";
zhan = "Zblog";
// switch语法是,
// seitch(判断,可以是外部变量的判断) {
// case 结果(这个结果可能是一个字符也可能是数字,甚至可能是一个表达式 break)}
switch (zhan.toLocaleLowerCase()) {
case "dedecms":
console.log("目前使用的织梦cms");
break;
case "diguocms":
console.log("目前使用的帝国cms");
break;
case "zblog":
console.log("目前使用zblog博客程序");
break;
default:
console.log("可能大佬用的discuz吧");
break;
}
示例截图:
流程控制: 循环
先进行获取数组的长度
使用代码:.length
获取数组的长度
代码示例:
// 先声明一个数组类常量
const niuniu = ["niu", "luotuo", "feiji"];
// 打印一下
console.log(niuniu[0], niuniu[1], niuniu[2]);
// 当前的索引是从0开始,0 , 1, 2
// array是一个数组, 数组就是对象, 既然是对象就有方法和属性;
console.log(niuniu.length);
// .length 打印当前数组的长度.数组名.length
// 当前属性是打印数组的长度,当前数组有三个对象,;
console.log(niuniu[2]);
console.log(niuniu[3]);
// 提示越界了,没有这个参数
console.log(niuniu.length - 1);
console.log(niuniu[niuniu.length - 1]);
console.log(niuniu[niuniu.length]);
// 因为数组的长度是3,但是数组是从0开始的,结束就为2,所以超出越界了,因为数组的索引是从0开始
示例截图:
遍历索引
遍历索引的条件:
遍历循环数据的三个条件
- 起始索引
- 循环条件
- 更新条件
代码示例:
// 先声明一个当前索引
let a = 0;
let b = niuniu.length;
// 遍历循环数据的三个条件, 1,起始索引, 2,更新, 3,结束
if (a < b) {
console.log(niuniu[a]);
a = a + 1;
}
if (a < b) {
console.log(niuniu[a]);
a = a + 1;
}
if (a < b) {
console.log(niuniu[a]);
a = a + 1;
// 或者a++,意思一样
}
////////////////////
/////下面是简化方案
///////////////////
//这里以后回来看不要看不懂哦,这里是已经使用.length获取了数组的长度,let b = niuniu.length;赋值给了参数b,在上面,所以条件是当a=0,当a小于b时,a++,
a = 0;
while (a < b) {
console.log(niuniu[a]);
a++;
}
/**
* * 循环三条件
* * 1. 初始条件: 数组索引的引用 ( i = 0 )
* * 2. 循环条件: 为真才执行循环体 ( i < arr.length )
* * 3. 更新条件: 必须要有,否则进入死循环 ( i++ )
*/
示例截图:
简体方案一在上面已经写了第一个,下面是第二种简体方案
是用do while,
while是先判断条件是否成立,然后再进入循环体执行,do while是无论是否条件成立,都将循环一次.
示例代码:
// //while()入口型判断
// * do {} while(), 出口型判断,无论条件是否成立, 必须执行一次代码块
a = 0;
do {
console.log(niuniu[a]);
a++;
} while (a < niuniu.length);
// do循环是先执行一遍,然后才是判断语句
示例截图:
既然是循环体,那么还可以继续优化,继续优化的方案就是,先计算数组的长度,计算完毕后赋值给一个参数,老师还说了其他两种方案,哪两种方案最后说
先看未使用迭代,直接使用for循环的方式
代码部分:
// ! for () 是 while 的简化
// * 语法: for (初始条件; 循环条件; 更新条件) {...}
for (a = 0; a < niuniu.length; a++) {
console.log(niuniu[a]);
}
示例截图:
使用先计算数组长度,再进行循环的
就是预先将数组的长度,计算出来,放入到一个变量中,不必要每次循环都将计算数组的长度
代码部分:
// 优化方案
// 这个理解为,初始条件为a等于0,b是数组长度,当a小于数组长度时,a自身+1
// 优化, 将数组长度,提前计算出来缓存到一个变量中
for (a = 0, b = niuniu.length; a < b; a++) {
console.log(niuniu[a]);
}
剩下的是两种迭代器的for of 和for in方案,在es6中很常见的方案
for of:对数组操作循环
for in:对对象操作循环,当然,数组也是对象,也可以使用,但是不建议使用
首先说for of要知道几个方法,我用表格写到下面:
方法 | 使用方式/示例 | 说明 |
---|---|---|
.entries() | 数组.keys()/niuniu.keys() | .entries() 数组成员, 输出数组中的 “键值” 对组成的数组 |
.keys() | 数组.entries/niuniu.entries | .keys()输出数组中的 “键” 对组成的数组 |
.values() | 数组.values/niuniu.values | 输出数组中的 “值” 对组成的数组默认调用values(),输出值 |
for of代码语法:
for (let 变量 of 数组.entries()) {
console.log(变量);
}
代码示例:
// ! for - of : 快速迭代处理集合数据
// * 数组内部有一个迭代器的方法, 可以用for-of
// * for-of优点: 用户不必再去关心索引, 而将注意力集中到数组成员上
// 感觉for - of 是魔改版本,因为他缺少了起始和更新条件,只有一个数组成员,而数组成员直接赋值给了变量,变成了数组
// 写法是:
// 使用到一个新的对象方法,
// .entries() 数组成员
// v 输出数组中的 "键值" 对组成的数组
// .keys()
// v 输出数组中的 "键" 对组成的数组
// .values()
// v 输出数组中的 "值" 对组成的数组
// ! 默认调用values(),输出值
// for (let 变量 of 数组.entries()) {
// console.log(变量);
// }
// 上面这个变量,也是数组成员的意思
// for -of是针对数组使用
for (let shuzu of niuniu.entries()) {
console.log(shuzu);
}
for (let shuzu of niuniu.keys()) {
console.log(shuzu);
// 提取键
}
for (let shuzu of niuniu.values()) {
console.log(shuzu);
// 提取的键值对的对
}
for (let shuzu of niuniu) {
console.log(shuzu);
// 默认提取的键值对的对
}
示例截图:
for in语法:
for (let 变量/数组成员 in 数组) {
console.log(数组[变量/数组成员]);
}
示例代码:
// for -in是针对对象使用
// 遍历对象跟遍历数组稍微有一点不同;
// 遍历对象是以下写法;
// for (let 变量/数组成员 in 数组) {
// console.log(数组[变量/数组成员]);
// }
// 上面这个变量也是数组成员的意思
let niuniu1 = {
name: "名字",
name2: "名字2",
name3: "名字3",
};
for (let shuzu1 in niuniu1) {
console.log(niuniu1[shuzu1]);
}
for (let shuzu of niuniu.values()) {
console.log(shuzu);
}
// 数组数组 数组 数组也是对象
for (let shuzu2 in niuniu) {
console.log(niuniu[shuzu2]);
}
函数的参数与返回值
参数不足及参数过多的解决方案
参数不足的解决方案:
其实就是在方法里面默认一个参数,默认之后再调用结果的时候,并不会影响到调用时的结果.
直接上代码部分:
let ad = (a, b) => a + b;
console.log(ad(1, 2));
console.log(ad(1));
ad = (a, b = 0) => a + b;
console.log(ad(1));
console.log(ad(5, 5));
// 在参数返回值不足的情况下,给当前函数对象一个默认返回值即可
ad = function mingzi(a, b = 0) {
return a + b;
};
console.log(ad(1, 2));
function mingzi(a, b) {
return a + b;
}
console.log(mingzi(1, 2));
示例截图:
参数过多的解决方案:
使用… rest语法,剩余参数,归并参数,将所以参数全部压入到一个数组中
…语法还可以将集合展开
将数组压入到一个数组中
// 将多余的数字,可以以数组的方式全部接收
// ! ...: rest语法,剩余参数,归并参数,将所以参数全部压入到一个数组中
ad = (...c) => c;
console.log(ad(1, 2, 3, 4, 5, 6));
// 将所有的数字,压缩成数组,放到...c中
示例截图:
示例2:赋值方式:
ad = (a, b, ...shuzu) => `${a},${b},${shuzu}`;
console.log(ad(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
示例截图:
将数组展开
示例代码:
// 将集合数据展开
console.log(...[1, 2, 3, 4, 5]);
let ad1 = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(...ad1);
示例截图:
花絮部分,老师写的箭头函数代码,老师说我们还没学到,我就暂时先对代码还原成了非箭头函数
let f = (...arr) => arr.reduce((a, c) => a + c);
console.log(f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
//没学高阶函数,那就先给老师的讲解进行还原
f = function (...arr) {
return arr.reduce(function (a, c) {
return a + c;
});
};
console.log(f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
// 从服务器API接口获取到了个商品列表: JSON数组
const list = ["笔记本电脑", "小米12手机", "佳能 EOS-R相机"];
console.log(list);
// 将每个商品,套上html标签,最终渲染到html页面中
f = (...items) => items.map(item => `<li>${item}</li>`).join("");
console.log(f(...list));
// document.body.innerHTML = "<ul>" + f(...list) + "</ul>";
qq = function (...items) {
return items
.map(function (item) {
return `<li>${item}</li>`;
})
.join("");
};
console.log(qq(...list));
代码运行参数截图:
利用函数返回多个值
/ ! 返回值
// p 函数默认:'单值返回'
// y 如何返回多个值?
// 数组
qq = () => [1, 2, 3, 4, 5];
console.log(qq());
// 拆分处理
console.log(...qq());
// 结合for of循环提取键跟值
for (let tiqu of qq().entries()) {
console.log(tiqu);
}
for (let tiqu of qq().keys()) {
console.log(tiqu);
}
console.log(qq());
// 对象
qq = () => ({ name: "名字", Name: "名字2", nAme: "名字三" });
console.log(qq());
// 还原以上函数
//对象
let qq1 = function () {
return { name: "名字", Name: "名字2", nAme: "名字三" };
};
console.log(qq1());
// 结合for in循环提取
for (let tiqu in qq1()) {
console.log(qq1()[tiqu]);
}
对象字面量的简化
对象字面量的简化 推荐使用部分
属性简化
1 变量name 与 属性name 同名
2且在同一个作用域中,可以不写变量名
代码部分:
//对象字面量的简化 推荐使用部分
//先声明一个变量
let name = "小明";
let a = {
name: name,
};
console.log(a.name);
// 简化
a = {
name,
};
console.log(a.name);
// name: "猪老湿",
// name: name,
// * 1 变量name 与 属性name 同名
// * 2且在同一个作用域中,可以不写变量名
// 不加this返回的是数组的值
a = () => name;
console.log(a());
示例截图:
方法简化
所谓方法:本质仍是属性,只不过它的值是一个函数声明
在对象中的函数中,是简化,将 ”: function” 删除
并且记住:
箭头函数如果用到 this, 就不要用到对象字面量方法中
this: 普通函数, 调用时确定
this: 箭头函数, 声明时确定
先贴一个老师写的部分: 先贴一个老师写的部分:
user = {
name,
// 所谓方法:本质仍是属性,只不过它的值是一个函数声明
// getName: function () {
// return this.name;
// },
// 简化,将 ”: function" 删除
getName() {
return this.name;
},
// 箭头函数
getName1: () => user.name,
// 箭头函数如果用到 this, 就不要用到对象字面量方法中
// this: 普通函数, 调用时确定
// this: 箭头函数, 声明时确定
};
console.log(user.getName());
console.log(user.getName1());
自己的代码:
// 方法简化 对象内有数组的情况
a = {
name,
ab: function () {
return a.name;
},
};
console.log(a.ab());
a = {
name,
ab: function () {
return this.name;
},
};
console.log(a.ab());
// 简写
a = {
name,
ab: () => a.name,
ac() {
return this.name;
},
};
console.log(a.ab());
console.log(a.ac());
示例截图:
模板字面量与模板函数
先说模板字面量,算是一个较为好理解的.
模板字面量可以在传统的代码中插入插值,甚至可以计算以及放入块元素
使用到的符号为 打不出来,就是在键盘TAB上面那个键,也是在键盘左上角,esc下面那个站,键盘1旁边那个键,在使用字面量中,如果字面量中有变量,需要用${变量不限于一个}
包裹,在计算中,包裹的变量是${a+b}
这种,放入块元素时,需要对非变量,也就是字符部分需要用(没办法打不出来,就是tab上面那个键)符号包裹起来,直接上示例代码及图吧
//模板字面量与模板函数
// 模板字面量
// 传统如下:
console.log("你好啊php");
// 模板字面量可以在传统的代码中插入插值
let php = "php";
console.log(php);
console.log("你好" + php);
console.log(`你好${php}`);
// 还可以进行计算使用
console.log(`1+1=${1 + 1}`);
//甚至可以放入块元素
console.log(`${10 > 1 ? `大于` : `小于`}`);
刚刚看到一份老师的解释,贴出来
/**
* * 模板字面量: 可以使用插值表达式的字符串
* * 模板函数: 可以使用"模板字面量"为参数的函数
* * 模板函数,就是在"模板字面量"之前加一个标签/标识符,而这个标签,就是一个函数名
* * 模板函数的参数是有约定的, 不能乱写, 第一个是字面量数组,从第二起才是内部的占位符参数
*/
// v 模板字面量, 也叫"模板字符串" , 是同义词,我觉得用"模板字面量"更直观,准确
// v 模板函数, 有的书也翻译与"标签函数", 因为 它使用"模板字面量"做参数,称为"模板函数"更直观, 一看知识必须传一个模板字面量当参数
我的示例截图:
模板函数
模板函数也比较有意思,在声明成模板函数时,函数里面的第一个参数将变成数组,剩下那俩还是参数,在调用中,字符串的部分,将储存到数组中,也就是第一个参数中,在调用其他俩参数时,需要用${}来包裹,第一个参数既然已经成为了数组,那么调用他的方式,将以数组的方式调用.本来已经写完了,刚刚又看到老师的最后一段代码,发现一个事情,是模板函数中,…rest 将插值进行合并,如果使用$(数字)传入的参数值,那么此参数将直接传值给函数里面,看第三份示例图下面的代码
先上一份截图:
再上一份定义为模板函数的
代码部分:
// 当函数声明使用函数模板时,函数声明内的第一个对象变为数组,后面的为值
// function name(string, y, q) {
// console.log(string);
// console.log(y, q);
// let jiage = ` ${string[0]} ${y} ${string[1]} ${q} ${string[2]} ${y * q}${string[3]} `;
// console.log(jiage)
// }
// let y = 10;
// let q = 20;
// name`当前的蔬菜价格单价为${y}数量为${q}总价格为 ${y * q}元`;
function name(string, y, q) {
console.log(string);
console.log(y, q);
let jiage = ` ${string[0]} ${y} ${string[1]} ${q} ${string[2]} ${y * q}${string[3]} `;
console.log(jiage);
}
let y = 10;
let q = 20;
// 使用函数模板时不需要加(),如下 name``;
name`当前的蔬菜价格单价为${y}数量为${20}总价格为 ${y * q}元`;
// name();
// name``;
// console.log(name(1, y, q));
代码示例截图:
调用的代码部分:
// ! 模板函数的优化, 以后只用这一种, 上面也要能看懂
// * 使用 ...rest 将插值进行合并
function sum(strings, ...args) {
console.log(strings);
console.log(args);
console.log(`[${args.join()}] 之和是: ${args.reduce((a, c) => a + c)}`);
}
// 调用
sum`计算多个数和: ${1}${2}${3}${4}`;
示例截图:
get代码:.join()
将数组以字符串方式返回.reduce
数组内的数据总和
老师下面的就不用看了,自己写的代码,保存一下 后面自己学习用
先贴老师的:
流程分支
// todo 流程控制 : 分支
/**
* * 程序默认执行流程:
* * 1. 顺序: (默认)
* * 2. 分支: 单分支, 双分支, 多分支
* * 3. 循环: 单分支的重复执行
*/
// 代码块
{
console.log("Hello php.cn");
}
// ! 分支: 有条件的执行某个代码块
// * 单分支: 仅当表达式计算结果为真时, 才执行代码块
let age = 28;
// age >= 18 true: 执行
if (age >= 18) {
console.log("允许观看");
}
// 如果为false, 怎么办?
// 创建一个分支: 默认分支, else
// ! 双分支: 有一个"默认分支"
age = 15;
if (age >= 18) {
console.log("允许观看");
}
// * 默认分支
else {
console.log("少儿不宜");
}
// ! 双分支的简化
// ! 双分支属于高频操作, 系统提供了一个"语法糖"(简化方案): 三元
// * 语法: (条件) ? true : false
age = 50;
let res = age >= 18 ? "允许观看" : "少儿不宜";
console.log(res);
// ! 多分支: 有多个"默认分支"
age = 4;
if (age >= 18 && age < 35) {
console.log("允许单独观看");
}
// * 第1个默认分支
else if (age >= 35 && age < 60) {
console.log("建议二人观看");
}
// * 第2个默认分支
else if (age >= 60 && age < 120) {
console.log("建议在家人陪同下观看");
}
// * 第3个默认分支: 异常分支, 使用 "||" 或 , 满足条件之一就可以了, true
else if (age <= 3 || age >= 120) {
console.log("非法年龄");
}
// * 默认分支(可选)
else {
console.log("少儿不宜");
}
// 传统多分, if - else if - else if --- , 代码混乱
// switch 进行优化
// ! 多分支 switch
age = 18;
// * 区间判断, 使用 true
switch (true) {
case age >= 18 && age < 35:
console.log("允许单独观看");
break;
case age >= 35 && age < 60:
console.log("建议二人观看");
break;
case age > 60 && age < 120:
console.log("请在家人陪同下观看");
break;
case age <= 3 || age >= 120:
console.log("非法年龄");
break;
default:
console.log("少儿不宜");
}
// * 单值判断: 变量
let lang = "html";
lang = "css";
lang = "javascript";
lang = "js";
lang = "CSS";
lang = "JavaScript";
// lang = "HTML";
console.log(lang.toLowerCase());
switch (lang.toLowerCase()) {
// 将传入的进行判断的变量值,进行统一化
// 将传入的字符串, 全部小写, 或者 大写
case "html":
console.log("超文本标记语言");
break;
case "css":
console.log("层叠样式表");
break;
case "javascript":
case "js":
console.log("通用前端脚本编程语言");
break;
default:
console.log("不能识别");
}
流程控制循环:
// todo 流程控制: 循环
const colors = ["red", "green", "blue"];
// 0: red, 1: green, 2: blue
// * 1. 从哪开始? 2. 到哪结束? 索引从 0 开始, 到2 结束
console.log(colors[0], colors[1], colors[2]);
//array是一个对象, 是对象就会有属性或方法
// colors.length 数组长度, 数组内的成员数量
console.log(colors.length);
// 最后一个
console.log(colors[2]);
console.log(colors[colors.length - 1]);
// 遍历结束的标记, 数组越界了, undefined
console.log(colors[3]);
console.log(colors[colors.length]);
// * 1. 起始索引
let i = 0;
// * 2. 循环条件
let length = colors.length;
// i < colors.length 直到 i === 3 , i === colors.length的时候,遍历结束
// * 3. 更新条件
// 让数据的索引,自动指向下一个成员, 更新必须在代码块中
// ! 必须更新条件,否则进入死循环
// 第1次遍历
if (i < length) {
console.log(colors[i]);
// * 更新条件, 将 i 指向下一个元素的索引
// i = i + 1;
// i += 1;
// 如果每一次都递增 1, 还可进一步简化
i++;
}
console.log(i);
// 第2次遍历
if (i < length) {
console.log(colors[i]);
// * 更新条件
i++;
}
console.log(i);
// 第3次遍历
if (i < length) {
console.log(colors[i]);
// * 更新条件
i++;
}
console.log(i);
// 第4次遍历, 3 === length, i<length 为 false 不执行了
if (i < length) {
console.log(colors[i]);
// * 更新条件
i++;
}
console.log(i);
// ! while 循环
// * while 可以将上面的多次的if()遍历进行合并
i = 0;
while (i < length) {
console.log(colors[i]);
// * 更新条件
i++;
}
/**
* * 循环三条件
* * 1. 初始条件: 数组索引的引用 ( i = 0 )
* * 2. 循环条件: 为真才执行循环体 ( i < arr.length )
* * 3. 更新条件: 必须要有,否则进入死循环 ( i++ )
*/
// //while()入口型判断
// * do {} while(), 出口型判断,无论条件是否成立, 必须执行一次代码块
i = 0;
do {
console.log(colors[i]);
// * 更新条件
i++;
} while (i > length);
// ! for () 是 while 的简化
// * 语法: for (初始条件; 循环条件; 更新条件) {...}
for (let i = 0; i < colors.length; i++) {
console.log(colors[i]);
}
// 优化, 将数组长度,提前计算出来缓存到一个变量中
for (let i = 0, length = colors.length; i < length; i++) {
console.log(colors[i]);
}
// ! for - of : 快速迭代处理集合数据
// * 数组内部有一个迭代器的方法, 可以用for-of
// * for-of优点: 用户不必再去关心索引, 而将注意力集中到数组成员上
// v 输出数组中的 "键值" 对组成的数组
for (let item of colors.entries()) {
console.log(item);
}
// v 输出数组中的 "键" 对组成的数组
for (let item of colors.keys()) {
console.log(item);
}
// v 输出数组中的 "值" 对组成的数组
for (let item of colors.values()) {
console.log(item);
}
// ! 默认调用values(),输出值
for (let item of colors) {
console.log(item);
}
// ! for - in: 遍历对象
const obj = { a: 1, b: 2, c: 3, say: function () {} };
// 遍历对象
for (let key in obj) {
console.log(obj[key]);
}
// 数组也是对象
for (let i in colors) {
console.log(colors[i]);
}
// 数组也能用for-in,但不要这么用, for - of, forEach, map...
函数的参数与返回值
// ! 函数的参数与返回值
// y 1. 参数不足: 默认参数
let f = (a, b) => a + b;
console.log(f(1, 2));
// Nan: Not a Number
console.log(f(1));
// * 解决方案: 默认参数
f = (a, b = 0) => a + b;
console.log(f(1));
console.log(f(1, 2));
// y 2. 参数过多, ...rest
f = (a, b) => a + b;
// 多余的参数3,4忽略了
console.log(f(1, 2, 3, 4));
// 怎么将多余的参数,全部接收? ...rest
f = (...arr) => arr;
// ! ...: rest语法,剩余参数,归并参数,将所以参数全部压入到一个数组中
console.log(f(1, 2, 3, 4, 5));
// ...集合数据,可以将它"展开"成一个个独立的元素,用在调用的时候
console.log(...[1, 2, 3, 4]);
f = (a, b, ...arr) => `${a}, ${b}, ${arr}`;
f = (a, b, ...arr) => `${a}, ${b}, ${arr}`;
// f = function (a, b, ...arr) {
// return a',' b',' arr;
// };
console.log(f(1, 2, 3, 4, 5, 6));
f = (a, b, ...arr) => arr;
console.log(f(1, 2, 3, 4, 5, 6));
// 计算任何数量的数据之和
f = (...arr) => arr.reduce((a, c) => a + c);
console.log(f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
// 从服务器API接口获取到了个商品列表: JSON数组
const list = ["笔记本电脑", "小米12手机", "佳能 EOS-R相机"];
console.log(list);
// 将每个商品,套上html标签,最终渲染到html页面中
f = (...items) => items.map(item => `<li>${item}</li>`).join("");
console.log(f(...list));
// document.body.innerHTML = "<ul>" + f(...list) + "</ul>";
// ! 返回值
// p 函数默认:'单值返回'
// y 如何返回多个值?
// * 数组
f = () => [1, 2, 3];
console.log(f());
// * 对象: 模块
f = () => ({ a: 1, b: 2, get: function () {} });
console.log(f());
对象字面量的简化:
// y 对象字面量的简化,推荐使用
let name = "猪老湿";
// ! 属性简化
let user = {
// name: "猪老湿",
// name: name,
// * 1 变量name 与 属性name 同名
// * 2且在同一个作用域中,可以不写变量名
name,
};
console.log(user.name);
// ! 方法简化
user = {
name,
// 所谓方法:本质仍是属性,只不过它的值是一个函数声明
// getName: function () {
// return this.name;
// },
// 简化,将 ”: function" 删除
getName() {
return this.name;
},
// 箭头函数
getName1: () => user.name,
// 箭头函数如果用到 this, 就不要用到对象字面量方法中
// this: 普通函数, 调用时确定
// this: 箭头函数, 声明时确定
};
console.log(user.getName());
console.log(user.getName1());
模板字面量与模板函数
// y 模板字面量 与 模板函数
// ! 模板字面量
// 传统
console.log("hello world");
// 模板字面量
console.log(`hello world`);
// 模板字面量中,可以使用"插值"(变量,表达式),可以解析变量
let name = "朱老师";
console.log("Hello " + name);
// 变量/表达式等插值,使用 ${...}插入到模板字面量中
console.log(`Hello ${name}`);
console.log(`10 + 20 = ${10 + 20}`);
console.log(`${10 < 20 ? `大于` : `小于`}`);
// ! 模板函数
// * 就是使用"模板字面量'为参数的函数
//* 模板函数(第一个参数是字面量组成的数组,第二个参数起,是字面量中的插值列表)
// y 声明模板函数
function total(strings, num, price) {
console.log(strings);
console.log(num, price);
}
let num = 10;
let price = 20;
// y 调用模板函数
total`数量: ${10}单价:${500},${10}`;
// ! 模板函数的优化, 以后只用这一种, 上面也要能看懂
// * 使用 ...rest 将插值进行合并
function sum(strings, ...args) {
console.log(strings);
console.log(args);
console.log(`[${args.join()}] 之和是: ${args.reduce((a, c) => a + c)}`);
}
// 调用
sum`计算多个数和: ${1}${2}${3}${4}`;
/**
* * 模板字面量: 可以使用插值表达式的字符串
* * 模板函数: 可以使用"模板字面量"为参数的函数
* * 模板函数,就是在"模板字面量"之前加一个标签/标识符,而这个标签,就是一个函数名
* * 模板函数的参数是有约定的, 不能乱写, 第一个是字面量数组,从第二起才是内部的占位符参数
*/
// v 模板字面量, 也叫"模板字符串" , 是同义词,我觉得用"模板字面量"更直观,准确
// v 模板函数, 有的书也翻译与"标签函数", 因为 它使用"模板字面量"做参数,称为"模板函数"更直观, 一看知识必须传一个模板字面量当参数
自己的部分:
流程控制:
// 流程控制分支
// 默认分支
// 顺序分支,顺序分支又分为单分支, 双分支,多分支
// 循环分支
// 代码块
{
console.log("我爱你");
}
// 分支的意思就是有条件的时候,执行
// 单分支,就是执行的时候判断一次,只有一个分支结果
// 声明一个变量
let love = 10;
if (love >= 10) {
console.log("我爱你十分");
}
// 双分支
// 有一个默认分支,除了判断的那个分支外,当找不到当前匹配的结果时,默认的那个分支
love = 16;
if (love <= 15) {
console.log("你对我的爱还没有十五分");
} else {
console.log("还是你比较爱我,都超过15分了");
}
// 双分支的简化
// 需要用一个变量声明来做
let ai = love <= 15 ? "你对我的爱还没有十五分" : "还是你厉害,爱死我了,对我的爱都超过15分了";
console.log(ai);
// 语法请记住,双支判断的时候,是 判断语法 ? true : false;
// 多分支
love = 55;
if (love <= 10) {
console.log("我还没超过十岁拉");
} else if (love > 10 && love <= 20) {
console.log("我在10到20岁之间");
} else if (love >= 21 && love <= 35) {
console.log("我还是青春期吗???");
} else if (love >= 36 && love <= 50) {
console.log("我现在是青壮年??");
} else if (love >= 51 && love <= 60) {
console.log("我这年级上不了班了,在家待业吧,要不就看个大门吧");
} else if (love >= 60) {
console.log("超过60啦,在家哄小孩啦");
}
// 多分支优化版本
love = 50;
switch (true) {
case love > 10 && love <= 20:
console.log("我在十岁到20岁之间");
break;
case love >= 21 && love <= 35:
console.log("我还是青春期吗???");
default:
console.log("你猜猜我几岁");
}
// love = 10;
// switch (true) {
// case love > 10 && love <= 20:
// console.log ("我还没超过十岁拉");
// break;
// default:
// console.log("我在10到20岁之间");
// }
// 单值判断变量
let zhan = "dedecms";
// 还可以对字符格式化处理,比如别人提供的api是大小写字母等操作,我们需要对大小写进行格式化
zhan = "Diguocms";
zhan = "Zblog";
// 将传入的进行判断的变量值,进行统一化
// 将传入的字符串, 全部小写, 或者 大写
switch (zhan.toLocaleLowerCase()) {
case "dedecms":
console.log("目前使用的织梦cms");
break;
case "diguocms":
console.log("目前使用的帝国cms");
break;
case "zblog":
console.log("目前使用zblog博客程序");
break;
default:
console.log("可能大佬用的discuz吧");
break;
}
流程控制与循环
// 先声明一个数组类常量
const niuniu = ["niu", "luotuo", "feiji"];
// 打印一下
console.log(niuniu[0], niuniu[1], niuniu[2]);
// 当前的索引是从0开始,0 , 1, 2
// array是一个数组, 数组就是对象, 既然是对象就有方法和属性;
console.log(niuniu.length);
// .length 打印当前数组的长度.数组名.length
// 当前属性是打印数组的长度,当前数组有三个对象,;
console.log(niuniu[2]);
console.log(niuniu[3]);
// 提示越界了,没有这个参数
console.log(niuniu.length - 1);
console.log(niuniu[niuniu.length - 1]);
console.log(niuniu[niuniu.length]);
// 因为数组的长度是3,但是数组是从0开始的,结束就为2,所以超出越界了,因为数组的索引是从0开始
// 先声明一个当前索引
let a = 0;
let b = niuniu.length;
// 遍历循环数据的三个条件, 1,起始索引, 2,更新, 3,结束
if (a < b) {
console.log(niuniu[a]);
a = a + 1;
}
if (a < b) {
console.log(niuniu[a]);
a = a + 1;
}
if (a < b) {
console.log(niuniu[a]);
a = a + 1;
// 或者a++,意思一样
}
a = 0;
while (a < b) {
console.log(niuniu[a]);
a++;
}
/**
* * 循环三条件
* * 1. 初始条件: 数组索引的引用 ( i = 0 )
* * 2. 循环条件: 为真才执行循环体 ( i < arr.length )
* * 3. 更新条件: 必须要有,否则进入死循环 ( i++ )
*/
// //while()入口型判断
// * do {} while(), 出口型判断,无论条件是否成立, 必须执行一次代码块
a = 0;
do {
console.log(niuniu[a]);
a++;
} while (a < niuniu.length);
// do循环是先执行一遍,然后才是判断语句
// ! for () 是 while 的简化
// * 语法: for (初始条件; 循环条件; 更新条件) {...}
for (a = 0; a < niuniu.length; a++) {
console.log(niuniu[a]);
}
// 优化方案
// 这个理解为,初始条件为a等于0,b是数组长度,当a小于数组长度时,a自身+1
// 优化, 将数组长度,提前计算出来缓存到一个变量中
for (a = 0, b = niuniu.length; a < b; a++) {
console.log(niuniu[a]);
}
// ! for - of : 快速迭代处理集合数据
// * 数组内部有一个迭代器的方法, 可以用for-of
// * for-of优点: 用户不必再去关心索引, 而将注意力集中到数组成员上
// 感觉for - of 是魔改版本,因为他缺少了起始和更新条件,只有一个数组成员,而数组成员直接赋值给了变量,变成了数组
// 写法是:
// 使用到一个新的对象方法,
// .entries() 数组成员
// v 输出数组中的 "键值" 对组成的数组
// .keys()
// v 输出数组中的 "键" 对组成的数组
// .values()
// v 输出数组中的 "值" 对组成的数组
// ! 默认调用values(),输出值
// for (let 变量 of 数组.entries()) {
// console.log(变量);
// }
// 上面这个变量,也是数组成员的意思
// for -of是针对数组使用
for (let shuzu of niuniu.entries()) {
console.log(shuzu);
}
for (let shuzu of niuniu.keys()) {
console.log(shuzu);
// 提取键
}
for (let shuzu of niuniu.values()) {
console.log(shuzu);
// 提取的键值对的对
}
for (let shuzu of niuniu) {
console.log(shuzu);
// 默认提取的键值对的对
}
// for -in是针对对象使用
// 遍历对象跟遍历数组稍微有一点不同;
// 遍历对象是以下写法;
// for (let 变量/数组成员 in 数组) {
// console.log(数组[变量/数组成员]);
// }
// 上面这个变量也是数组成员的意思
let niuniu1 = {
name: "名字",
name2: "名字2",
name3: "名字3",
};
for (let shuzu1 in niuniu1) {
console.log(niuniu1[shuzu1]);
}
for (let shuzu of niuniu.values()) {
console.log(shuzu);
}
// 数组数组 数组 数组也是对象
for (let shuzu2 in niuniu) {
console.log(niuniu[shuzu2]);
}
函数的参数与返回值
//函数的参数与返回值
//函数的参数返回值不足的情况
let ad = (a, b) => a + b;
console.log(ad(1, 2));
console.log(ad(1));
ad = (a, b = 0) => a + b;
console.log(ad(1));
console.log(ad(5, 5));
// 在参数返回值不足的情况下,给当前函数对象一个默认返回值即可
ad = function mingzi(a, b = 0) {
return a + b;
};
console.log(ad(1, 2));
function mingzi(a, b) {
return a + b;
}
console.log(mingzi(1, 2));
// 以上为非简体写法
ad = (a, b) => a + b;
console.log(ad(1, 2, 3, 4, 5));
// 1+2=3,所以只能显示2个
// 显示只显示前俩 后面的并没有显示
// 将多余的数字,可以以数组的方式全部接收
// ! ...: rest语法,剩余参数,归并参数,将所以参数全部压入到一个数组中
ad = (...c) => c;
console.log(ad(1, 2, 3, 4, 5, 6));
// 将所有的数字,压缩成数组,放到...c中
// 将集合数据展开
console.log(...[1, 2, 3, 4, 5]);
let ad1 = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(...ad1);
ad = (a, b, ...shuzu) => `${a},${b},${shuzu}`;
console.log(ad(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
let f = (...arr) => arr.reduce((a, c) => a + c);
console.log(f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
//没学高阶函数,那就先给老师的讲解进行还原
f = function (...arr) {
return arr.reduce(function (a, c) {
return a + c;
});
};
console.log(f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
// 从服务器API接口获取到了个商品列表: JSON数组
const list = ["笔记本电脑", "小米12手机", "佳能 EOS-R相机"];
console.log(list);
// 将每个商品,套上html标签,最终渲染到html页面中
f = (...items) => items.map(item => `<li>${item}</li>`).join("");
console.log(f(...list));
// document.body.innerHTML = "<ul>" + f(...list) + "</ul>";
qq = function (...items) {
return items
.map(function (item) {
return `<li>${item}</li>`;
})
.join("");
};
console.log(qq(...list));
// ! 返回值
// p 函数默认:'单值返回'
// y 如何返回多个值?
// 数组
qq = () => [1, 2, 3, 4, 5];
console.log(qq());
// 拆分处理
console.log(...qq());
// 结合for of循环提取键跟值
for (let tiqu of qq().entries()) {
console.log(tiqu);
}
for (let tiqu of qq().keys()) {
console.log(tiqu);
}
console.log(qq());
// 对象
qq = () => ({ name: "名字", Name: "名字2", nAme: "名字三" });
console.log(qq());
// 还原以上函数
//对象
let qq1 = function () {
return { name: "名字", Name: "名字2", nAme: "名字三" };
};
console.log(qq1());
// 结合for in循环提取
for (let tiqu in qq1()) {
console.log(qq1()[tiqu]);
}
对象字面量的简化
//对象字面量的简化 推荐使用部分
//先声明一个变量
let name = "小明";
let a = {
name: name,
};
console.log(a.name);
// 简化
a = {
name,
};
console.log(a.name);
// 不加this返回的是数组的值
a = () => name;
console.log(a());
// 方法简化 对象内有数组的情况
a = {
name,
ab: function () {
return a.name;
},
};
console.log(a.ab());
a = {
name,
ab: function () {
return this.name;
},
};
console.log(a.ab());
// 简写
a = {
name,
ab: () => a.name,
ac() {
return this.name;
},
};
console.log(a.ab());
console.log(a.ac());
模板字面量与模板函数
//模板字面量与模板函数
// 模板字面量
// 传统如下:
console.log("你好啊php");
// 模板字面量可以在传统的代码中插入插值
let php = "php";
console.log(php);
console.log("你好" + php);
console.log(`你好${php}`);
// 还可以进行计算使用
console.log(`1+1=${1 + 1}`);
//甚至可以放入块元素
console.log(`${10 > 1 ? `大于` : `小于`}`);
// 当函数声明使用函数模板时,函数声明内的第一个对象变为数组,后面的为值
// function name(string, y, q) {
// console.log(string);
// console.log(y, q);
// let jiage = ` ${string[0]} ${y} ${string[1]} ${q} ${string[2]} ${y * q}${string[3]} `;
// console.log(jiage)
// }
// let y = 10;
// let q = 20;
// name`当前的蔬菜价格单价为${y}数量为${q}总价格为 ${y * q}元`;
function name(string, y, q) {
console.log(string);
console.log(y, q);
let jiage = ` ${string[0]} ${y} ${string[1]} ${q} ${string[2]} ${y * q}${string[3]} `;
console.log(jiage);
}
let y = 10;
let q = 20;
// 使用函数模板时不需要加(),如下 name``;
name`当前的蔬菜价格单价为${y}数量为${20}总价格为 ${y * q}元`;
// name();
// name``;
// console.log(name(1, y, q));