箭头函数,symbol,迭代器,生成器函数,promise,Set,Map,Class,数值的扩展,模块化,async,await,常用方法的使用

本文介绍了JavaScript中的剪头函数、symbol的独特性、基本类型与对象、迭代器与生成器的用法,以及Promise、Set、Map和类的深入实践。通过实例演示了如何解决回调地狱、异步操作和数据结构的运用。
摘要由CSDN通过智能技术生成

一、剪头函数

1、第一种方法

//语法
let 函数名 = (参数) => {}
let func_name = (item) => {
    return item * item;
}

2、第二种方法(参数只有一个时,可以省略括号)

//语法
let 函数名 = 参数 => {}
let func_name = item => {
    return item * item;
}

3、第三种方法(函数只有一行代码时,可以省略花括号)

//语法
let 函数名 = 参数 => 参数 * 参数
const arr = [1,2,3,4,5,6,7]
const result = arr.filter(item => item % 2 ===0 )

注:filter()返回符合函数返回的值;

箭头函数适合与 this 无关的回调,定时器,数组的方法回调;

箭头函数不适合与this 有关的回调,时间回调,对象的方法;

参数默认值
函数形参可以给默认值,调用函数的时候如果传值则使用所传的值,没传值则使用默认值

let sum = (a,b,c=7) => a+b+c;

//调用,不给C传参,结果 10
sum(1,2);
//给C传参
sum(2,5,7);
解构赋值:
function sum(options){
    console.log(options.host);
    console.log(options.username);
    console.log(options.password);
    console.log(options.port);
}
//调用传参
sum({
    host: 'www.baidu.com',
    username: 'wayne',
    password: '123456',
    port: 3306
});

function sumTwo({host: '192.168.0.0',username,password,port}){
    console.log(host);
    console.log(username);
    console.log(password);
    console.log(port);
}
//调用传参
sumTwo({
    host: 'www.baidu.com',
    username: 'wayne',
    password: '123456',
    port: 3306
});

rest参数(es6新增)

//es5写法:
function data(){
    console.log(arguments);//打印出来的是一个对象
}
data('wayne','del','zhang','bin');

…args必须放在最后面,因为他会把传的参数都归类到一个数组里

//es6写法:
function data(...args){
    console.log(args);//打印出来的是一个数组
}
data('wayne','del','zhang','bin');

function data(a,b,...args){
    console.log(args);//打印出来的是一个数组
}
data('wayne','del','zhang','bin');

…三个点可以将数组转化成逗号连接的元组

扩展运算符的应用

1、数组合并

1、常用方法concat:
let arr1 = [1,2];
let arr2 = [3,4];
let arr3 = arr1.concat(arr2);
2、扩展运算符:
let arr4 = [...arr1,...arr2];

2、克隆数组

let arr = [1,2,3,4];
let new_arr = [...arr];

3、将伪数组转成真数组

let divs = document.querySelectAll('div');
let divs_arr = [...divs];

二、symbol

symbol是唯一的,不可以用于计算,比较;symbol是独一无二的值;

//1、第一种创建方式
let name = symbol('zhang');
//2、第二种创建方式
let name = symbol.for('zhang');

使用for创建的相同值,会是相等的;

let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');

s1 === s2 // true

JavaScript基本类型:

//记得技巧
USONB
U undefined
S string symbol
O object
N number null
B boolean

创建symbol对象属性:

let games = {
    name: 'wayne',
    [Symbol('say')]: function(){
        console.log('添加成功!');
    },
    [Symbol('animate')]: function(){
        console.log('燃起来吧!');
    }
}

symbol值可以转化为boolear值,但是不能转化为数值;

symbol.description可以返回symbol的描述;

getOwnPropertySymbols()方法,可以获取指定对象的所有 Symbol 属性名(只返回symbol属性);

Reflect.ownKeys()方法可以返回所有类型的键名,包括常规键名和 Symbol 键名;

Symbol.for()为 Symbol 值登记的名字,是全局环境的,不管有没有在全局环境运行。

三、迭代器

iterator,迭代器

