当前位置: 首页 > news >正文

04-ES6

let和const命令

ES6中新增了let命令,用来声明变量,用法类似与var

let和var的不同:

1、不存在变量提升        

          console.log(a); //Cannot access 'a' before initialization

          let a = 100;

2、同一个作用域不能重复定义同一个名称

          var c = 20;

          let c = 30;

          console.log(c);//Identifier 'c' has already been declared

3、有严格的作用域        

        function fn() {

            var a = "a";

            if (true) {

              var a = "b";

            }

            console.log(a);//b

          }

          fn();

          function fn() {

            var a = "a";

             //ES6中引入了块级作用域,var a 和let a不在一个作用域中

            if (true) {

              let a = "b";

            }

            console.log(a);//a

          }

          fn();

4、块级作用域的重要性

        //for循环的i会提升为全局变量

          for (var i = 0; i < 5; i++) {}

          console.log(i); //5

          for (let i = 0; i < 5; i++) {} //i的作用域范围只能在for循环的过程中

          console.log(i); //i is not defined

const的使用

const 声明一个只读的常量。一旦声明,常量的值就不能改变。

保持let的不存在变量提升,同一个作用域内不能重复定义同一个名称,有着严格的作用域;

常量obj储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把obj指向另一个地址, 但对象本身是可变的,所以依然可以为其添加新属性

const x = 10;//如果声明的是常量,则不能修改

  x = 100; //Assignment to constant variable.

  console.log(x);

  const y;//Missing initializer in const declaration const声明变量时,需要立即初始化

  console.log(y);

  //const声明引用类型,可以对值进行修改

  const arr = [1,2,3,4];

  arr[0] = 100;

  console.log(arr);

  const obj = {};

  obj.id = 1;

  console.log(obj);

解构

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)

解构是ES6的新特性, 比ES5代码简洁,清晰,减少代码量

数组解构

左边模式匹配,定义变量,右边是定义的数组或者对象

let [a, b, c] = [1, 2, 3];

let [a2, b2, c2, d2] = ["red", "blue", "green"];

let [x, [y1, y2], z] = [1, [2, 3], 4];

let arr = [100, 200];

var x = arr[0] || 1;

//默认值写法

let [x = 1] = arr; //arr[0]存在在解构成x,如果不存在,则赋值为1

//当值是undefined的时候,才会触发默认值机制

let [x = 1] = [undefined, undefined];

console.log(x);//1

var [y = 1, z] = [100, null];
console.log(y,z);//100 null

//默认值如果是表达式【函数】,值在用到的时候,才会执行,惰性求值

var [y = 1, z = f()] = [100, 200];

console.log(y,z);//100,200

对象解构

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对 象的属性没有次序,变量必须与属性同名,才能取到正确的值

对象解构的写法:let { id, name } = { id: 1, name: "jack" };

如果没有对应的属性名,则返回undefined

//id:_id  别名

let { id:_id, name:_name } = { id: 1, name: "jack" };

//i为undefined,则返回1

let { id: _id, name: _name, i = 1 } = { id: 1, name: "jack" };

let { x = 10 } = {};

console.log(x);//10

let { x:a = 10 } = {};

console.log(x);//x is not defined,x是匹配模式,真正的变量是a

//解构用于方法入参

const fn = ({ count, num }) => num + count;
var obj = { count: 100, num: 99 };
let sumcount = fn(obj);
console.log(sumcount);

//累加&解构

let obj = { id: 1, msg: "error", arr: [5, 6, 7, 8] };

const sum = ({ id, arr }) =>
arr.reduce((total, current) => total + current, id);
console.log(sum(obj));

如果要将一个已经声明的变量用于解构赋值,必须非常小心

//报错的原因:因为 JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在 行首,避免 JavaScript 将其解释为代码块,才能解决这个问题

let x;
{x} = {x:1};//编译错误
console.log(x);

正确写法:

let x;
({x} = {x: 1});
将整个解构赋值语句,放在一个圆括号里面,就可以正确执行

函数参数解构

//数组参数解构

function sum([x = 0, y = 0]=[]) {
return x + y;
}

函数参数 [x = 0, y = 0] = [] 表示:

  • 参数是一个数组,默认值为空数组 []
  • 如果传入的数组没有第一个元素,x默认为0
  • 如果传入的数组没有第二个元素,y默认为0

sum();//0+0=0

sum([1]);//1+0=1;

sum([1,2]);

//对象参数解构

function fn2({ x = 1, y = 2 } = {}) {

  console.log(x + y);

}

var obj = { x: 10, y: 20 };

fn2(obj);

 扩展

字符串扩展

