词法作用域
一个变量到底代表什么意思,要根据上下文来推断
块作用是不存在变量提升着一说的
// let username = 'zs';// var age = 18;
//块作用域和词法作用域的区别varflag=falseif(true{console.log(username)letusername='zs'}
//console.log(username)
3、字符串扩展
(1)编码扩展
es5只能识别\u之后四位16进制数值,多余四位则识别为两个以上字符
es6通过\u{}可识别4位以上16进制数值的字符
//1 0000000 1 ascii gbk unicode utf-8
(2)startsWith endWith两个api可以判断字符串是否以某个字符开头或结尾
4、数组扩展
varstr=newArray(5).fill(0).map(()=>{return'li'}).join('')
var obj = { username: "zs", count: { math: 90, his: 80 } };
//'username' 'count.math'functionreturnAttr(obj,express){//以.为分隔符得到一个属性层级数组letexpressArr=express.split('.')returnexpressArr.reduce((obj,currentAtr)=>{returnobj[currentAtr]},obj)}console.log(returnAttr(obj,'count.tongji.current'))
5、Symbol
es5----->有几种数据类型
基5
引1
es6----->有几种数据类型
整数类型
Symbol:全应用唯一的值
Symbol和Symbol.for获取Symbol值得区别
letone=Symbol.for('aaa')
lettwo=Symbol.for('aaa')
one===two
6.Set
letfirst=newSet()
first.add(1)
first.add(2)
first.add(1)
//first.delete(2)
//first.clear()
//console.log(first.has(2))for(letvalueof first){console.log(value)}
//console.log(first.keys())
7、Map
//Map 图
let first=newMap([['name','zs'['age',18]])
//console.log(first) first.set('count',90)
first.set('count',85) first.delete('count')
// console.log(first.get('name'))
// console.log(first.has('name'))
// console.log(first)for(letvalueof first){console.log(value)}
8、defineProperty
用法
Object.defineProperty(obj,key,{....})
enumerable boolean 设置该属性是否可被遍历
value any 该属性被访问时的返回值
configurable boolean 该属性值是否可以被改写
writeable boolean 该属性值是否可以被改写
let obj = {
username: 'zs',
age: 18
}
Object.defineProperty(obj, 'username', {
enumerable: false,
configurable: false
})
Object.defineProperty(obj, 'username', { enumerable: true })
for (let key in obj) {
console.log(key)
}
属性代理
let obj = {
username: 'zs',
age: 18
}
//数据劫持configurable 属性代理
let str = "666"
Object.defineProperty(obj, 'uername', {
get() {
return str
},
set(newValue) {
console.log("设置值被触发了")
str = 'bw' + newValue
}
})
obj.username = "8888"
console.log(obj.username)
不成功的属性代理
letobj = {
username: 'zs',
age: 18,
count: {
math: 90
}
}
//封装一个函数 将obj对象的所有属性均进行属性代理
function myProxy(obj) {
letkeyArr = Object.keys(obj)
for (leti = 0; i < keyArr.length; i++) {
let tmp;
Object.defineProperty(obj, keyArr[i], {
get() {
returntmp;
}, set(newValue) {
tmp = newValue
}
})
}
}
myProxy(obj)
obj.age = 19
console.log(obj)
// 将一个不定层级的嵌套对象进行属性代理
let obj = {
username: 'zs',
age: 18,
}
math:901、块作用域
凡是左右花括弧包含的区域都是一个独立的作用域。该作用域里的变量只在该作用域内有效。
2、词法作用域
一个变量到底代表什么意思,要根据上下文来推断
块作用是不存在变量提升着一说的
// let username = 'zs';// var age = 18;//块作用域和词法作用域的区别varflag=falseif(true){console.log(username)letusername='zs'}//console.log(username)
3、字符串扩展
(1)编码扩展
es5只能识别\u之后四位16进制数值,多余四位则识别为两个以上字符
es6通过\u{}可识别4位以上16进制数值的字符
//1 0000000 1 ascii gbk unicode utf-8
(2)startsWith endWith两个api可以判断字符串是否以某个字符开头或结尾
4、数组扩展
var str=newArray(5).fill(0).map(()=>{return'li'}).join('')
var obj = { username: "zs", count: { math: 90, his: 80 } };
//'username' 'count.math'functionreturnAttr(obj,express){//以.为分隔符得到一个属性层级数组letexpressArr=express.split('.')returnexpressArr.reduce((obj,currentAtr)=>{returnobj[currentAtr]},obj)}console.log(returnAttr(obj,'count.tongji.current'))
5、Symbol
es5----->有几种数据类型
基5
引1
es6----->有几种数据类型
整数类型
Symbol:全应用唯一的值
Symbol和Symbol.for获取Symbol值得区别
letone=Symbol.for('aaa')
lettwo=Symbol.for('aaa')
one===two
6.Set
letfirst=newSet()
first.add(1)
first.add(2)
first.add(1)
//first.delete(2)
//first.clear()
//console.log(first.has(2))for(letvalueof first){console.log(value)}
//console.log(first.keys())
7、Map
//Map 图
letfirst=newMap([['name','zs'['age',18]])
//console.log(first)first.set('count',90)
first.set('count',85)first.delete('count')
// console.log(first.get('name'))
// console.log(first.has('name'))
// console.log(first)for(letvalueof first){console.log(value)}
8、defineProperty
用法
Object.defineProperty(obj,key,{....})
enumerable boolean 设置该属性是否可被遍历
value any 该属性被访问时的返回值
configurable boolean 该属性值是否可以被改写
writeable boolean 该属性值是否可以被改写
let obj={
username:'zs',
age:18
}
Object.defineProperty(obj,'username',{
enumerable:false,
configurable:false
})
Object.defineProperty(obj,'username',{enumerable:true})
for(letkeyinobj){
console.log(key)
}
属性代理
let obj={
username:'zs',
age:18}
//数据劫持configurable 属性代理
let str="666"
Object.defineProperty(obj,'uername',{
get(){
return str
},
set(newValue){
console.log("设置值被触发了")
str='bw'+newValue
}
})
obj.username="8888"
console.log(obj.username)
不成功的属性代理
letobj={
username:'zs',
age:18,
count:{
math:90
}}
//封装一个函数 将obj对象的所有属性均进行属性代理
functionmyProxy(obj){
letkeyArr=Object.keys(obj)
for(leti=0;i<keyArr.length;i++){
let tmp;
Object.defineProperty(obj,keyArr[i],{
get(){
returntmp;
},set(newValue){
tmp=newValue
}
})
}
}
myProxy(obj)
obj.age=19
console.log(obj)
将一个不定层级的嵌套对象进行属性代理
let obj={
username:'zs',
age:18,
count:{
math:90
}
}
//封装一个函数 将obj对象的所有属性均进行属性代理
function myProxy(obj){
let keyArr=Object.keys(obj)
for(let i=0;i<keyArr.length;i++){
proxyAttr(obj,keyArr[i],obj[keyArr[i]])
}
}
function proxyAttr(obj,key,value){
if(typeof value==='object'){
myProxy(value)
}
Object.defineProperty(obj,key,{
get(){
returnvalue;
},
set(newValue){
if(value===newValue){
return
}
value=newValue
}
})
}
myProxy(obj)
obj.age=19
console.log(obj)
proxy进行对象代理
let obj={username:'zs',age:18,count:{math:90}}
let newObj=new Proxy(obj,{
get(target,key){
console.log('你在获取值'+key)
returntarget[key]
},
set(target,key,value){target[key]=value}})
newObj.username='lisi',
console.log(newObj.count.math)
原型链
访问对象的某个属性,如果不存在,就逐层向上它的原型中查找,直到Object,次过程形成的链条就叫原型链。
将Object上的一些功能函数放到了Reflect对象上
Promise
逐行执行---->阻塞---->异步---->回调地域--->Promise
可以将回调地狱改善为then的链式调用
function ajax(fn){
setTimeout(() => {
fn(4576)
}, 2000)
}
// ajax((data)=>{// ajax((res)=>{// console.log(res)// })// })//fullfield 成功 pedding 等待 reject 错误
let first = new Promise((resolve, reject) => {
ajax((data) => {
resolve(data)
})
})
first.then((res) => {
console.log(res)
returnres + 1
}).then((ress) => {
console.log(ress)
ajax((data) => {
console.log(data)
})
})
//直接将ajax函数封装为promise
function ajax(options){
returnnewPromise((resolve, reject) => {
setTimeout(() => {
try {
resolve(100)
} catch (err) {
reject(404)
}
}, 2000)
})
}
ajax({
url: "",
methods: "GET"
}).then((res) => {
console.log(res)
return ajax({
url: "",
methods: "GET",
params: {
id: res
}
})
}).then((pro) => {
console.log(pro)
})
promise封装,一层then调用
const FULLFIELD = "fulfield";
const PENDDING = "pendding";
const REJECT = "reject";
class myPromise {
constructor(excute) {
this.value = undefined;
this.fail = undefined;
this.state = PENDDING;
this.successContainer = [];
this.failContainer = [];
excute(this.resolve.bind(this), this.reject.bind(this));
}
resolve(data) {
if (this.state === PENDDING) {
this.state = FULLFIELD;
this.successContainer.forEach((itemFn) => {
this.value = dataitemFn(data);
});
}
}
reject(err) {
if (this.state === PENDDING) {
this.state = REJECT;
this.failContainer.forEach((itemFn) => {
this.value = erritemFn(err);
});
}
}
then(success, fail) {
if (this.state === FULLFIELD) {
success(this.value);
} else if (this.state === REJECT) {
typeof fail === "function" && fail(this.fail);
} else {
this.successContainer.push(success);
typeof fail === "function" && this.failContainer.push(fail);
}
}
}
let first = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(100);
}, 2000);
});
generator函数的声明和使用
//generator
function*test(){
console.log('666')
yield1+100
yield2
return100
}
//generator函数调用拿到的是一个执行器
let first=test()
console.log(first.next())
console.log(first.next())
console.log(first.next())
console.log(first.next())
generator函数解决异步流程控制
let first;
function add(){
console.log('generator函数开启执行')
setTimeout(()=>{
first.next(300)
},2000)}
function login(verify){
setTimeout(()=>{
first.next('true'+verify)
},2000)}
//generator
function*test(){
let a=yieldadd() //验证码请求
console.log(a,'---')
let status=yield login(a)//登录请求
console.log(status)
return 100
}
//generator函数调用拿到的是一个执行器
first=test()
first.next()
歌词播放Low版
let arr = [
"[ti:等你归来]",
"[ar:程响]",
"[al:等你归来]",
"[by:dongmei_karakal]",
"[offset:0]",
"[00:00.00]等你归来 - 程响",
"[00:01.49]词:宁缺",
"[00:02.14]曲:宁缺",
"[00:02.78]编曲:曲比阿且",
"[00:04.06]宣发:刘芳",
"[00:04.92]混音:王朋",
"[00:05.77]母带:全相彦",
"[00:06.84]",
"[00:07.70]文案:冷小婧",
"[00:08.77]艺术效果:华玮轩",
"[00:10.27]出品人:潘鸿业",
"[00:11.55]OP:北京金翼龙国际文化传媒有限公司",
"[00:14.98]「未经著作权人书面许可 不得以任何方式(包括翻唱、翻录等)使用」",
"[00:21.00]我就在这里",
"[00:23.21]等你披星戴月乘着风而来",
"[00:29.26]",
"[00:30.39]我就在这里埋好烈酒候你故事开",
"[00:37.53]千千万万人海灯火阑珊",
"[00:42.54]你多少次不在",
"[00:46.17]走遍高高低低一路辗转",
"[00:50.90]朝暮青丝已白",
"[00:54.62]",
"[00:56.51]我在红尘等你 人间等你",
"[01:01.77]守繁华之外",
"[01:04.96]揽尽星辰入怀 千川归来",
"[01:10.14]化一片沧海",
"[01:13.39]我在九幽等你 极乐等你",
"[01:18.46]望彼岸花开",
"[01:21.68]长对三生浮白 不畏不改",
"[01:26.80]渡过去将来",
"[01:30.39]",
"[01:51.13]我就在这里",
"[01:53.01]等你跨山越海踏着云烟来",
"[01:59.33]",
"[02:00.56]我就在这里望尽天涯风雨也不改",
"[02:07.97]安安静静岁月时光荏苒",
"[02:12.47]你或许会徘徊",
"[02:15.93]挥别近近远远一身尘埃",
"[02:20.82]俯仰皆是无奈",
"[02:24.79]",
"[02:26.66]我在红尘等你 人间等你",
"[02:31.73]守繁华之外",
"[02:34.90]揽尽星辰入怀 千川归来",
"[02:40.13]化一片沧海",
"[02:43.46]我在九幽等你 极乐等你",
"[02:48.48]望彼岸花开",
"[02:51.64]长对三生浮白 不畏不改",
"[02:56.92]渡过去将来",
"[02:59.85]我在红尘等你 人间等你",
"[03:05.35]守繁华之外",
"[03:08.40]揽尽星辰入怀 千川归来",
"[03:13.65]化一片沧海",
"[03:16.94]我在九幽等你 极乐等你",
"[03:21.88]望彼岸花开",
"[03:25.10]长对三生浮白 不畏不改",
"[03:30.38]渡过去将来",
"[03:33.85]",
"[03:35.11]长对三生浮白 不畏不改",
"[03:40.94]渡过去将来",
]
var container=document.getElementById('container')
let i=0;
let timelang=1000;
let time=setInterval(()=>{
if(i>arr.length){clearInterval(time)}
var div=document.createElement('div')
div.innerHTML=arr[i]if(i!=1){
container.appendChild(div)
}
i++
},1000)
歌词播放generator
<!DOCTYPE html>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metahttp-equiv="X-UA-Compatible"content="IE=edge">
<metaname="viewport"content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,body,#container{
width:100%;
height:100%;
}
</style>
</head>
<body>
<divid="container"></div>
<script>
let arr = [
"[ti:等你归来]",
"[ar:程响]",
"[al:等你归来]",
"[by:dongmei_karakal]",
"[offset:0]",
"[00:00.00]等你归来 - 程响",
"[00:01.49]词:宁缺",
"[00:02.14]曲:宁缺",
"[00:02.78]编曲:曲比阿且",
"[00:04.06]宣发:刘芳",
"[00:04.92]混音:王朋",
"[00:05.77]母带:全相彦",
"[00:06.84]",
"[00:07.70]文案:冷小婧",
"[00:08.77]艺术效果:华玮轩",
"[00:10.27]出品人:潘鸿业",
"[00:11.55]OP:北京金翼龙国际文化传媒有限公司",
"[00:14.98]「未经著作权人书面许可 不得以任何方式(包括翻唱、翻录等)使用」",
"[00:21.00]我就在这里",
"[00:23.21]等你披星戴月乘着风而来",
"[00:29.26]",
"[00:30.39]我就在这里埋好烈酒候你故事开",
"[00:37.53]千千万万人海灯火阑珊",
"[00:42.54]你多少次不在",
"[00:46.17]走遍高高低低一路辗转",
"[00:50.90]朝暮青丝已白",
"[00:54.62]",
"[00:56.51]我在红尘等你 人间等你",
"[01:01.77]守繁华之外",
"[01:04.96]揽尽星辰入怀 千川归来",
"[01:10.14]化一片沧海",
"[01:13.39]我在九幽等你 极乐等你",
"[01:18.46]望彼岸花开",
"[01:21.68]长对三生浮白 不畏不改",
"[01:26.80]渡过去将来",
"[01:30.39]",
"[01:51.13]我就在这里",
"[01:53.01]等你跨山越海踏着云烟来",
"[01:59.33]",
"[02:00.56]我就在这里望尽天涯风雨也不改",
"[02:07.97]安安静静岁月时光荏苒",
"[02:12.47]你或许会徘徊",
"[02:15.93]挥别近近远远一身尘埃",
"[02:20.82]俯仰皆是无奈",
"[02:24.79]",
"[02:26.66]我在红尘等你 人间等你",
"[02:31.73]守繁华之外",
"[02:34.90]揽尽星辰入怀 千川归来",
"[02:40.13]化一片沧海",
"[02:43.46]我在九幽等你 极乐等你",
"[02:48.48]望彼岸花开",
"[02:51.64]长对三生浮白 不畏不改",
"[02:56.92]渡过去将来",
"[02:59.85]我在红尘等你 人间等你",
"[03:05.35]守繁华之外",
"[03:08.40]揽尽星辰入怀 千川归来",
"[03:13.65]化一片沧海",
"[03:16.94]我在九幽等你 极乐等你",
"[03:21.88]望彼岸花开",
"[03:25.10]长对三生浮白 不畏不改",
"[03:30.38]渡过去将来",
"[03:33.85]",
"[03:35.11]长对三生浮白 不畏不改",
"[03:40.94]渡过去将来",
]
var container = document.getElementById('container')
let playEr;
function playOne(str,time){
let timer = setTimeout(()=>{
let div = document.createElement('div')
div.innerHTML = str
container.appendChild(div)
clearTimeout(timer)
playEr.next()
},time)
}
function *playSong(arr){
for(let i = 0;i < arr.length;i++){
yield playOne(arr[i],Math.floor(Math.random()*5)*1000)
}
}
playEr = playSong(arr)
playEr.next();
</script>
</body>
</html>
迭代器 itorater
letobj={
username:'zs',
age:18,
[Symbol.iterator]:function*(arg){
letkeyArrs=Object.keys(obj)
for(leti=0;i<keyArrs.length;i++){
yieldkeyArrs[i]+":"+obj[keyArrs[i]]
}
}
}
for(let value of obj){
console.log(value)
}
}
}
//封装一个函数 将obj对象的所有属性均进行属性代理
function myProxy(obj){
let keyArr=Object.keys(obj)
for(let i=0;i<keyArr.length;i++){
proxyAttr(obj,keyArr[i],obj[keyArr[i]])
}
}
function proxyAttr(obj,key,value){
if(typeof value==='object'){
myProxy(value)
}
Object.defineProperty(obj,key,{
get(){
returnvalue;
},
set(newValue){
if(value===newValue){
return
}
value=newValue
}
})
}
myProxy(obj)
obj.age=19
console.log(obj)
proxy进行对象代理
let obj={username:'zs',age:18,count:{math:90}}
let newObj=new Proxy(obj,{
get(target,key){
console.log('你在获取值'+key)
returntarget[key]
},
set(target,key,value){target[key]=value}})
newObj.username='lisi',
console.log(newObj.count.math)
原型链
访问对象的某个属性,如果不存在,就逐层向上它的原型中查找,直到Object,次过程形成的链条就叫原型链。
将Object上的一些功能函数放到了Reflect对象上
Promise
逐行执行---->阻塞---->异步---->回调地域--->Promise
可以将回调地狱改善为then的链式调用
functionajax(fn){
setTimeout(()=>{
fn(4576)
},2000)}
// ajax((data)=>{// ajax((res)=>{// console.log(res)// })// })//fullfield 成功 pedding 等待 reject 错误
let first=new Promise((resolve,reject)=>{
ajax((data)=>{
resolve(data)
})})
first.then((res)=>{
console.log(res)
returnres+1}).then((ress)=>{
console.log(ress)
ajax((data)=>{console.log(data)
})
})
直接将ajax函数封装为promise
functionajax(options){
returnnewPromise((resolve,reject)=>{
setTimeout(()=>{
try{
resolve(100)
}catch(err){
reject(404)
}
},2000)
})
}
ajax({
url:"",
methods:"GET"
}).then((res)=>{
console.log(res)
return ajax({
url:"",
methods:"GET",
params:{
id:res
}
})
}).then((pro)=>{
console.log(pro)
})
promise封装,一层then调用
const FULLFIELD='fulfield'
const PENDDING='pendding'
const REJECT='reject'
class myPromise{
constructor(excute){
this.value=undefined;
this.fail=undefined;
this.state=PENDDING;
this.successContainer=[];
this.failContainer=[];
excute(this.resolve.bind(this),this.reject.bind(this))
}
resolve(data){
if(this.state===PENDDING){
this.state=FULLFIELD;
this.successContainer.forEach((itemFn)=>{
this.value=dataitemFn(data)})}}
reject(err){if(this.state===PENDDING){
this.state=REJECT;
this.failContainer.forEach((itemFn)=>{
this.value=erritemFn(err)}
)}
}
then(success,fail){
if(this.state===FULLFIELD){
success(this.value)
}else if(
this.state===REJECT){
typeof fail==='function'&&fail(this.fail)
}else{
this.successContainer.push(success);
typeof fail==='function'&&this.failContainer.push(fail)}
}
}
let first=new MyPromise((resolve,reject)=>{
setTimeout(()=>{resolve(100)},2000)})
generator函数的声明和使用
//generator
function*test(){
console.log('666')
yield1+100
yield2
return100
}
//generator函数调用拿到的是一个执行器
let first=test()
console.log(first.next())
console.log(first.next())
console.log(first.next())
console.log(first.next())
generator函数解决异步流程控制
let first;
functionadd(){
console.log('generator函数开启执行')
setTimeout(()=>{
first.next(300)
},2000)}
function login(verify){
setTimeout(()=>{
first.next('true'+verify)
},2000)}
//generator
function*test(){
let a=yieldadd() //验证码请求
console.log(a,'---')
let status=yield login(a)//登录请求
console.log(status)
return 100
}
//generator函数调用拿到的是一个执行器
first=test()
first.next()
歌词播放Low版
let arr = [
"[ti:等你归来]",
"[ar:程响]",
"[al:等你归来]",
"[by:dongmei_karakal]",
"[offset:0]",
"[00:00.00]等你归来 - 程响",
"[00:01.49]词:宁缺",
"[00:02.14]曲:宁缺",
"[00:02.78]编曲:曲比阿且",
"[00:04.06]宣发:刘芳",
"[00:04.92]混音:王朋",
"[00:05.77]母带:全相彦",
"[00:06.84]",
"[00:07.70]文案:冷小婧",
"[00:08.77]艺术效果:华玮轩",
"[00:10.27]出品人:潘鸿业",
"[00:11.55]OP:北京金翼龙国际文化传媒有限公司",
"[00:14.98]「未经著作权人书面许可 不得以任何方式(包括翻唱、翻录等)使用」",
"[00:21.00]我就在这里",
"[00:23.21]等你披星戴月乘着风而来",
"[00:29.26]",
"[00:30.39]我就在这里埋好烈酒候你故事开",
"[00:37.53]千千万万人海灯火阑珊",
"[00:42.54]你多少次不在",
"[00:46.17]走遍高高低低一路辗转",
"[00:50.90]朝暮青丝已白",
"[00:54.62]",
"[00:56.51]我在红尘等你 人间等你",
"[01:01.77]守繁华之外",
"[01:04.96]揽尽星辰入怀 千川归来",
"[01:10.14]化一片沧海",
"[01:13.39]我在九幽等你 极乐等你",
"[01:18.46]望彼岸花开",
"[01:21.68]长对三生浮白 不畏不改",
"[01:26.80]渡过去将来",
"[01:30.39]",
"[01:51.13]我就在这里",
"[01:53.01]等你跨山越海踏着云烟来",
"[01:59.33]",
"[02:00.56]我就在这里望尽天涯风雨也不改",
"[02:07.97]安安静静岁月时光荏苒",
"[02:12.47]你或许会徘徊",
"[02:15.93]挥别近近远远一身尘埃",
"[02:20.82]俯仰皆是无奈",
"[02:24.79]",
"[02:26.66]我在红尘等你 人间等你",
"[02:31.73]守繁华之外",
"[02:34.90]揽尽星辰入怀 千川归来",
"[02:40.13]化一片沧海",
"[02:43.46]我在九幽等你 极乐等你",
"[02:48.48]望彼岸花开",
"[02:51.64]长对三生浮白 不畏不改",
"[02:56.92]渡过去将来",
"[02:59.85]我在红尘等你 人间等你",
"[03:05.35]守繁华之外",
"[03:08.40]揽尽星辰入怀 千川归来",
"[03:13.65]化一片沧海",
"[03:16.94]我在九幽等你 极乐等你",
"[03:21.88]望彼岸花开",
"[03:25.10]长对三生浮白 不畏不改",
"[03:30.38]渡过去将来",
"[03:33.85]",
"[03:35.11]长对三生浮白 不畏不改",
"[03:40.94]渡过去将来",
]
var container=document.getElementById('container')
let i=0;
let timelang=1000;
let time=setInterval(()=>{
if(i>arr.length){clearInterval(time)}
var div=document.createElement('div')
div.innerHTML=arr[i]if(i!=1){
container.appendChild(div)
}
i++
},1000)
歌词播放generator
<!DOCTYPE html>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metahttp-equiv="X-UA-Compatible"content="IE=edge">
<metaname="viewport"content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,body,#container{
width:100%;
height:100%;
}
</style>
</head>
<body>
<divid="container"></div>
<script>
let arr = [
"[ti:等你归来]",
"[ar:程响]",
"[al:等你归来]",
"[by:dongmei_karakal]",
"[offset:0]",
"[00:00.00]等你归来 - 程响",
"[00:01.49]词:宁缺",
"[00:02.14]曲:宁缺",
"[00:02.78]编曲:曲比阿且",
"[00:04.06]宣发:刘芳",
"[00:04.92]混音:王朋",
"[00:05.77]母带:全相彦",
"[00:06.84]",
"[00:07.70]文案:冷小婧",
"[00:08.77]艺术效果:华玮轩",
"[00:10.27]出品人:潘鸿业",
"[00:11.55]OP:北京金翼龙国际文化传媒有限公司",
"[00:14.98]「未经著作权人书面许可 不得以任何方式(包括翻唱、翻录等)使用」",
"[00:21.00]我就在这里",
"[00:23.21]等你披星戴月乘着风而来",
"[00:29.26]",
"[00:30.39]我就在这里埋好烈酒候你故事开",
"[00:37.53]千千万万人海灯火阑珊",
"[00:42.54]你多少次不在",
"[00:46.17]走遍高高低低一路辗转",
"[00:50.90]朝暮青丝已白",
"[00:54.62]",
"[00:56.51]我在红尘等你 人间等你",
"[01:01.77]守繁华之外",
"[01:04.96]揽尽星辰入怀 千川归来",
"[01:10.14]化一片沧海",
"[01:13.39]我在九幽等你 极乐等你",
"[01:18.46]望彼岸花开",
"[01:21.68]长对三生浮白 不畏不改",
"[01:26.80]渡过去将来",
"[01:30.39]",
"[01:51.13]我就在这里",
"[01:53.01]等你跨山越海踏着云烟来",
"[01:59.33]",
"[02:00.56]我就在这里望尽天涯风雨也不改",
"[02:07.97]安安静静岁月时光荏苒",
"[02:12.47]你或许会徘徊",
"[02:15.93]挥别近近远远一身尘埃",
"[02:20.82]俯仰皆是无奈",
"[02:24.79]",
"[02:26.66]我在红尘等你 人间等你",
"[02:31.73]守繁华之外",
"[02:34.90]揽尽星辰入怀 千川归来",
"[02:40.13]化一片沧海",
"[02:43.46]我在九幽等你 极乐等你",
"[02:48.48]望彼岸花开",
"[02:51.64]长对三生浮白 不畏不改",
"[02:56.92]渡过去将来",
"[02:59.85]我在红尘等你 人间等你",
"[03:05.35]守繁华之外",
"[03:08.40]揽尽星辰入怀 千川归来",
"[03:13.65]化一片沧海",
"[03:16.94]我在九幽等你 极乐等你",
"[03:21.88]望彼岸花开",
"[03:25.10]长对三生浮白 不畏不改",
"[03:30.38]渡过去将来",
"[03:33.85]",
"[03:35.11]长对三生浮白 不畏不改",
"[03:40.94]渡过去将来",
]
var container = document.getElementById('container')
let playEr;
function playOne(str,time){
let timer = setTimeout(()=>{
let div = document.createElement('div')
div.innerHTML = str
container.appendChild(div)
clearTimeout(timer)
playEr.next()
},time)
}
function *playSong(arr){
for(let i = 0;i < arr.length;i++){
yield playOne(arr[i],Math.floor(Math.random()*5)*1000)
}
}
playEr = playSong(arr)
playEr.next();
</script>
</body>
</html>
迭代器 itorater
letobj={
username:'zs',
age:18,
[Symbol.iterator]:function*(arg){
let keyArrs=Object.keys(obj)
for(let i=0;i<keyArrs.length;i++){
yield keyArrs[i]+":"+obj[keyArrs[i]]
}
}
}
for(let value of obj){
console.log(value)
}