const names = ['wayne','del','zhang','b']
let iterator = names[Symbol.iterator]();
//调用next()方法,指向下一个
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

四、生成器函数

创建生成器函数,就在function后面加个*;

function * names(arg){
    console.log(arg);
    yield 111;
    console.log(arg);
    yield 222;
    console.log(arg);
    yield 333;
}

//执行获取迭代器函数
let name = names('AAA');
console.log(name.next());
//next()方法可以传参
console.log(name.next('BBB'));
console.log(name.next('CCC'));
console.log(name.next('DDD'));

使用生成器函数解决回调地狱问题;

//我想使控制台输出1,2,3,每过一秒输出一个,老方法使用定时器嵌套
function one () {
  setTimeout(() => {
    console.log(111);
    action.next();
  }, 1000);
}

function two () {
  setTimeout(() => {
    console.log(222);
    action.next();
  }, 2000);
}

function three () {
  setTimeout(() => {
    console.log(333);
    action.next();
  }, 3000);
}

function* send () {
  yield one();
  yield two();
  yield three();
}

let action = send();
action.next();

生成器用于异步操作:

//拿一个用户的数据  
	function user() {
      setTimeout(() => {
        let data = '用户数据';
        action.next(data);
      }, 1000);
    }

    function goods() {
      setTimeout(() => {
        let data = '商品数据';
        action.next(data);
      }, 1000);
    }

    function order() {
      setTimeout(() => {
        let data = '订单数据';
        action.next(data);
      }, 1000);
    }

    function* gen() {
      let users = yield user();
      console.log(users);
      let good = yield goods();
      console.log(good);
      let orders = yield order();
      console.log(orders);
    }

    let action = gen();
    action.next();

五、promise

实例化promise对象:

// 实例化 promise 对象
    const app = new Promise(function (resolve, reject) {
      // 成功返回
      // let data = '成功获取到数据!';
      // resolve(data);
        
      // 失败返回
      let data = '获取数据失败了';
      reject(data);
    })

调用 promise 对象的 then 方法,then方法里面有两个函数,一个返回成功的,一个返回失败的,成功里面带的是value,失败里面带的是reason;

//调用promise对象的then方法
    app.then(function (value) {
      console.log(value);
    }, function (reason) {
      console.error(reason);
    })

调用打开其他文件的内容;

const fs = require('fs');
// 实例化
const app = promise(function (resolve, reject) {
  fs.readFile('./data.md', function (err, data) {
    if (err) reject(err);
    resolve(data);
  })
})
// 调用 promise 对象的 then 方法
app.then(function (value) {
  console.log(value.toString());
}, function (reason) {
  console.error('读取失败');
})

最基础的请求数据方式:

    // 1.创建对象
    const xhr = new XMLHttpRequest();

    // 2.初始化
    xhr.open("GET", "https://test.api.com/v3/course/info?course_id=85");

    // 3、发送请求
    xhr.send();

    // 4、绑定事件,处理响应结果
    xhr.onreadystatechange = function () {
      // 判断
      if (xhr.readyState === 4) {
        // 判断响应状态码 200-299
        if (xhr.status >= 200 && xhr.status <= 299) {
          // 成功则返回
          console.log(xhr.response);
        } else {
          // 失败则返回
          console.error(xhr.status);
        }
      }
    }

使用promise封装Ajax:

// promise封装Ajax
    const app = new Promise(function (resolve, reject) {
      // 接口地址:https://api.apiopen.top/getJoke

      // 1.创建对象
      const xhr = new XMLHttpRequest();

      // 2.初始化
      xhr.open("GET", "https://test.api.com/v3/course/pageList?page_num=1");

      // 3、发送请求
      xhr.send();

      // 4、绑定事件,处理响应结果
      xhr.onreadystatechange = function () {
        // 判断
        if (xhr.readyState === 4) {
          // 判断响应状态码 200-299
          if (xhr.status >= 200 && xhr.status <= 299) {
            // 成功则返回
            resolve(xhr.response);
          } else {
            // 失败则返回
            reject(xhr.status);
          }
        }
      }
    })

    // 指定回调
    app.then(function (value) {
      console.log(value);
    }, function (reason) {
      console.error(reason);
    })

