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

9.15 ES6-变量-常量-块级作用域-解构赋值-箭头函数

变量Let

ES5作用域: 全局作用域,函数作用域(局部作用域) ES6新增 let: 定义变量

  • 定义块级作用域 {}

  • 在同一块级作用域不能重复声明

const: 定义常量

  • 声明必须赋值

  • 不允许更改

块级作用域

花括号包括起来的就是块,就是块语法,大家比较常见的可能是if(){},for(){}这都是语法块,块级作用域 特点1: 同一个代码块中不允许声明同名的变量

let a = 10;
var b = 100;
let a = 100;
console.log(a);

注意2: let声明的是一个变量,变量是可读可改的,能修改

let a=200; 
a = 'hello'
console.log(a) // hello

注意3: let 声明的变量, 不存在 声明前置

console.log(c);// 报错
let c = 5;
console.log(c);

注意4: 通过 let 声明的变量只在 let 命令所在的代码块内有效

ES 6中变量的作用域: 块级作用域 ----- {}

if(true){let a=12
}
alert(a);// 报错,a只在上面的语法块中才有用

案例:块级作用域怎么用

<script>
window.onload=function(){var aBtn=document.getElementsByTagName('input');for(var i=0;i<aBtn.length;i++){aBtn[i].index=i; // 存储i下标值aBtn[i].onclick=function(){console.log(i); // 每次打印出来的都是3console.log(this.index); // 0,1,2}}
} 
</script>
<input type="button" value="按钮1"/>
<input type="button" value="按钮2"/>
<input type="button" value="按钮3"/>
<script>
for(let i=0;i<aBtn.length;i++){aBtn[i].onclick=function(){console.log(i); // 0,1,2}
}
</script>

暂时性死区: 在代码块内, 使用 let 声明变量之前, 该变量是不可用的

常量const

const 用于声明一个只读的常量

注意一:同一个代码块中不允许声明同名的变量

const a=100;
const a=200; // 报错,不能重复定义
console.log(a);

注意二:const声明的是一个常量,常量只读不改

const PIM = 3.14;
// PIM = 3;// 报错
console.log(PIM);

注意三:块级作用域,只在花括号里面有效

if(true){const a=12
}
alert(a);//报错

注意四: 如果 const 保存的是数组/对象/函数等 空间的地址时, 只能保证 所保存的地址不变, 地址中的值, 无法控制.

let numArr = [9, 5, 2, 7];// [9,5,2,7]
const arrP = numArr;
numArr[0] = 99;
console.log(arrP);// [99,5,2,7]
console.log(numArr); // [99,5,2,7]

面试题:let,const,var的区别
![[2dfb7dec-5e46-4b03-b2eb-9293ab676441.png]]

解构赋值【拆解架构,重新赋值】

ES 6允许按照一定的模式, 从数组和对象中提取值, 然后对变量进行赋值. 解构赋值分为数组的解构赋值、对象的解构赋值、字符串的解构赋值、数值和布尔值的解构赋值、函数参数的解构赋值、函数的参数的解构赋值

解构赋值的本质: 模式匹配. 只要 = 两侧的模式相同, 左侧的变量就可以被赋予对应的值.

数组的结构

  1. 原始方法的解构赋值
let arr=[1,2,3];
let a=arr[0];
let b=arr[1];
let c=arr[2];
console.log(a,b,c)
  1. 使用解构赋值
// 方法一
{let [a,b,c]=[1,2,3];console.log(a,b,c)
}
// 方法二
{let a,b,c;[a,b,c]=[1,2,3];console.log(a,b,c)
}
// 错误示范
let [a,b,c,d];
[a, b, c, d] = [9, 5, 2, 7];
console.log(a, b, c, d);
  1. 不完全解构
let arr = [4, 7, 9, 3];
let [num1,num2] = arr;
let [,num1,num2] = arr;
let [num1,num2,...num3] = arr;
let [num1, , , num2] = arr;
console.log(num1, num2);
  1. 解构失败
let [aName] = [];
console.log(aName);// undefined
  1. 不定长度的解构赋值
let color = ['red','green','blue','pink','black','white'];
let [col1,...col2] = color;
console.log(col1,col2);

对象的解构赋值

注意:对象的解构赋值与数组有一个重要的不同, 数组的元素是按顺序排列的, 变量的取值由先后位置决定, 而对象的属性没有次序, 只要键名匹配成功即可完成赋值

  1. 变量名与键名一致(对象的字面量表示法)
let {brand, price} = {brand: '宝马', price: 740};
let {price,brand}={brand:'宝马',price:250};
console.log(brand, price);
  1. 变量名与键名不一致
let {brand: a, price: b} = {brand: '宝马', price: 740};
console.log(a, b);
  1. 同一个对象给六个变量赋值
let dataObj = {codeNum: '200',codeMsg: 'ok',data: [{name: '刘德华', age: 60},{name: '刘德华', age: 60}]
};
let {codeNum, data, data: listObj, data: [dataPer], data:[{name, age}]} = dataObj;

注意:已经声明过的变量, 用于解构赋值时要特别小心. {} 很容易被系统识别

字符串的解构赋值

字符串能够使用解构赋值的原因是: 字符串时特殊的数组(字符串能够被转换成一个类似数组的对象)

let [a, b, c, d, e] = "Hello";
console.log(a, b, c, d, e);

解构赋值的用途

  1. 交换变量的值
let a = 3, b = 5;
[a, b] = [b, a];
console.log(a, b);
  1. 从函数内部返回多个值
let {dataObj} = {code: 200, msg: 'ok', dataObj: ['jack','rose','bob','小明']}; 
console.log(dataObj);
  1. 可以迅速提取一个对象中的方法;
let {floor, random, sin} = Math;
console.log('======');
console.log(Math.floor(Math.random() * 256)); // 原来的操作
console.log(floor(random() * 256));  // 现在的操作

箭头函数

箭头函数也称为也称为胖箭头函数; 箭头函数的基本语法:()=>{}

定义箭头函数

  1. 通过事件直接调用匿名函数
window.onload=function(){alert('abc');
}
window.onload=()=>{alert('abc')
}
  1. 通过赋值的方式创建函数
let show=function(){alert('abc');
}
let show=()=>{alert('abc');
}
show();
  1. 可以传参的箭头函数
let show=function(a,b){alert(a+b);
}
show(12,6);
let show=(a,b)=>{alert(a+b);
}
show(12,6);

案例:给下面数组排序

let arr=[12,5,3,67,23,99,14,25];// 正序排序
// 普通方法
arr.sort(function(a,b){return a-b;
});
// 改写为箭头函数
arr.sort((a,b)=>{return a-b
);
alert(arr);
但是这里面几个注意事项:

A. 如果只有一个参数,()可以省

B. 如果只有一条语句,{}可以省

C. 只有一条语句的时候,并且使用return进行返回,不仅{}可以省略,return也可以省略

D.在箭头函数中不能使用arguments,使用展开运算符

注意一:如果只有一个参数,()可以省

// 求一个数的平方是多少
let show=function(a){alert(a*2) 
}
// 简写成箭头函数
let show=(a)=>{alert(a*2)
}
// 强调:只有一个参数,就可以省略(),强调一下,只有一个多了不行,少了也不行
let show=a=>{alert(a*2)
}
show(12);

注意二:如果只有一条语句,{}可以省略

let show=a=>alert(a*2) // 意思很明白:进去是a,吐出来是2*2
show(12);

注意三:如果只有一条语句,并且是用return进行返回,不仅{}可以省略,return也可以省略

let show=a=>(a*2) // 意思很明白:进去是a,吐出来是2*2
alert(show(12));

案例:添加一个函数,功能2秒钟之后改变页面的背景颜色

注意四:不能使用arguments

function gets(){console.log(arguments);
}
let gets=()=>{console.log(arguments);
}
gets(12,34,23,4);

箭头函数使用注意事项: 函数体内 this 是定义时所在的对象, 不再是使用时所在的对象(此时 this 变成一个静态的值了)

箭头函数的默认值

  1. 参数的默认值不是传值, 而是每次都会重新计算
let x = 100;
function fun2(a = x + 1) {console.log(a);
}
fun2();// 101
x = 1000;
fun2();// 1001
  1. 一般设置默认值的参数应该是函数的尾参数
function fun3(a, b = 3) {console.log(a, b);
}
fun3(5);

获取剩余(rest)参数 【…args 】,等同于ES5中的arguments

ES5中的arguments和ES6中rest剩余参数的区别是:argument中是伪数组,rest中是真数组

function total(...args){// ES5:// console.log(arguments)  //伪数组// args: 真数组console.log(args instanceof Array);console.log(args);
}

其实就是展开运算符 + 变量名

show=(a,b,...args)=>{alert(a);alert(b);alert(args)
}
show(12,15,23,43,11);

注意:…args 必须是最后一个行参 箭头函数没有arguments,如果箭头函数的外层又普通函数,那么arguments会获取外层普通函数的实参

函数的两个属性

ES6里面提供了函数的两个属性,分别是:length和name

length: 获取数组中参数的长度 但是,如果参数指定了默认值,函数的length属性将返回没有指定默认值的参数个数

function fun(a, b,c,d) {
}
console.log(fun.length);

Name: 函数的name属性,返回该函数的函数名

function fun1() {
}
console.log(fun1.name);

注意一:使用匿名函数表达式的方法定义的函数,它的name属性值就是变量的名字

let fun2 = function(argument){
}
console.log(fun2.name) //fun2

注意二:函数声明的优先级高于变量名

let superFun3 = function fun3(argument){
}
console.log(superFun3.name) //fun3
// 调用的时候变量名的优先级高

箭头函数的this指向

  1. 箭头函数的this指向
    箭头函数的this指向 是 父级程序的this指向 如果没有父级程序 或者 父级程序没有指向 箭头函数的this指向是window
<button>登陆</button>
<script>var btn = document.querySelector('button');// 1. 匿名函数绑定的事件处理函数 this指向默认是事件源 也就是div标签对象btn.addEventListener('click' , function(){console.log(this); // btn元素本身})// 2. 箭头函数的this指向,是父级程序的this指向,下面的箭头函数没有父级程序,所以this指向是windowbtn.addEventListener('click' , ()=>{console.log(this); // window对象})
</script>
  1. 对象中定义的函数 和箭头函
var obj={name:18,sayhi:()=>{console.log(this);},eat:function(){console.log(this);}
}
obj.sayhi();
obj.eat();
  1. 在箭头函数中不能通过函数【call/apply/bind】方法,修改this指向

call:函数调用.call(参数1,参数2,参数3…)

参数1:要改变的指向 之后的参数2,参数3…是原始函数需要的数据

apply:函数调用.apply(参数1,[参数2,参数3…])

参数1:要改变的this指向 之后的所有参数以数组的形式赋值 原始函数需要的数据

总结:call和apply执行程序的原理、结果都完全一致,只是给原始函数赋值参数的语法形式不同

bind:bind(参数1,参数2,参数3…)

参数1:新的this指向 之后所有的参数 参数2,参数3…都是原始函数需要的参数数据

var obj = {name: 18,sayhi: () => {console.log(this);},eat: function () {console.log(this);}
}
obj.sayhi();
obj.sayhi.call(111);
obj.eat();
obj.eat.call(111);

总结:箭头函数没有this,它的this取决于作用域链上的this,它不可以通过 bind 等方法改变this 指向。

不能通过new关键字调用

javascript函数有两个内部方法:Call和Construct.

当通过new调出函数时,执行Construct方法,创建一个实例对象,然后再执行函数体,将this绑定到实例上。

当直接调用的时候,执行Call方法,直接执行函数体。 箭头函数并没有Construct方法,不能被用作构造函数,如果通过new的方式调用,会直接报错。

let foo1 = () => {};
let foo2 = new foo1(); //TypeError: foo1 is not a constructor

is not a constructor

没有原型

由于不能使用new调用函数,所以也没有构建原型的需求,于是箭头函数也不存在prototype这个属性。

let foo = () => {};
console.log(foo.prototype); //undefined

总结:

  • 没有this,捕捉其所在的上下文的this值,作为自己的this

  • 不能绑定arguments, 用rest参数 … 解决

  • 箭头函数没有原型属性


文章转载自:

http://ofqglQTV.qwzpd.cn
http://K0w6vIJb.qwzpd.cn
http://vbY0GgPx.qwzpd.cn
http://Zru9Cgbf.qwzpd.cn
http://ABJjMIFn.qwzpd.cn
http://32TZyIZO.qwzpd.cn
http://NASPTz4Q.qwzpd.cn
http://EXZXRzy2.qwzpd.cn
http://bKEfh4gE.qwzpd.cn
http://39w5gJyY.qwzpd.cn
http://wslGEe7K.qwzpd.cn
http://7saocZJS.qwzpd.cn
http://Za4Bu0wY.qwzpd.cn
http://SZahK84X.qwzpd.cn
http://hBzlMGeH.qwzpd.cn
http://UOz0rQMb.qwzpd.cn
http://rUotuu2L.qwzpd.cn
http://w9D7ADCQ.qwzpd.cn
http://ybIATxBj.qwzpd.cn
http://f1pFUPLn.qwzpd.cn
http://RBU26BR8.qwzpd.cn
http://RpKwX5Oi.qwzpd.cn
http://GDFosOed.qwzpd.cn
http://yKF9CveW.qwzpd.cn
http://kcPFi4BC.qwzpd.cn
http://9EHrj4FV.qwzpd.cn
http://lxOLiaF3.qwzpd.cn
http://2JcNNXuq.qwzpd.cn
http://e6FBJs3j.qwzpd.cn
http://MbEck7CN.qwzpd.cn
http://www.dtcms.com/a/385160.html

相关文章:

  • 第一章:走进 ES6
  • 9.15 ES6-展开运算符-新增数组字符串方法-字面量对象简写
  • 架构师成长之路-架构方法论
  • 【CTF-WEB】表单提交(特殊参数:?url=%80和?url=@)(通过GBK编码绕过实现文件包含读取flag)
  • Java快速入门基础1
  • 嵌入式跟踪宏单元ETM(Embedded Trace Macrocell)
  • [免费]基于Python的Django商品二手交易平台【论文+源码+SQL脚本】
  • 「Memene 摸鱼日报 2025.9.15」Gemini 应用在美国 iOS 下载量超越 ChatGPT,西湖大学推出 AI 审稿系统
  • 并发和并行区别
  • RabbitMQ 内存管理与性能优化
  • VSCode关闭C或C++项目启动时的自动cmake功能
  • Git 查看状态(git status)、查看提交记录(git log)和提交日志(git reflog)
  • 第五届长城杯(京津冀蒙版)WEB
  • N1 junior 2025 safenotes
  • 2025年09月15日Github流行趋势
  • 通过网络强化增强混合IT环境的安全
  • 【数据结构入门】排序算法(5):计数排序
  • 超大规模多模态交通数据集:320TB+海量数据资源,涵盖行车视频、无人机航拍、第一视角步行骑行与道路监控,助力自动驾驶与智慧交通算法突破
  • [数据结构——Lesson13.冒泡与选择排序]
  • tar-符号连接(软连接)
  • php学习 (第六天)
  • MTK Linux Charger驱动分析(二) - power_supply_core.c
  • 如何做好AI智能体
  • 邻接矩阵幂 A^m 的几何意义
  • PL3381T/PL3383T/PL3384T 12V非隔离降压型芯片(200/300/400mA)
  • 食品科技企业NotCo完成SAP系统升级 构建统一数字化平台
  • LinuxC++项目开发日志——高并发内存池(6-内存回收机制)
  • 数值计算2
  • 硬件 - oring多电源切换
  • RocketMQ-高性能消息中间件的原理