let和const声明变量
| 1.let变量声明 不存在变量提升问题 |
| 特点: |
| 1.是一个块级的作用域 类似在类中的实例变量一样,只能在声明内部使用,外部不能使用 |
| 2.不允许在相同作用域内,重复声明同一个变量 |
| 1-1.变量提升测试 |
| console.log(b); |
| let b = 100 |
| console.log(b) |
| |
| 1-2.变量名重复 |
| let a = 40 |
| var a = 5000 |
| console.log(a) |
| |
| 1-3. 变量可以被覆盖 |
| let a = 10 ; |
| a = 100 |
| a = 1000 |
| console.log(a); |
| |
| |
| 2.const变量声明 |
| 声明一个只读的常量。一旦声明,常量的值就不能改变 |
| const一旦声明变量,就必须立即初始化,不能留到以后赋值 |
| const foo; |
| 特点: |
| 1.声明后不能修改,块级的作用域 |
| 2.变量不能重复,不能被覆盖 |
| |
| console.log(a); |
| const a = 100 |
| |
| 2-1.变量声明后就无法在重新赋值 |
| const a = 100 |
| a = 1000 |
| 虽然无法直接修改a变量,但是如果a变量是个对象的情况下是可以对内部的值进行修改的 |
| const p = { |
| name : '123', |
| age : 456, |
| } |
| p.name = '1xx222' |
| |
| 3.var变量声明 |
| 特点: |
| 1.在启动时,将全部的var声明的变量提升到全局作用域中 |
| 2.声明变量是可以被覆盖,可以重复的 |
| |
| var a; |
| console.log(a); |
| var a = 1000 |
变量提升
| 使用var |
| arr = []; |
| for (var i = 0; i < 10; i++) { |
| arr[i] = function () { |
| return i |
| } |
| } |
| console.log(arr); |
| console.log(arr[5]()); |
| |
| |
| 使用let 因为let不会存在变量提升的问题,不会污染全局 |
| |
| arr = []; |
| for (let i = 0; i < 10; i++) { |
| arr[i] = function () { |
| return i |
| } |
| } |
| console.log(arr); |
| console.log(arr[5]()); |
| |
模板字符串
| |
| <div class="box"> |
| |
| </div> |
| |
| |
| <script> |
| |
| const obox = document.querySelector('.box') |
| |
| let id = 1, name = 'xxx'; |
| |
| |
| |
| let htmlstr = ` |
| <ul> |
| <li> |
| <p id="${id}">${name}</p> |
| </li> |
| </ul> |
| ` |
| obox.innerHTML = htmlstr |
| </script> |
剩余运算符与扩展运算符
| 1.函数的默认参数 |
| function bba(a = 10, b = 20) { |
| return a + b |
| } |
| console.log(bba(100, 300)); |
| |
| |
| function add(a,b=date(5)){ |
| return a+b |
| } |
| function date(val){ |
| return 5 + val |
| } |
| |
| 2.剩余运算符 |
| |
| |
| |
| function pick(object, ...key) { |
| console.log(key) |
| |
| let res = Object.create(null) |
| for (let i = 0; i < key.length; i++) { |
| res[key[i]] = object[key[i]] |
| } |
| return res |
| } |
| |
| let book = { |
| title: '1231', |
| author: "65465", |
| year: 2019, |
| } |
| |
| let bookdata = pick(book, 'title', 'author', "year") |
| console.log(bookdata) |
| |
| |
| 3.扩展运算符 |
| 扩展运算符:将数组进行分割,将改革想作为分离的参数进行传入函数中 |
| const arr = [11,22,33,44,566,778979,9879] |
| console.log(Math.max(...arr)) |
| |
箭头函数
| es6的箭头函数 => 来定义 取代function(){} 等价于 ()=>{} 匿名函数 |
| |
| add = function(a,b){ |
| return a + b |
| } |
| |
| add = (a,b)=>{ |
| return a + b |
| } |
| |
| add = (a,b) => a+b |
| |
| 1.无参数 必须有()存在 |
| ()=>{ |
| return '123456' |
| } |
| |
| 2.单个参数 |
| val => { return val+5 |
| } |
| |
| 3.单个参数返回 |
| val => val |
| |
| 4.返回对象参数 |
| let getobj = obj => ( |
| {name:'666',age:18} |
| ) |
| |
| 闭包: |
| |
| let fn = (function(){ |
| return function(){ |
| return 123 |
| } |
| })() |
| fn(); |
| |
| 箭头函数闭包 |
| let fns = (() => { |
| return () => { |
| return 123 |
| } |
| }) (); |
| fn(); |
箭头函数指向this问题
| es6 解决this指向问题 使用=> 就会找上层的作用域 |
| 箭头函数之后没有this指向,通过查找作用域进行找 |
| 一但使用箭头函数,当前有没有作用域,就找上层的作用域 |
| 3层作用域 this |
| |
| let pa = { |
| id : 10, |
| |
| init:function(){ |
| |
| document.addEventListener('click',(event)=>{ |
| console.log(this); |
| this.doSomeThings(event.type) |
| |
| },false) |
| }, |
| doSomeThings:function(type){ |
| console.log(`事件类型${type},事件id${this.id}`) |
| } |
| |
| } |
| pa.init() |
| console.log(pa.doSomeThings()); |
| |
| 怎么查找作用域 |
| 在 document.addEventListener方法定义的内部是一个作用域 |
| 这个作用域上层指向了 init:function init变量 |
| init 变量的上层作用域 指向了对象pa 所以 this指向pa对象 |
| |
| 假设 int:function 定义为箭头函数 => 那么相当于 init没有作用域,就会找到pa对象的作用域 |
| 在找到window 作用域练 最外层. |
| |
| 箭头函数注意: |
| 1.使用箭头函数就会内部就没有 arguments 方法,因为使用箭头函数就没有作用域链,就会指向weindow |
| |
| let pa = ()=>{ |
| console.log(arguments) |
| return 10+20 |
| } |
| console.log(pa()) |
| |
| 2 箭头函数不能使用new关键字实例化对象 |
| let pa = ()=>{} |
| console.log(pa) |
| let p = function(){} |
| console.log(p()) |
| let p = new pa |
解构赋值
| |
| let info = { |
| type: 'id', |
| name: ' askjh' |
| } |
| es6 完全结构 |
| let { type, name } = info |
| console.log(type, name) |
| |
| |
| let obj = { |
| a: { |
| name: '张三' |
| }, |
| b: [], |
| c: 'hello world' |
| |
| } |
| let {a} = obj |
| console.log(a) |
| |
| 还可以使用 剩余运算符进行获取 |
| let {a,...bs} = obj |
| console.log(bs) |
| |
| |
| |
| let {a,b=30} = {a:40} |
| console.log(a,b) |
| |
| |
| |
| |
| let arr = [1,2,3] |
| let [a,b,c] = arr |
| console.log(a,b,c) |
| |
| |
| let [n,[d],e] = [1,[2],3] |
| console.log(n,d,e) |
对象的扩展
| 1. es6 直接写入变量的函数 作为对象的属性 |
| const name = '消息下', age = 12 |
| const pe = { |
| name, |
| age, |
| sayName(){ |
| console.log(name) |
| } |
| } |
| pe.sayName() |
| |
| |
| 2. set 方 与 get 方法的使用 |
| |
| |
| let caet = { |
| wheel:4 , |
| set(val){ |
| if (val < this.wheel){ |
| throw new Error('数量太少') |
| } |
| }, |
| get(){ |
| return this.wheel |
| } |
| } |
| caet.set(3) |
| console.log(caet.get()) |
| |
| 3. 属性表达式 |
| const obj = {} |
| obj.isshow = true |
| console.log(obj); |
| const name = 'a' |
| obj[name+'bc'] = 123 |
| console.log(obj) |
| obj['f'+ 'cc'] = function(){ |
| console.log(this); |
| } |
| console.log(obj) |
| |
| |
| |
| 4.对象方法 |
| |
| console.log(NaN === NaN); |
| console.log(Object.is(NaN,NaN)); |
| |
| 5.assign() 对象的合并 |
| let t = { |
| |
| } |
| let b = { |
| a:10 |
| } |
| Object.assign(t,b) |
| console.log(t) |
symbol类型
| 原始数据 symbol ,表示他他是一个独一无二的值 |
| const name = Symbol('name') |
| const name2 = Symbol('name') |
| const name3 = "name" |
| |
| console.log(name3 ===name) |
| console.log(name === name2); |
| console.log(typeof name ) |
| # 用来定义对象的私有变量,可以设置对象的私有的属性 |
| # 不能使用new命令 因为生成的 Symbol 是一个原始类型的值,不是对象,所以不能使用new命令来调用 |
| # 也不能作为对象进行使用, 可以认为他是一个字符串 |
| let obj = { |
| 'name' : '123' |
| } |
| let s2 = Symbol(obj) |
| console.log(s2); |
| |
| # Symbol 值不能与其他类型的值进行运算,会报错 |
| let a = Symbol('a') |
| console.log('bcd' + a); |
| |
| # Symbol 可以作为if中的参数可以作为bool,但是不能转为数值 |
| let a = Symbol() |
| console.log(Boolean(a)); |
| if(a){ |
| console.log('123'); |
| } |
| console.log(Number(sym)); |
| |
| |
| 内部方法 |
| const sym = Symbol('foo'); |
| 1.返回symbol('描述') 描述 |
| console.log(sym.description ); |
| |
| 2.可以作为对象的属性名 |
| let obj = {} |
| obj[sym] = 123456 |
| 或者 |
| let a = {}; |
| Object.defineProperty(a, mySymbol, { value: 'Hello!' }); |
| |
| 3.可以作为消除魔术字符串 |
| 魔术字符串:在程序中多次出现的 |
| const a = { |
| 'b':'name' |
| } |
| const a = { |
| 'b': Symbol() |
| } |
| |
| |
| 4.Symbol.for(),Symbol.keyFor() |
| s1 = Symbol.for('123') # 如果希望使用同一个Symbol对象就是for方法,他会全局环境中进行搜索,而Symbol不会,如果Symbol.for已经存在就会调用存在的Symbol.for不会重新创建 |
| Symbol.keyFor('s1') # 为了找到Symbol.for登记的值 |
set集合类型
| 无序不可以重复的类型 |
| let set = new Set() |
| console.log(set); |
| |
| 常用方法: |
| set.add('name') |
| set.delete('name') |
| set.has('name') |
| set.size |
| set.forEach((key,val)=>{ |
| console.log(key,val); |
| }) |
| |
| |
| let set2 = new Set([1,2,3,4,4,5,66,44]) |
| let arr = [...set2] |
| console.log(arr); |
| |
| |
| |
| |
| let arr1 = [ 1,2,3,4] |
| arr1 = null |
| |
| WeakSet() |
map类型
| map类型是键值对的有序列表,键和值的任意类型 |
| 无法被释放 |
| |
| |
| let map = new Map(); |
| |
| map.set("name", '张三') |
| |
| console.log(map) |
| |
| |
| console.log(map.get('name')); |
| |
| |
| console.log(map.has('name')) |
| |
| |
| console.log(map.delete('name')) |
| |
| |
| map.clear() |
| |
| |
| map.set([11, 2, 3, 44, 5, 6,], 'hello') |
| console.log(map); |
| |
| let m = new Map([["a", 1], ["b", 2]]) |
| console.log(m) |
数组补充
| 数组的方法 from of |
| function add(){ |
| arguments |
| console.log(arguments); |
| let arr = Array.from(arguments); |
| } |
| |
| add(1,2,3,4) |
| |
| |
| 2.使用扩展用算符进行快送转换运算符 |
| <li>1</li> |
| <li>1</li> |
| <li>1</li> |
| <li>1</li> |
| let lis = document.querySelectorAll('li') |
| |
| console.log([...lis]); |
| |
| 3.使用form对元素进行处理 |
| let lis = document.querySelectorAll('li') |
| let list = Array.from(lis, (ele) => { return ele.textContent }) |
| |
| let list2 = Array.from(lis, ele => ele.textContent ) |
| |
| 4.of方法 将一组的值转换为数组 任意的数据类型转换为数组 |
| console.log(Array.of(3,1,2,4,5,6,7,88,9)); |
| |
| |
| 5.数据的其他的方法 |
| 5-1.copywithin() 方法 了解 |
| |
| let a = [1, 2, 3, 4, 5, 6].copyWithin(0, 3) |
| console.log(a); |
| |
| |
| |
| 5-2.find查找数值 findindex查找数值的元素 |
| |
| [1, 2, -103, 4, 5, -10, 7].find((n) => { |
| return n < 0 |
| }) |
| |
| |
| [1, 2, -103, 4, 5, -10, 7].findindex((n) => { |
| return n < 0 |
| }) |
| |
| 5-3.includes 返回一个bool值 表示一个数组是否包含这个值 |
| |
| console.log([1,2,3,4].includes(2)); |
| console.log([1,2,3,4].includes(10)); |
| |
| 6.entries方法 |
| keys(对键的遍历) values(对值的遍历) 返回一个遍历起 可以使用for ... of 进行遍历 通过这些方法生成遍历器 |
| |
| 6-1.keys 获取索引 |
| let a = [1, 2, 3, 4, "a", 6].keys() |
| console.log(a); |
| |
| for (let index of a) { |
| console.log(index) |
| } |
| |
| 6-2.values 获取元素 |
| let b = [1, 2, 3, 4, "a", 6].values() |
| for (let index of b) { |
| console.log(index) |
| } |
| |
| 6-3.entries 获取val 和key |
| let c = [1, 2, 3, 4, "a", 6].entries() |
| for (let [key, val] of c) { |
| console.log('这是键', key) |
| console.log('这是值', val) |
| } |
迭代器interator
| |
| |
| const item = ['1',2,55,'asd'] |
| |
| |
| |
| |
| let func = item[Symbol.iterator]() |
| |
| console.log(func); |
| |
| |
| console.log(func.next()) |
| console.log(func.next()) |
| console.log(func.next()) |
| console.log(func.next()) |
| console.log(func.next()) |
| |
| |
| |
| |
| |
| |
生成器
| 生成器的应用,异步编程,让异步编程同步执行 |
| 1. |
| function* func(){ |
| |
| let res = yield request('传入的网络地址') |
| |
| |
| } |
| const ite = func() |
| ite.next() |
| function request(url){ |
| $.ajax({ |
| url:url, |
| method:'get', |
| success(res){ |
| ite.next(res) |
| } |
| }) |
| } |
| |
| 2.加载效果 |
| function* en(){ |
| add() |
| yield del() |
| func() |
| } |
| const ite = en() |
| console.log(ite); |
| ite.next() |
| function add(){ |
| console.log('开始加载... 图片'); |
| } |
| |
| |
| function func(){ |
| console.log('隐藏加载提示...显示图片') |
| } |
| |
| function del(){ |
| |
| setTimeout(() =>{ |
| console.log('加载完成,隐藏加载效果') |
| |
| |
| ite.next() |
| },5000) |
| |
| } |
生成器generator
| 作用: |
| 1.generator 函数 可以通过yield关键字 将函数挂起,为了改变执行流程提供了可读性 |
| 2.为异步编程(解决异步代码) |
| 区别: |
| 1.function后 函数名前 * |
| 2 只能在函数内部使用yield表达式 让函数挂起 |
| |
| 1.例如:生成器函数 |
| function* func(){ |
| yield 1; |
| } |
| |
| let fn = func() |
| |
| |
| console.log(fn.next().done); |
| |
| |
| |
| 案例 |
| |
| function* add(){ |
| console.log('hehehe'); |
| |
| let x = yield "a" |
| console.log('hahah',x); |
| let y = yield '123' |
| console.log('hahahz',y); |
| return x+y |
| } |
| let fn = add() |
| |
| |
| console.log(fn.next(10)); |
| |
| |
| |
| console.log(fn.next(20)); |
| |
| |
| |
| |
| console.log(fn.next(20)); |
| |
| |
| |
| 主要作用就是 不具备 interator 接口的对象提供的遍历操作 |
| 将不具备 interrator循环的对象 变为可遍历操作 |
| function* func(obj) { |
| const propkey = Object.keys(obj) |
| console.log(propkey); |
| for (let p of propkey) { |
| yield [p, obj[p]] |
| } |
| } |
| |
| |
| const obj = { |
| name: 133, |
| age: 456 |
| } |
| |
| |
| |
| console.log(obj); |
| |
| for (let [key, val] of func(obj)) { |
| console.log(key, val); |
| console.log(`${key}:${val}`) |
| } |
promise
| 异步编程的解决方案 承诺 因为是一个对象 所以需要new 创建对象 |
| promise 相当于一个容器,放置这未来要执行的事件(异步)的一个结果 |
| 各种异步操作都可以使用同样的方式进行处理 axios库就是基于promise |
| |
| |
| 特点: |
| 1. 对象的状态不收外接影响 异步处理的状态: peendig(进行中) resolved(成功) rejected(失败了) |
| 这三个状态 保存在peomise |
| 2.一旦改变,就会在变,任何时候都可以 得到结果 进行中- 成功 进行中-失败 都存储在peomise |
| |
| 案例: |
| |
| |
| |
| let pro = new Promise(function (rejected, resolved) { |
| |
| |
| let res = { |
| code: 200, |
| data: { |
| name: '成功了' |
| }, |
| error: '失败 了' |
| } |
| |
| setTimeout(() => { |
| if (res.code === 200) { |
| resolved(res.datas) |
| } else { |
| rejected(res.error) |
| } |
| }, 1000) |
| }) |
| console.log(pro); |
| |
| 创建的promise对象的回调方法 |
| |
| |
| pro.then((val) => { |
| |
| console.log(val); |
| }, (err) => { |
| console.log(err) |
| }) |
| |
| |
| 封装异步操作 |
| ex 接受时间 |
| 封装了promise 方法,变得更为灵活 |
| function time(ex) { |
| return new Promise((rejected, resolved) => { |
| setTimeout(() => { |
| resolved('成功的信息') |
| }, ex); |
| }) |
| } |
| time(1000).then((val) => { |
| console.log(val) |
| }) |
promise封装异步函数
| pormise 封装一个ajax 异步请求 |
| const getJSON = function(url){ |
| |
| new Promise((reject,resolve)=>{ |
| |
| const xhr = new XMLHttpRequest() |
| |
| xhr.open('GET',url) |
| |
| xhr.onreadystatechange = handler |
| |
| xhr.responseText = 'json' |
| |
| xhr.setRequestHeader('Accept','application/json') |
| |
| xhr.send() |
| |
| function handler(){ |
| |
| console.log(this.readyState) |
| if(this.readyState === 4){ |
| if(this.status === 200){ |
| resolve(this.response) |
| }else{ |
| reject(new Error(this.statusText)) |
| } |
| } |
| } |
| }) |
| } |
| |
| getJSON('url') |
| .then((val)=>{ |
| console.log(val) |
| },(error)=>{ |
| console.log(error); |
| }) |
| |
| |
| |
| |
| |
| |
| getJSON('url').then(val=>{ |
| |
| }).catch(err=>{ |
| |
| }) |
补充
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| function img(imgs) { |
| return new Promise((resolve, reject) => { |
| new imgg = new Image() |
| img.onload = function () { |
| resolve(img) |
| } |
| img.src = imgsrc |
| }) |
| } |
| |
| function timeout() { |
| let p = new Promise((resolve, reject) => { |
| setTimeout(() => { |
| reject('请求超时') |
| }, 3000) |
| }) |
| } |
| |
| Promise.rece([img('images/2.peg'), timeout()]).then(res => { |
| console.log(res); |
| }).catch(err=>[ |
| console.log(err) |
| ]) |
| |
| race() finally(()=>{也是一个回调函数}) 不论是promise对象请求数据成功失败 都会执行race() finally()这两个方法 |
async异步
| async 解决异步操作更加方便 |
| 使用async 进行异步操作 返回一个promise对象 可以统括then 和catch |
| async 时gemerator 的一个语法糖 |
| |
| 1.案例使用async |
| async function f(){ |
| |
| |
| |
| return await 'await等待命令' async方法必须要与await配合使用 |
| } |
| f() |
| f().then(res=>{ |
| console.log(res) |
| }).catch(error=>{ |
| console.log(error) |
| }) |
| |
| |
| 方便理解 |
| async function f(){ |
| let s = await '你好 你好 async' |
| let data = await s.split('') |
| return data |
| |
| } |
| |
| |
| async函数中有多个await 那么then函数等待 所有的await指令 运行完毕的结果 才会执行then |
| |
| |
| await '后面必须是一个promise对象,不管是什么类型都会转换为promise对象' |
| await 特点就是 如果一个出错执行了错误信息,下面的await不会执行 |
| |
| 2.捕获异常 |
| async function f2(){ |
| await Promise.reject('出错了') |
| await Promise.resolve('正确的') |
| |
| } |
| f2().then( |
| (val)=>{ |
| console.log(val); |
| } |
| ).catch( |
| (err)=>{ |
| console.log(err); |
| }) |
| |
| |
| 3.解决await 出现错误不执行的弊端 |
| async function f2(){ |
| try { |
| await Promise.reject('出错了') |
| }catch(err){ |
| } |
| return await Promise.resolve('正确的') |
| } |
| |
| f2().then( |
| (val)=>{ |
| console.log(val); |
| } |
| ).catch( |
| (err)=>{ |
| console.log(err); |
| }) |
| |
| |
| 4.模拟异步请求 |
| function getJSON(url){ |
| |
| console.log(url) |
| return HeWeather6 |
| } |
| |
| |
| HeWeather6 = { |
| now :{ |
| 'xx':123 |
| } |
| } |
| |
| |
| async function func(url) { |
| |
| |
| let res = await getJSON(url) |
| |
| let arr = await res.now |
| return arr |
| } |
| |
| |
| |
| func('这是url').then((val) => { console.log(val); }) |
| |
| 总结:generator promise async 解决回掉地狱的问题(回掉循环 嵌套太多) 异步操作更加方便 |
class构造
| class 关键字时es6的语法糖 |
| |
| class Person{ |
| constructor(name,age){ |
| this.name = name |
| this.age = age |
| } |
| |
| sayname(){ |
| return this.name |
| } |
| sayage(){ |
| return this.age |
| } |
| |
| } |
| |
| let p1 = new Person('aa',123) |
| console.log(p1); |
| |
| console.log(p1.sayage()); |
| console.log(p1.sayname()); |
| |
| |
| |
| Object.assign(Person.prototype,{ |
| sayxx(){ |
| return xx |
| }, |
| sayzz(){ |
| return yy |
| } |
| }) |
class类的继承
| |
| |
| |
| class animal { |
| |
| constructor(name, age) { |
| this.name = name |
| this.age = age |
| } |
| |
| show() { |
| return this.name |
| } |
| func() { |
| return this.age |
| } |
| } |
| 继承语法: |
| class 子类名 extends 父类名 |
| class dog extends animal{ |
| |
| } |
| |
| |
| class dog extends animal{ |
| |
| constructor(name,age,color){ |
| super(name,age) |
| this.color = color |
| } |
| |
| saycole(){ |
| return `${this.name}${this.age}` |
| } |
| |
| func() { |
| return `${this.name}${this.age}` |
| } |
| } |
| |
| let p1 = new dog('aa',18,'red') |
| console.log(p1); |
| |
| |
| console.log(p1.show()); |
| |
| console.log(p1.color()); |
模块化
| 在modules/index.js文件将函数或者变量进行抛出 |
| |
| |
| |
| |
| |
| export const name = '张珊' |
| export const age = 18 |
| |
| export function func(){ |
| return '你好我是xx' |
| } |
| |
| export {func} |
| |
| |
| |
| |
| 在需要的文件导入index.js文件中的变量和函数 |
| <script type="module"> |
| |
| |
| import {name,age,func} from './modules/index.js' |
| |
| console.log(name) |
| console.log(age) |
| console.log(func()); |
| |
| </script> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现