使用promise解决回调地狱问题:

// 使用promise解决回调地狱问题
    const app = new Promise((resolve, reject) => {
      fs.readFile("./XXX.XX", (err, data) => {
        resolve(data);
      })
    });

    // 指定回调
    app.then(value => {
      return new Promise((resolve, reject) => {
        fs.readFile("./XXX.XX", (err, data) => {
          resolve([value, data]);
        })
      })
    }).then(value => {
      return new Promise((resolve, reject) => {
        fs.readFile("./XXX.XX", (err, data) => {
          value.push(data);
          resolve(value);
        })
      })
    })

六、Set

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

set是一个新增的构造函数,会自动去重,将重复的元素删除;

//创建set()数据结构  更多使用的是const进行创建
const names = new Set();

//也可以直接在Set()中添加数据,一般都是直接添加数组
const names = new Set(['wayne','zhang','del','bin']);

//对set()对象的操作有:.add(新增元素),.delete(删除元素),.has(检测元素),.clear(清空元素)
//添加元素
names.add('tian');
//删除元素
names.delete('tian');
//检测元素(检测数组中是否有该元素,又返回true,没有返回false)
names.has('tian');
//清空元素
names.clear();

//可以使用for……of进行遍历
for(let v of names){
    console.log(v);
}

数组去重

// 去除数组的重复成员
[...new Set(array)]

// 也可以去除重复的字符
[...new Set('ababbc')].join('')

// Array.from 去除数组重复成员的另一种方法
const items = new Set([1, 2, 3, 4, 5]);
const array = Array.from(items);

Set 结构的实例有四个遍历方法,可以用于遍历成员。

  • Set.prototype.keys():返回键名的遍历器
  • Set.prototype.values():返回键值的遍历器
  • Set.prototype.entries():返回键值对的遍历器
  • Set.prototype.forEach():使用回调函数遍历每个成员

默认遍历的方法是values

let arr = new Set(['wayne','del','zhang'])
// keys()
for(let item of arr.keys()){
    console.log(item);//返回的是键名:'wayne','del','zhang'
}
// values()
  for(let item of arr.values()){
      console.log(item);//返回的是键值:'wayne','del','zhang'
  }

  // entries()
  for(let item of arr.entries()){
      console.log(item);//返回的是键值对:['wayne','wayne'],['del','del'],['zhang','zhang']
  }

  //forEach()
  arr.forEach((value, key) => console.log(key + ' : ' + value));//返回的'wayne':'wayne','del':'del','zhang':'zhang'

Set 结构的键名就是键值(两者是同一个值),因此第一个参数与第二个参数的值永远都是一样的。

实例:
let num_one = [1, 2, 3, 4, 5, 2, 3, 6];
  let num_two = [7, 4, 8, 9, 2, 5, 5, 5];
  // 1、去重
  let aa = [...new Set(num_one)];
  let bb = [...new Set(num_two)];
  console.log('去重', aa, bb);
  // 2、交集
  let intersection = aa.filter(item => new Set(bb).has(item));
  console.log('交集', intersection);
  // 3、并集
  let union = [...new Set([...aa, ...bb])];
  console.log('并集', union);
  // 4、差集
  let dif = aa.filter(item => !new Set(bb).has(item));
  console.log('差集', dif);

七、Map

它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。

map是一个升级版的对象;

	//声明一个map对象
    let names = new Map();

    // 对map的一些操作,set(添加元素),get(获取元素),size(查看对象长度),delete(删除对象,括号内填写所要删除的键),clear(清空对象)
    // set操作
    names.set('name', 'wayne');
    names.set('change', () => {
      console.log('Map是一个对象');
    })
    let age = () => {
      console.log('map函数');
    }
    names.set(age, [22, 23, 24, 25]);
    console.log(names, names.size);
	
	//get操作
	names.get('name');//返回:wayne
    //size操作
    console.log(names.size);

    // delete操作
    names.delete('change');
    console.log(names, names.size);

    // clear操作
    names.clear();
    console.log(names, names.size);

八、Class