includes():     返回布尔值,表示是否找到了参数字符串。

startsWith():   返回布尔值,表示参数字符串是否在原字符串的头部。

endsWith():     返回布尔值,表示参数字符串是否在原字符串的尾部

repeat():       返回一个新字符串,表示将原字符串重复n次。

padStart():     用于头部补全

padEnd():       用于尾部补全

数值扩展

Number.parseInt("100");

Number.parseFloat("100.01");

//用来判断数字是否是一个整数,返回bool

Number.isInteger(100.01);

Math.ceil()       返回大于或等于一个给定数字的最小整数,ES5

Math.floor()     返回小于或等于一个给定数字的最大整数,ES5

Math.round()     返回一个数字四舍五入后最接近的整数,ES5

//ES6

Math.trunc()     用于去除一个数的小数部分,返回整数部分

Math.sign()       方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数 值

//运算符:**,指数运算符

2**3 = 8

数组扩展

//用于将一组值,转换为数组

var v = Array.of(); //[]

var v = Array.of(1, 2, 3); //[1,2,3]

//ES6  

var v = Array.of(); //[]

var v = Array.of(1, 2, 3); //[1,2,3]

//创建指定长度的数组,ES5

var v = new Array(3);//参数是数字,则是数组长度

console.log(v.length);

//创建一个数组,数组内的元素是字符3,ES5

var v1 = new Array("3");

console.log(v1);

//find()用于找出第一个符合条件的数组成员

//find方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组

var arr = [3, 4, 7, 9];

var a = arr.find((value, index, arr) => {

  return value > 5;

});

//findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,

// 如果所有成员都不符合条件,则返回-1

var arr = [3, 4, 7, 9];

var a = arr.find(function (item, index, arr) {

  //返回第一个符合条件的数组成员的位置

  return item > 5;

});

//用于将一个固定值替换数组的元素

var arr = ["blue", "Orange", "red", "green"];

arr.fill("abc", 2, 4); //["blue", "Orange", "abc", "abc"]

//方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的 includes 方法类似

[1, 2, 3].includes(2); // true

[(1, 2, 3)].includes(4); // false

var arr = ["blue", "Orange", "red", "green"];

arr.includes("blue"); //true

//用于将嵌套的数组“拉平”,变成一维的数组

var v = [1, 2, [3, 4], 5, [6, 7, 8]].flat(); //[1, 2, 3, 4, 5, 6, 7, 8]

对象扩展

  //对象属性2种定义方式

  var o = {};

  o.name = "xp";

  let v = "age";

  o[v] = 20; //这种定义v指的是变量

  console.log(o);

  //对象属性定义方式

  let age = "age1";

  o = {

    [age]: 22,

  };

  console.log(o);

//链判断运算符

let firstName = message.body.user.firstName; //可以这样写,但是不规范,没有对数据的存在进行校验

firstName =

  (message &&

    message.body &&

    message.body.user &&

    message.body.user.firstName) || 'default';

//这样的层层判断非常麻烦,引入了“链判断运算符” ?.,简化上面的写法

firstName = message?.body?.user?.firstName || "default";

//空值合并运算符

let info = "aaaa";

let b = info ?? "bbbb";//如果info为null或者undefined,则取很后面的值

函数扩展

函数默认参数

  /****************ES5*************** */function fun(x, y) {y = y || 20;console.log(y);}fun(123);/****************ES6********************* */function fun(x, y = 10) {console.log(y);}fun(234);

rest参数

  /****************arguments******************* *///方法的参数是动态的,使用arguments参数集合,类似与数组function fn() {console.log(arguments); //类似数组}fn(1, 2, 3);////rest动态参数function fn(...values) {console.log(values);let filterNum = values.filter((value, index, values) => {return value > 20;});console.log(filterNum); //[ 222, 333 ]}fn(11, 222, 333, 13); //结果是一个标准的数组//报错function fun(a,...b,c){}fun(1,2,3,4)

箭头函数

  var f = (n1, n2) => n1 + n2;//定义一个方法,返回一个对象var f = function (n1, n2) {return { n1, n2 };};//箭头函数写法---写法错误var f = (n1, n2) => {n1, n2;};//正确写法var f = (n1, n2) => {return { n1, n2 };};var a = f(1, 2);console.log(a); //{ n1: 1, n2: 2 }//正确写法,返回对象,需要使用()把对象包起来var f = (n1, n2) => ({ n1, n2 });var a = f(1, 2);console.log(a); //{ n1: 1, n2: 2 }///方法入参解构let f = ({ x = 0, y = 0 } = {}) => {return [x, y];};f({ x: 3, y: 3 });
箭头函数的坑

