目录
let 与 const
const
解构赋值
用在数组上
用在对象上
模板字符串
新增检测相关字符串方法
填充与去空白,遍历for..of
新增数组方法
find的用法
findIndex的用法
forEach的用法
fill的用法
map的用法
some的用法
every的用法
reduce的用法
includes的用法
filter的用法
箭头函数
对象新增方法
module模块
类
新增数据类型
set不重复的数组
map任意键的对象
迭代对象
Promise承诺
promise解决回调过深问题
同步和异步
jsonp获取天气
使用promise加载一张照片
promise同时加载多张图片
async与await修饰符
generator生成器
Object.defineProperty
proxy代理对象
ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准
let 与 const
- let:ES6新增,用于声明变量,有 块级作用域
- var:ES5中用于声明变量的关键字, 存在各种问题(例如:红杏出墙~)
- var存在的问题:
- var声明的变量for循环在单击时候已经执行完毕,执行完与 的值就是5
let声明局部作用域(for 循环的局部作用域是相互不影响的)
const PI = "3.1415926";
// 1.声明提升
// 此处会正常打印,但这是错误的(属于先上车后买票了!)
console.log(name);
var name = "大帅比";
// 2. 变量覆盖
var demo = "小明";
var demo = "小红";
// 此处会打印小红,这也是错误的(属于套牌车,违法的啊,兄弟)
// 同一个项目中,发生变量覆盖可能会导致数据丢失以及各种不可预知的bug,原则上来说:变量不能重名
console.log(demo)
// 3. 没有块级作用域
function fn2(){
for(var i = 0; i < 5; i++){
// do something
}
// 此处会正常打印出 i 的值,这是错误的
// i是定义在循环体之内的,只能在循环体内打印,当前现象叫做红杏出墙!!!
console.log(i);
}
fn2();
- let不会存在上述问题:
- let不会变量提升(在javascript引/擎执行代码前,先把所有变量和函数提升到最前面,变量统-赋值为undefined )
// 1. 不会存在声明提前
// 此处会报错(这里必须报错,原则上来说不能先上车后买票)
console.log(name);
let name = "大帅比";
// 2. 不会有变量覆盖
let demo = "小明";
let demo = "小红";
// 此处会报错(不能使用套牌车!)告诉你已经定义了此变量。避免了项目中存在变量覆盖的问题
console.log(demo)
// 3. 有块级作用域
function fn2(){
for(let i = 0; i < 5; i++){
// do something
}
// 此处会报错,无法打印,防止红杏出墙!!!
// i是定义在循环体之内的,循环体外当然无法打印
console.log(i);
}
fn2();
const
- const 声明一个只读的常量,一旦声明,常量的值就不能改变
- 一般用于全局变量
- 通常变量名全部大写(请按照规则来,不要乱搞,容易出事情)
<script>
// 01 和let基本一致(局部 不会变量提升,不能重复声明)
// 02 声明必须赋值
// Uncaught 没有捕捉到 SyntaxError 语法错误
// const PI;
const PI = 3.1415926;
console.log(PI);
// 03 声明的数据不能修改(值类型)
const PERSON = {
name: "mumu",
age: 18
}; //引用类型常量
PERSON.age = 24;
//引用类型只要不是重新赋值,都是引用同一块内存地址
// PERSON = {}
console.log(PERSON);
// 04 建议变量名大写
</script>
解构赋值
- 解构赋值是对赋值运算符的扩展
- 针对数组或者对象进行模式匹配,然后对其中的变量进行赋值
用在数组上
let [a, b, c] = [1, 2, 3];
// a = 1,b = 2,c = 3 相当于重新定义了变量a,b,c,取值也更加方便
// , = 占位符
let arr = ["小明", "小花", "小鱼", "小猪"];
let [,,one] = arr; // 这里会取到小鱼
// 解构整个数组
let strArr = [...arr];
// 得到整个数组
console.log(strArr);
<script>
// 01 把数组解析单个的变量
// 02 可以逗号跳过某个元素
let arr = [1, 3, 5, 7, 9, 11, 12, 13];
let [a, b, ...c] = arr;
console.log(a); //1
console.log(b); //3
console.log(c); //array(6)
// 03 可以给默认值
// 通过...接收剩余内容(不定参)
let arr2 = [1, 2, 3, 4];
let [d, e, f, g = 88] = arr2;
console.log(d, e, f, g);
//04 可以交换变量
var k = 100;
var j = 50;
[k, j] = [j, k];
console.log(k, j);
</script>
用在对象上
let obj = {
className : "卡西诺",
age: 18
}
let {className} = obj; // 得到卡西诺
let {age} = obj; // 得到18
// 剩余运算符
let {a, b, ...demo} = {a: 1, b: 2, c: 3, d: 4};
// a = 1
// b = 2
// demo = {c: 3, d: 4}
<body>
<h1>解构对象</h1>
<p>对象解构就是把对象解析为单独的变量</p>
<p>不用按顺序解构</p>
</body>
<script>
let obj = { name: "mumu", age: 18, job: "tea" }
let { name, age } = obj;
console.log(name); //mumu
console.log(age); //18
</script>
模板字符串
- 模板字符串相当于 加强版的字符串 ,用反引号 ``
- 除了作为普通字符串,还可以用来定义多行字符串,可以在字符串中加入变量和表达式
let str1 = "穿堂而过的";
let str2 = "风";
// 模板字符串
let newStr = `我是${str1}${str2}`;
// 我是穿堂而过的风
console.log(newStr)
// 字符串中调用方法
function fn3(){
return "帅的不行!";
}
let string2= `我真是${fn3 ()}`;
console.log(string2); // 我真是帅的不行!
新增检测相关字符串方法
<body>
<h1>String字符串</h1>
<p>检测: includes是否包含...,startsWith以...开头endsWith以...结尾</p>
<p>includes检测是否包含字符串,包含返回true,不包含返回false</p>
</body>
<script>
var str = "我爱我的祖国,我的祖国,是中国的国"
// alert(str.includes("他乡"));
// alert(str.startsWith("我恨"));
alert(str.endsWith("国"))
</script>
填充与去空白,遍历for..of
<p>padStart填充在前面, padEnd填充后面 </p>
<p>trim移除两端空白,trimLeft ,trimRight移除左右空白</p>
<p>表单交互先移除空白</p>
<p>遍历的新方式 for of</p>
</body>
<script>
var str = "1";
//补齐3位数,不够用0来填充
console.log(str.padStart(3, "0"));
console.log(str.padEnd(3, "0"));
//时间 01 22
var mystr = " 你好,东三街怎么走 "
console.log(mystr);
console.log(mystr.trim());
//特别生僻字是占两个字节
var str = "田里的水太多了,你去𠮷口,把水放出来"
// for (var i = 0; i < str.length; i++) { //不能识别生僻字
// console.log(str[i]);
// }
for (let s of str) { //可以识别生僻字
console.log(s);
}
</script>
新增数组方法
find的用法
//find的用法:查找数组中第一个满足要求的项(多个满足也只会返回第一个)
let arr = [1,2,3];
let temp = arr.find(item => item > 2);
console.log(temp);//3
let temp1 = arr.find(item => item > 1);
console.log(temp1);//2
findIndex的用法
//findIndex的用法:查找数组中第一个满足要求的项的当前索引
let arr = [1,4,9];
let index = arr.findIndex(item => item === 4);
console.log(index);//1
forEach的用法
//forEach的用法
let arr = [1,2,3];
arr.forEach((item,key,arrData) => {//item:数组的每一项,key:当前的索引,arrData:数据源
console.log(item);//1,2,3
console.log(key);//0,1,2
});
fill的用法
//声明指定数组长度,并填充对应数据
const arr = new Array(3).fill("Agwenbi");
console.log(arr);//["Agwenbi","Agwenbi","Agwenbi"]
map的用法
//map的用法:类似于forEach
let arr = [1,2,3];
let newArr = arr.map((item,key,arrData) => {//与forEach的一致
return item ** 2;
});
console.log(newArr);//[1,4,9];
some的用法
//some的用法:类似于逻辑或,判断数据的每一项是否有满足条件的,如果有就返回true,如果都不满足才返回false
let arr = [1,4,9];
let flag = arr.some(item => item >= 5);
console.log(flag);//true
let flag1 = arr.some(item => item >= 10);
console.log(flag1);//false
every的用法
//every的用法:判断数组中的每一项是否都满足条件,如果都满足则返回true,只要有一项不满足则返回flase,有点类似于逻辑与&&
let arr = [1,4,9];
let flag = arr.every(item => item >= 0);
console.log(flag);
let flag1 = arr.every(item => item > 1);
console.log(flag1);
reduce的用法
//reduce的用法:第一次循环时,perv为数组第一项,next为数组第二项
let arr = [1,4,9];
let newArr = arr.reduce((prev,next) => {
return prev + next;//作为下一次的prev的值
});
//第一次循环时 prev:1 next:4
//第二次循环时 prev:5 next:9
//循环结束
console.log(newArr);//14
let newArr1 = arr.reduce((prev,next) => {
return prev + next;
},10);//循环结束时再加上第二个参数10,最终结果为24
console.log(newArr1);
includes的用法
//includes的用法:查找数组是否包含某一个项
let arr = [1,4,9];
console.log(arr.includes(1));//true
console.log(arr.includes(5));//false
filter的用法
//filter的用法:根据条件过滤数组项,返回过滤后的新数组
let arr = [1,4,9];
let newArr = arr.filter(item => item >= 3);//过滤大于等于3的数据
console.log(newArr);//[4,9]
箭头函数
<script>
//01 箭头函数:函数的简写
var fun = function () {
alert("love");
}
var fun1 = () => alert("love");
//=> 左侧是参数
// => 右侧是执行语句
fun();
fun1();
//02 如果参数不是一个需要加()
var fun = (name, age) => alert("大家好我的名字是" + name + "今年" + age)
fun("木木", 19);
//03 如果有多行语句需要用{},返回用return
var fun3 = age => {
if (age > 18) {
alert("可以参军")
} else {
alert("下屁孩")
}
}
fun3(19)
//04 如果需要返回对象用({})
var fun4 = (name, age) => ({ name: name, age: age, msg: "大家好,我是" + name })
var obj = fun4("小雪", 17);
console.log(obj);
</script>
<script>
//不能作为构造函数
// var age = 50;
// var obj = {
// age:18,
// grow:(){
// setInterval(()=>{
// this.age++;
// console.log(this.age);
// },3000)
// }
// }
// obj.grow();
var arr = [2, 4, 6, 7, 8];
//过滤出大于5的数
var arr1 = arr.filter(item => item > 5)
console.log(arr1)
var total = arr.reduce((a, b) => a + b)
console.log(total);
var arr2 = arr.map(item => item * 2)
console.log(arr2);
</script>
对象新增方法
<h1>对象新增</h1>
<p>Object.create()通过现有方法创建一个新的对象</p>
<p>新对象的原型上源对象的方法和属性</p>
<p>Object.key()获取对象所有键的集合成为一个数组</p>
<p>Object.values()获取值得集合</p>
<p>Object.assign()合并对象</p>
</body>
<script>
var obj1 = { name: "mumu", age: 18, leg: 12 };
var obj2 = { age: 17, job: "teacher" };
//合并复制对象
var obj3 = Object.assign(obj1, obj2);
console.log(obj3);
var vals = Object.values(obj3);
console.log(vals);
var keys = Object.keys(obj3);
console.log(keys);
var obj4 = Object.create(obj3)//继承
</script>
module模块
导入
<script type="module">
导入默认
import format from './相对路径'
// format可以和导出的时候不一致
导入
import {reverse} from './相对路径'
// reverse要和源文件方法一致
导入别名
impot {reverse as r} rom ’./相对路径‘
默认和普通方法是一个文件
import format ,{reverse as r,PRICE,name,say} from ’./相对路径‘
导入所有
import * as utitls from ’文件地址‘
utils.reverse()
默认导出方法访问
utils.default()
导出
导出默认
function format(date){}
export defaut format
export default function format(date){}
导出
export function reverse(){}
导出变量
export const PRICE = 500;
先声明再导出
var name = “mumu”;
function say(){
console.log("我的价格是"+PRICE)
}
export {name,say}
<body>
<h1>Es6模块</h1>
<p>灵活导入外部代码</p>
</body>
<script type="module">
// import format from './js/index.js';
// console.log(format(new Date()));
//名称reverse必须和index.js方法名保持一致
// as是起一个别名的意思
import format, { reverse as r, PRICE, name, say } from './js/index.js'
// console.log(r("甜蜜蜜"));
// console.log(PRICE);
// say()
// console.log(name);
//把index文件中所有东西导入别名是utils
import * as utils from './js/index.js';
utils.say();
console.log(utils.reverse("我喜欢你"));
console.log(utils.default(new Date()));
// export 导出 default 默认
// module 模块 import 导入 from从 as 别名
类
typeof class
结果是 Function
类的本质是函数class Block{
}
构造函数
constructor(){}
实例化的时候 new关键字调用的就是构造函数super()
调用父类的构造函数extends 继承父类的方法
static 类的静态属性和方法
类的this指向的是它的实例(也就是new出来的对象)
<script type="module">
import student from './js/student.js'
var s1 = new student("小红", 22, "javascript")
var s2 = new student("小张", 26, "前端")
console.log(s1, s2);
//使用继承的方法
s1.say();
//使用自身的方法
s2.study();
</script>
js代码
export default class person {
constructor(name, age) {
= name;
this.age = age;
}
say() {
console.log("我是" + + "今年" + this.age + "岁,一顿要吃" + this.age + "个馍");
}
}
//类的最基本格式
// 类就是创建对象实例的模板
// constructor 构造函数
// this指向是其创建出来实例
// 导入person
import person from './person.js'
export default class student extends person {
constructor(name, age, major) {
super(name, age); //调用父构造函数
this.major = major;
}
study() {
console.log( + "正在努力地学习" + this.major);
}
}
新增数据类型
set不重复的数组
<script>
var s1 = new Set([1, 2, 2, 1, 2, 1, 2, 1, 3])
console.log(s1); //1,2,3
// set常用来去重
var arr = [1, 2, 1, 2, 1, 2, 1, 2, 3, 3, 5];
var arr1 = [...new Set(arr)];
console.log(arr1); // 1,2,3,5
var s1 = new Set([1, 2, 5, 1, 5, 9, 8])
// add添加delete 删除clear清空has检测size大小
console.log(s1.size); // 5
s1.add(88);
s1.delete(5);
console.log(s1); //1,2,9,8,88
</script>
map任意键的对象
<script>
//map 图键名可以是任意类型
var m = new Map([["name", "mumu"], ["age", 18], [{ eye: 2 }, "好眼睛"]]);
console.log(m);
// set(key,value)设置 get(key)获取 size大小 delete删除 clear清空
console.log(m.get("name"));
m.set(null, "没有");
console.log(m);
m.delete("age");
console.log(m);
</script>
weakSet
值都是引用类型的setweakMap
键都是引用类型symbol唯一符合
(对象的键)
迭代对象
//迭代对象,可以用for of 遍历对象是迭代对象
// String 字符串 Array数组 Set集合 Map 图
// keys键结果 values值得集合 entries键与值得集合
var s1 = new Set([1, 5, 7, "name", "mumu"])
for (var v of s1) {
console.log(v);
}
for (var key of s1.keys()) {
console.log(key);
}
for (var key of s1.values()) {
console.log(key);
}
var arr = ["red", "blue", "yellow"]
for (var key of arr.keys()) {
console.log(key);
}
for (var [k, v] of arr.entries()) {
console.log(k, v);
}
Promise承诺
var p = new Promise((resolve, reject) => {
var n = Math.random();
setTimeout(() => {
if (n > 0.5) { resolve("买个大house 前面是游泳池,后面是花园") }
else { reject("游泳池去大众澡堂") }
}, 2000)
})
console.log(p);
// 承诺有3个状态 pending准备 rejected拒绝 resolved兑现
// 状态发生变化就不能更改
//.then回调函数拿到的是resolved兑现状态的结果
//.catch回调函数拿到的是rejected拒绝的理由
p.then(res => {
console.log(res);
})
.catch(err => console.log(err))
promise解决回调过深问题
function say(msg, delay) {
// 返回一个promise的实例
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(msg);
}, delay)
})
}
say("你笑起来真好看", 2000)
.then(res => {
console.log(res);
return say("我能加你个微信吗?", 3000)
})
.then(res => {
console.log(res);
return say("能做你男朋友吗,备胎2号,3号也行", 5000)
})
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err)
})
同步和异步
同步是按顺序从上至下阻塞式执行代码(上一行代码不执行完毕,下行是不会执行)
异步是先执行主线程的代码,再执行其他线程(非阻塞式)
//实现异步:1.回调函数2.事件响应3.promise承诺4.订阅和发布模式
function say(str, delay, callback) {
setTimeout(() => {
console.log(str);
if (callback) { callback() }
}, delay)
}
say("你笑起来真好看", 2000, () => { //2s后执行
say("欧能加你个微信吗?", 3000, () => { //3s后执行
say("我讷讷个男朋友", 5000) //5s后执行
})
})
jsonp获取天气
<body>
<div class="a1"></div>
<div class="a2"></div>
</body>
<script>
// 什么事浏览器同源策略(当前文件请求服务器时候要求,请求地址与当前文件同源)
// 同源:域名,子域名,端口号,协议一致
// 跨域:绕过浏览器的同源策略跨域名获取数据
// jsonp 利用script src没有同源策略限制返回方法执行加数据
// 提前定义这个方法就可以
// 拼接url,定义方法的名称,动态创建script 异步
function jsonp(url) {
return new Promise((resolve, reject) => {
// 定义函数的名称
var funname = "jp" + Date.now();
// 定义script的src
var src = url + "&callback=" + funname;
// 创建一个script
var script = document.createElement("script");
// 指定src
script.src = src;
// 插入body
document.body.appendChild(script);
// 定义函数
window[funname] = function (data) {
// 把动态创建的script标签移除
document.body.removeChild(script);
resolve(data);
}
// 错误拒绝
script.onerror = function (err) {
// 把动态创建的script标签移除
document.body.removeChild(script);
reject(err)
}
})
}
var odiv = document.querySelector(".a1")
var odiv1 = document.querySelector(".a2")
jsonp("https://r.inews.qq.com/api/ip2city?otype=jsonp")
.then(res => {
// 先通过ip获取地址
console.log(res.city);
odiv.innerHTML = `${res.city} `
// 返回新的promise获取天气
return jsonp(`https://wis.qq.com/weather/common?weather_type=observe|forecast_24h|air&source=pc&province=${res.province}&city=${res.city}`)
})
.then(res => {
console.log("天气", res);
odiv1.innerHTML = ` 天气: ${res.data.observe.weather} <img src='https://mat1.gtimg.com/pingjs/ext2020/qqindex2018/dist/img/weather/${res.data.observe.weather_code}.svg' width='20'> 空气质量:${res.data.air.aqi_name} 温度:${res.data.observe.degree}℃ `
})
.catch(err => console.error(err))
使用promise加载一张照片
//02 在promise创建一个img标签
//03 img onload加载resolve img
//04 img onerror出错reject
function downImg(url) {
//返回promise
return new Promise((resolve, reject) => {
//创建图片
var img = document.createElement("img");
//指定src
img.src = url;
//加载成功返回图片
img.onload = function () {
resolve(img);
}
//加载失败返回错误原因
img.onerror = function (err) {
reject(err)
}
})
}
downImg("https://img0.baidu.com/it/u=922902802,2128943538&fm=253&fmt=auto&app=120&f=JPEG?w=1422&h=800")
.then(res => {
document.body.appendChild(res);
})
.catch(err => {
console.error(err);
})
实例P
//实例p
.then(res=>{})
//回调函数获取resolved返回的结果
//返回一个新的promise实例
.catch(err=>{})
//获取rejected的原因
promise同时加载多张图片
<h1>下载图片</h1>
<script>
// 01 定义一个函数,返回一个promise
// 02 在promise创建一个img标签
// 03 img onload加载 resolve img
// 04 img onerror出错 reject
function downImg(url) {
// 返回promise
return new Promise((resolve, reject) => {
// 创建图片
var img = document.createElement("img");
// 指定src
img.src = url;
// 加载成功返回图片
img.onload = function () {
resolve(img);
}
// 加载失败返回错误原因
img.onerror = function (err) {
reject(err)
}
})
}
// 同时下载3张,3张图片都下载完毕同时显示
var urls = [
"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/32a62196b9af47752c96e7a50c86417c.jpg?w=632&h=340",
"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/264af0123292658e3cde80ce12599121.jpg?w=632&h=340",
"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/28c13d0d11b38ec17fa5d83bc6ba5912.jpg?w=632&h=340"
]
// race 赛跑(返回最先resolve结果)拿到最到的resolve结果(第一张图)
// Promise.race(urls.map(item => downImg(item)))
// .then(res => {
// document.body.appendChild(res);
// })
// .catch(err => {
// console.error(err);
// })
// promise.all 参数中所有的promise,resolve才会reslove
Promise.all(urls.map(item => downImg(item)))
.then(res => {
console.log(res);
for (var k of res) {
document.body.appendChild(k);
}
})
.catch(err => {
console.error(err);
})
async与await修饰符
//async修饰的函数,函数执行返回的是一个promise对象
//通常配合await等待关键字,await只能出现在async装饰的函数里面
// await 用来等待异步的resolve结果 只能出现在async装饰的函数中
//await会等待promise的resolve的结果
function say(msg, delay) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(msg), delay);
})
}
async function doit() {
var m1 = await say("你好,我能加你个微信吗?", 4000);
console.log(m1);
var m2 = await say("走,吃个串串", 3000);
console.log(m2);
return "国企快乐"
}
doit()
.then(res => console.log(res))
// doit()
// .then(res=>{})
// .catch(err=>{})
generator生成器
generator
生成器
就是在函数前面添加个 *
function *range(min,max){
for(var i=min,i<max;i++){
yield i;
}
}
生成器执行的结果是 一个迭代器
var iter = range(1,10)
迭代器通过next方法返回一个对象,对象的value是 yield生成的结果 在生成器里面 遇到yield就停止等待下一次next调用
{value:1,done:false}
....
{value:undefined,done:true}
可以通过for 来遍历迭代器
for(v of range(1,100)){
console.log(v)
}
String,Array,Set,Map的迭代器
arr[Symbol.iterator]()
Object.defineProperty
Object.defineProperty(obj,props,{
set(v){ //设置},
get(){//获取},
})
可以定义对象的某个属性
eg.
// vue2响应式原理,object. defineProperty结合订阅与发布模式,通过观察者连接视图与数据
// object. defineProperty劫持对象的getter 与setter
// object对象define订阅Property属性throw抛出
var obj = { _age: 18 };
Object.defineProperty(obj, "age", {
//当获取age的值得时候执行get方法
get() {
return this._age;
},
//当设置age值得时候执行set方法
set(v) {
if (v > 200 || v < 1 || isNaN(v)) {
throw "年龄设置错误"
} else {
this._age = v;
}
}
})
proxy代理对象
target目标对象
handle 处理器
set(target,property,value){
//拦截set
}
get(target,property){
// 拦截set
return target[property]
}
var proxy = new Proxy(target,handel)
eg.
//要被劫持的对象
var obj = {
price: 100,
}
//处理器
var handle = {
//堆obj对象进行get 或者set的劫持
get(target, propery) {
console.log(new Date().toLocaleString(), "康康又在看他两位数的钱包了");
return target[propery]
},
set(target, propery, value) {
target[propery] = value;
console.log("康的钱包变成" + value
)
}
}
//生成代理对象proxy
var proxy = new Proxy(obj, handle)
//price 价格 handle 处理 get 获取 target 目标 property属性 Locale本地 proxy代理