Es5通过构造函数实例化对象的语法:

	// 这是Es5通过构造函数实例化对象的语法
    // 手机
    function Phone(brand, price) {
      this.brand = brand;
      this.price = price;
    }

    // 添加方法
    Phone.prototype.call = function () {
      console.log('我可以打电话!');
    }

    // 实例化对象
    let Huawei = new Phone('华为', 5999);
    Huawei.call();
    console.log(Huawei);

Es6 class写法:

    // Es6 Class
    class Iphone {
      // 构造方法,名字不能修改
      constructor(brand, price) {
        this.brand = brand;
        this.price = price;
      }

      // Es5中对象创建方法使用的是call: function(){},在class中不允许使用:,直接call()
      call() {
        console.log('这是Es6 class的写法');
      }
    }

    // 实例化类
    let xiaomi = new Iphone('xiaomi', 4399);
    xiaomi.call();
    console.log(xiaomi);

static属性只属于类,不属于实例化对象

    class Phone {
      // 静态属性
      static name = 'static静态属性只属于类,不属于实例化对象';
      static change() {
        console.log("我只属于类");
      }
    }

    // 实例化对象
    let call = new Phone();
    console.log(call.name);
    console.log(Phone.name);

Es5的继承

    // 这是父
    function Phone(brand, price) {
      this.brand = brand;
      this.price = price;

    }

    Phone.prototype.call = function () {
      console.log('我可以打电话');
    }
    // 智能手机 这是子
    function son_phone(brand, price, color, size) {
      Phone.call(this, brand, price);
      this.color = color;
      this.size = size;
    }

    // 设置子级构造函数的原型
    son_phone.prototype = new Phone;
    son_phone.prototype.constructor = son_phone;

    // 声明子类的方法
    son_phone.prototype.photo = function () {
      console.log('我可以拍照');
    }

    son_phone.prototype.playGame = function () {
      console.log('我可以玩游戏');
    }
    const app = new son_phone('小米', 4699, '黑色', '6.9inch');
    console.log(app);

Es6 class的继承

    // es6 封装继承
    class Phone {
      // 构造方法
      constructor(brand, price) {
        this.brand = brand;
        this.price = price;
      }

      call() {
        console.log('我可以打电话');
      }
    }

    class Son_phone extends Phone {
      // 构造方法
      constructor(brand, price, color, size) {
        super(brand, price);
        this.color = color;
        this.size = size;
      }

      photo() {
        console.log('我可以拍照');
      }

      playGame() {
        console.log('我可以打游戏');
      }
    }

    const app = new Son_phone('xiaomi', 4699, 'black', '6.9inch');
    console.log(app);
    app.call();
    app.photo();
    app.playGame();

九、数值的扩展

    //1.Number.EPSILON是JavaScript表示的最小精度
    //EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16
    function equal(a, b) {
      if (Math.abs(a - b) < Number.EPSILON) {
        return true;
      } else {
        return false;
      }
    }
    console.log(0.1 + 0.2 === 0.3);//false
    console.log(equal(0.1 + 0.2, 0.3));//true
    //2.Number.isFinite检测一个数值是否为有限数
    // isFinite判断返回值是否有限,有限个返回TRUE,无限个返回FALSE
    let num = 100;
    console.log(Number.isFinite(num));//true

    //3.Number.isNaN 检测一个数值是否为NaN,判断数值是否为非数字NaN
    let a = NaN;
    console.log(Number.isNaN(a));//true

    // 4.Number.parseInt Number.parseFloat可以将字符串转化成整形,浮点型
    let b = '1351adnaw';
    let c = '852.332bbb';
    console.log(Number.parseInt(b), Number.parseFloat(c));//1351  852.332

    // 5.Number.isInteger 判断一个数值是否是整数
    console.log(Number.isInteger(5));//true
    console.log(Number.isInteger(2.5));//false

    // 6.Math.trunc 将数字的小数部分抹掉
    console.log(Math.trunc(3.5));//3

    // 7.Math.sign 判断一个数是否是正数  负数  零
    console.log(Math.sign(100));//1
    console.log(Math.sign(0));//0
    console.log(Math.sign(-100));//-1
    // 1、Object.is 判断两个值是否完全相等
    console.log(Object.is('zhang', 'wayne'));//false
    console.log(Object.is('wayne', 'wayne'));//true

    // 2、Object.assign 对象合并
    const a = {
      name: 'wayne',
      age: 29,
      sex: 'man',
      money: 99999999
    }
    const b = {
      name: 'zhang',
      age: 24,
      sex: 'man'
    }
    // 谁在前面谁就是模板,如果出现相同键名,后面的值会覆盖前面的值
    console.log(Object.assign(a, b));

    // 2、Object.prototypeof 设置原型对象  Object.prototypeof 获取原型对象
    const app = {
      name: 'wayne'
    }
    const cities = {
      names: ['wayne', 'zhang', 'del']
    }
    // 第一个参数是需要设置的对象    第二个参数是定义的类型
    Object.setPrototypeOf(app, cities);
    console.log(Object.getPrototypeOf(app));
    console.log(app);