1、箭头函数不能当成构造函数,也就是不能使用new关键字 

  //箭头函数不能当成构造函数,也就是不能使用new关键字var p_fn = (name, age) => {this.name = name;this.age = age;};var pfn = new p_fn("aaa", 30); //p_fn is not a constructor

2、箭头函数没有原型对象

3、不可以使用arguments对象 该对象在函数体内不存在 替代 rest

  var f = () => {console.log(arguments[2]);};f(); //Uncaught ReferenceError: arguments is not defined//使用rest代替var f = (...rest) => {console.log(rest);};f(1, 2, 3, 4);function fn3() {console.log(arguments[1]);}fn3(1, 2, 3, 4); //2

4、this指向 由于箭头函数不绑定this,它会捕获其所在上下文的this的值,作为自己的this值

  let x = "x";let y = "y";let obj = {x: "x2",y: "y2",getX: function () {console.log(this.x);},getY: () => {console.log(this); //this指向Windowconsole.log(this.y);},};obj.getX(); //this指向objobj.getY(); //undefined//箭头函数中this指向://箭头函数中没有this,但是箭头函数会捕获所在(定义的位置)上下文的this的值。//这里的getY在obj对象中,obj对象定义在Window里。

尽量不要在对象的方法里写箭头函数【不确定就在箭头函数中打印this】

扩展运算符

扩展运算符是三个点...

它好比rest参数的逆运算。

扩展运算符将一个数组转为用逗号分隔的参数序列。

该运算符主要用于函数调用。

  //合并两个数组let arr2 = [1, 2, 3];let arr3 = [4, 5];let arr4 = [...arr2, ...arr3];console.log(arr4);function sum(x, y) {return x + y;}const item = [1, 2];sum(...item);/***************************************************///第一种写法var a = [];function f(x, y) {a.push(...y);}f(a, [1, 2, 3, 4]);console.log(a); //[ 1, 2, 3, 4 ]//第二种写法var a = [];function f(x, ...y) {//这的...y是可变参数,会将参数变成数组,也就是[[1, 2, 3, 4]]a.push(...y);//这的...y是扩展运算符,会将[[1, 2, 3, 4]]分解成[ 1, 2, 3, 4 ]}f(a, [1, 2, 3, 4]);console.log(a); //[[ 1, 2, 3, 4 ]]/**********************扩展************************ */let array = [{ id: 1, name: "a" },{ id: 3, name: "a" },{ id: 10, name: "a" },{ id: 4, name: "a" },{ id: 27, name: "a" },{ id: 50, name: "a50" },];//求id最大的对象?let maxId = Math.max(...array.map((v) => v.id));console.log(maxId);

扩展运算符可以和解构结合起来使用

  let [first, ...rest] = [1, 2, 3, 4, 5];console.log(first);//1console.log(rest);//[ 2, 3, 4, 5 ]

扩展运算符在对象中的使用

  let o1 = { id: 1 };let o2 = { name: "o2" };let o3 = { ...o1, ...o2 };console.log(o3);//{ id: 1, name: 'o2' }
http://www.dtcms.com/a/273165.html

相关文章:

  • 多线程 JAVA
  • Java :Optional容器类
  • python的保险业务管理与数据分析系统
  • AI 智能体:从辅助工具到自主决策者
  • 【YOLO脚本】对模型yaml文件测试
  • ZYNQ MPSOC PL端DDR4读写--仿真(3)
  • JDK的Closure闭包详解
  • 发现和发明浅谈
  • 2025年最新Dubbo-admin 部署
  • HTML初学者第四天
  • Android 应用常见安全问题
  • JavaScript基础(三)
  • 一文讲清楚React Hooks
  • 解决问题的“测地线”:关于第一性原理与其他系统思考框架
  • RocksDB 与 ZenFS:原理、特性及在科研与工程中的应用初步探索
  • 使用Arthas监听Spring代理对象
  • 从UI设计到数字孪生实战部署:构建智慧教育的在线学习分析平台
  • Java观察者模式实现方式与测试方法
  • Constants
  • SSM 框架整合教程:从环境搭建到 CRUD 实现
  • html页面,一个控件,可以粘贴图片和样式,一直按enter键会将下面内容推下去
  • OrCAD 24.1补丁005中文界面切换指南
  • QT Android 如何打包大文件到目录下?
  • 【Pandas】pandas DataFrame from_records
  • Android开发中几种scope的对比
  • ClickHouse JSON 解析
  • Kubernetes Dashboard UI 部署安装
  • stm32计时的两个方法
  • HarmonyOS学习记录4
  • 基于U-net的高阶心音信号去噪系统设计与实现