十、模块化

使用模块化之前,vscode先下载一个live server;

只有export声明过的属性,方法,函数等才能被引用

//这是一个data.js文件
//第一种暴露方式
let name = 'wayne';
export let age = 24;
export function call () {
  console.log('我可以打电话!');
}
//第二种暴露方式
let name = '韦恩';
function call () {
  console.log("我可以打电话!");
}
export { name, call };
//第三种暴露方式(默认暴露),default后面可以是任意类型,数字、字符串、对象等
export default {
  names: 'zhang',
  money: function () {
    console.log('99999999元');
  }
}

导入方式:

//这是使用es6引用data.js内的数据
<script type="module">
    //引入 data 模块内容
    //第一种导入方式:通用导入方式
    import * as data from './data.js'
    console.log(data);

	// 第二种导入方式:解构赋值形式
    import { name, call } from './data.js';
    // 当别名相同时,可以利用as进行更改名字
    import { name as user, call } from './data.js';
	// 默认导入,一定要重命名,不能直接使用default
    import { default as data } from './data.js';
    console.log(data);

    // 3、简便形式  针对默认暴露
    import data from './data.js';
    console.log(data);
</script>

十一、async

声明一个async函数

async function call(){
	return 'wayne';
}
const result = call();
console.log(result);

async返回的永远都是一个promise对象,除了主动抛出错误,或者手动返回一个promise对象,且返回错误,其他情况都是返回正确promise对象,resolve;

async function fn(){
    return new Promise(resolve,reject){
        //返回成功
        resolve('成功的数据');
        //返回失败
        //reject('失败的数据');
    }
}

const result = fn();

result.then(value=>{
    console.log(value);
},reason=>{
    console.log(reason);
})

await的使用:

const p = new Promise((resolve,rejecet)=>{
    resolve('成功的值');
    reject('失败的值');
})
async fucntion fn(){
    try{
        //try里面返回Promise正确的值,需要在p前面是用await
		let result = await p;
        console.log(result);
    }catch(e){
        //catch返回错误的值
        console.log(e);
    }
}

async和await结合起来使用,非常像同步的异步执行;

function fn1() {
      return new Promise((resolve, reject) => {
        resolve('成功数据111');
      })
    }

    function fn2() {
      return new Promise((resolve, reject) => {
        resolve('成功数据222');
      })
    }

    function fn3() {
      return new Promise((resolve, reject) => {
        resolve('成功数据333');
      })
    }

    async function main() {
      let one = await fn1();
      let two = await fn2();
      let three = await fn3();
      console.log(one);
      console.log(two);
      console.log(three);
    }

    main();

封装Ajax进行请求数据

    function sendAjax(url) {
      return new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest();
        xhr.open("GET", url);
        xhr.send();
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4) {
            xhr.status === 200 ? resolve(xhr.responseText) : reject(xhr.responseText);
          }
        }
      })
    }

    async function fn() {
      try {
        let res = await sendAjax("http://test.api.com/v3/course/pageList?page_num=1&page_size=10");
        console.log(res);
      } catch (e) {
        console.log(e);
      }
    }

    fn();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值