文章目录

  • let
    • 1.ES6简介
    • 2.let关键字
      • 2.1 不存在变量提升
      • 2.2 暂时性死区
      • 2.3 不允许重复声明
    • 3.块级作用域
      • 3.1 为什么需要块级作用域
        • 缺点1:内部变量可能会覆盖外层的变量
        • 缺点2:for循环中的计数变量泄露为全局变量。
      • 3.2 ES6块级作用域
    • 4.案例
  • const
    • 1.基本用法
      • 1.2 必须初始化
      • 1.3 一般变量名大写
      • 1.4 也有块级作用域
      • 1.5 不存在变量提升
      • 1.6 不可重复声明
      • 1.7 对于数组和对象中的元素进行修改,不算对常量的改变
  • 变量的解构赋值
    • 1.什么是解构
    • 2.数组解构
      • 不完全解构
    • 3.对象解构赋值
      • 方法解构
      • 注意点
    • 4.字符串解构
    • 5.函数参数的解构赋值
    • 6.用途
      • 6.1 交换变量的值
      • 6.2 从函数中返回多个值
      • 6.3 函数参数的定义
  • 函数扩展
    • 1.函数参数的默认值
      • 作用域
    • 2.rest参数
      • 2.1 基本用法
      • 2.2 rest参数和arguments对象的区别
    • 3.箭头函数
      • 3.1 定义
      • 3.2 语法
      • 3.3 其他写法
      • 3.4 箭头函数中this指向

let

1.ES6简介

ECMA是一个标准 JavaScript是ECMAScript的实现。

ES6是ECMAScript的一个版本,是2015年发布的,ES2015.

2.let关键字

ES6新增的关键字,用来声明变量。用法类似于var,但是所声明的变量,只在let所在的代码块有效。

var a = [];for (var i = 0; i < 10; i++) {a[i] = function(){console.log(i);}
}
a[6](); //10

var定义的变量遇到for循环的大括号是不会形成作用域的。所以在上面代码调用时,调用的是一个全局的变量。

    var a = [];for (let i = 0; i < 10; i++) {a[i] = function () {console.log(i);}}a[6](); //6

以上代码中,i是使用let声明的,当前的i只在本轮的循环中有效。每一个循环中的i其实都是一个新的变量。所以输出的是6.

for (var i = 0; i < 3; i++) {var i = "abc";console.log(i); //执行一次abc}// 循环一次时输出abc,i++时,i已经变成abc,无法i++,i就变成NaN,直接从循环跳出
    for (let i = 0; i < 3; i++) {let i = "abc";console.log(i);}

结果:输出3次abc。

原因:在代码块中的变量i与for循环中的变量i不在用一个作用域。

2.1 不存在变量提升

var 存在变量提升。即变量在声明之前使用时,值为undefined。js会将声明语句放在所有js代码之前执行。

console.log(a);
var a = 10;
//相等于
var a;
console.log(a);
a = 10;
console.log(a);
let a = 10;

结果:提示错误Cannot access 'a' before initialization

2.2 暂时性死区

 var tmp = 123;if(true){tmp = "abc";let tmp;console.log(tmp);}

结果:提示错误Cannot access 'a' before initialization

使用变量时,会先寻找同一作用域下的变量。以上代码中,tmp=abc会优先寻找到下面的let tmplet tmp不存在变量提升,所以提示错误。

总结:在代码块中,使用let命令声明变量之前,该变量都是不可用的状态,在语法上,称为“暂时性死区”

2.3 不允许重复声明

let不允许在相同的作用域中,重复声明同一个变量。

//Identifier 'a' has already been declared
let a = "yasuo";
let a = "jianhao"
console.log(a);
//Identifier 'a' has already been declared
function show(a){let a = 10;
}
show(100);

以上代码中,函数的形参a与函数内部的a作用域相等,所以会报错。

 function show(a){{let a = 10;}}show(100);

3.块级作用域

3.1 为什么需要块级作用域

ES5 只有全局作用域和局部作用域(函数作用域),没有块级作用域。

缺点1:内部变量可能会覆盖外层的变量

var date = new Date();
function f(){console.log(date);if(false){var date = "今天是个好日子"  }
}
f();//undefined

上面案例中,if代码块外部原意为使用外层的date,内部使用内部的date。但是函数执行后,结果却为undefined,原因是存在变量的提升。导致内部的date覆盖了外部的date变量

缺点2:for循环中的计数变量泄露为全局变量。

    var hello = "hello"for (var i = 0; i < hello.length; i++) {console.log(hello[i]);}console.log(i);

以上案例中,for·循环中的变量i只是用来作为计数使用,但是for循环执行完成后,它没有消失,而是作为全局变量仍然存在。以后可能不会再使用,造成资源的浪费。

3.2 ES6块级作用域

function show(){let a = "亚索";if(true){let a = "剑豪";{let a = "孤儿索"}console.log(a);}console.log(a);}show()

块级作用域下的变量不会对外层的变量造成影响,同时支持多层嵌套。

if(true)let  a = "亚索";console.log(a);

ES6的块级作用域必须有大括号,所以使用if判断时,不可以省略大括号。

4.案例

<ul><li>诺手</li><li>狼人</li><li>亚索</li><li>卡莎</li><li>猫咪</li>
</ul>
 var lis = document.querySelectorAll("li");// for (var i = 0; i < lis.length; i++) {//     lis[i].dataset.index = i;//     lis[i].onclick = function(){//         alert(this.dataset.index);//     }// }for (let i = 0; i < lis.length; i++) {lis[i].onclick = function(){alert(i);}}

以上案例,使用let关键字实现点击li,弹出相当元素的下标。

const

1.基本用法

const也是用来声明变量的,不过它声明的是一个只读的常量。一旦声明,值不可修改。

const PI = 3.1415926;
// alert(PI);
PI = 3.14;
//Assignment to constant variable 为一个常量赋值了
alert(PI)

1.2 必须初始化

const PI;
PI = 3.1415926;
alert(PI);
//Missing initializer in const declaration  const声明中缺少初始化式

因为const声明的变量的值不可修改,所以,const一旦声明变量,则必须初始化。

1.3 一般变量名大写

规范。

1.4 也有块级作用域

const与``let`相同,只会在声明的所在代码块作用域内生效。

{const PI = 3.1415926;}
alert(PI);
//报错

1.5 不存在变量提升

alert(PI);
const PI = 3.1415926;
//报错

1.6 不可重复声明

 var PI = "3.14";const PI = 3.1415926;

1.7 对于数组和对象中的元素进行修改,不算对常量的改变

const变量保存的变量指向的值的内存地址。对于简单的数据(数值,字符串,布尔值)值保存在变量指向的内存地址。

对于复合数据类型,变量指向的内存地址,只是该对象的地址,其中的内容发生变化不会使该对象的内存地址发生变化。

const obj = {name:"亚索"
}
obj.name = "疾风剑豪";
console.log(obj.name);
//疾风剑豪
const obj = {name: "亚索"}obj.name = "疾风剑豪";obj = {name: "孤儿索"}console.log(obj.name); //Assignment to constant variable.为一个常量赋值了

变量的解构赋值

1.什么是解构

ES6中,按照一定的模式,从数组或对象中提取值,对变量进行赋值。这个过程叫做解构赋值。

2.数组解构

const arr = ["诺手","蝎子","劫","EZ","女坦"];
let nuo = arr[0];
let lailai = arr[1];
let jie = arr[2];
let ez = arr[3];
let f = arr[4];
//ES6
let [nuo,lailai,jie,ez,f] = ["诺手","蝎子","劫","EZ","女坦"];

本质上,这种写法属于“模式匹配”。只要赋值号两边的模式相同,左边的变量就会被赋予对应的值。

let [a,[b,c]] = [1,[2,3]];
let [a, b] = [1, 2, 3];
console.log(a); //1
console.log(b); //2

解构失败时,变量的值为undefined。

let [a,b] = [1];
console.log(a);//1
console.log(b);//undefined

不完全解构

let [a,b] = [1,2,3];
console.log(a);//1
console.log(b);//2

赋值号两边不是完全相等的。

3.对象解构赋值

const obj = {name:"亚索",skill:"hasakei"
}
let {name,skill} = obj;

变量名与属性名相同,才能取到正确的值。

如果想要自定义变量名,则用:进行修改。

let {name:n,skill} = obj;
console.log(n);

方法解构

var obj = {r:function(){console.log("狂风绝息斩");},e:function(){console.log("e去不复返");}
}
const {r,e} = obj;
r(); //狂风绝息斩
e(); //e去不复返
     const {log} = console;log(log);const obj = {p: ["hello", {y: "world"}]}let {p: [a, {y: b}]} = obj;console.log(a); //helloconsole.log(b); //world

注意点

let x;
{x} = {x:1};

以上代码是错误写法。{x}前面如果没有let const的变量声明的关键字,则js会将其视为代码块。

如果需要提前声明变量,则需要将解构语句用小括号包裹起来;。

let x;
({x} = {x:1});
console.log(x); //1

数组本质也是特殊的对象,也可以对数组进行对象属性的解构。

 const arr = ["诺手","蝎子","劫","EZ","女坦"];let {length,0:first,4:last} = arr;console.log(first);//诺手console.log(last);//女坦

4.字符串解构

const str = 'hello';
let [a,b,c,d,e] = 'hello';
let {length} = 'hello';//5

类数组的对象都有一个length属性,我们可以对这个属性进行解构赋值。

5.函数参数的解构赋值

function add([x,y]){return x+y;
}
let sum = add([1,2]);
console.log(sum);//3

以上案例,函数add的参数表面上一个数组,但是在传入参数的那一刻,数组参数会被解构成变量x和与y.

6.用途

6.1 交换变量的值

let a = 1;
let b = 2;
// let tmp = a;
// a = b;
// b = tmp;
[a,b] = [b,a];

6.2 从函数中返回多个值

function fn(){return [1,2,3];
}
let [a,b,c] = fn();
function fn2(){return {name:"yasuo",age:"25"}
}
let {name,age} = fn2();

6.3 函数参数的定义

function fn({a,b,c}){console.log(a);//1console.log(b);//2console.log(c);//3
}
fn({c:3,b:2,a:1})

函数扩展

1.函数参数的默认值

ES6之前,不能为函数的参数设置默认值,只能在代码中进行判断

function show(a,b){if(typeof b === "undefined"){b = 0;}console.log(a,b);
}
show(1);

ES6的写法

function show(a,b=0){console.log(a,b);
}
show(1);

设置默认值的参数应该在函数的最后面,否则默认值设置是无效的。

 function show(a=0,b){console.log(a,b);}show(1)//1 undefined

函数的length属性为函数的参数个数。若设置了默认值,length的计数中是不计算设置了默认值的参数的。

作用域

一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。

等到初始化结束,这个作用域就会消失。

var a = 1;
function fn(a,b = a){console.log(b);
}
fn(2)//2
let a = 1;
function fn(b = a) {let a = 2;// console.log(a);//2console.log(b); //1
}
fn();

函数调用中,(b=a)是一个单独的作用域,a变量不存在,则会去外部寻找。

2.rest参数

2.1 基本用法

        function add(...v){for (var i = 0; i < v.length; i++) {console.log(v[i])}}add(2,1,3)//2 1 3

rest参数必须是最后一个正式参数。

        //错误写法function add(...v,a){}

2.2 rest参数和arguments对象的区别

arguments对象不是一个数组,只是一个类似数组的对象。不能使用数组的方法。

rest参数是一个真正的数组,所以可以使用数组的方法

function sort(...v){// return arguments.sort(); 报错arguments.sort is not a functionreturn v.sort()//ƒ sort() { [native code] }
}
console.log(sort(3,1,4,8));

3.箭头函数

3.1 定义

箭头函数是对于匿名函数表达式的一种简写方法。

3.2 语法

//普通匿名函数
var a = function(a,b){}
//箭头函数
//()形参的位置
//=> 箭头函数的标志
//{} 函数代码块
()=>{}
var fn = function(a,b){console.log(a+b);console.log("我是普通匿名函数");
}
fn(10,20);
var fn2 = (a,b)=>{console.log(a+b);console.log("我是箭头函数");
}
fn2(10,20);

3.3 其他写法

如果箭头函数只有一个形参,则可以省略小括号。

var fn = a =>{console.log(a);
}

如果只包含一个语句,则省略{}和return。

var fn = a => a*a

箭头函数中没有arguments对象。

var fn = a => {console.log(arguments.length);//报错arguments is not defined
}

3.4 箭头函数中this指向

箭头函数内部的this是由上下文确定的。

它会找到自身定义的位置中的this值,作为自身的this。

let div = document.querySelector("div");div.onclick = function(){console.log(this);//div}div.onclick = ()=>{console.log(this);}//windowdiv.onclick = function(){let fn = function(){console.log(this);}fn();//windowlet fn = ()=>{console.log(this);}fn();//div}let obj = {name:"亚索",fn:function(){console.log(this);},fun:()=>{console.log(this);}}obj.fn();//objobj.fun();//window

2021-02-24let和const,变量的解构赋值,函数扩展相关推荐

  1. ES6 | let 关键字 + const关键字 + 箭头函数 + rest参数 + 扩展运算符 ... + Symbol + 迭代器 + 生成器 + 变量的解构赋值 + 模板字符串

    目录 ECMASript 相关介绍 ECMASript 6 新特性 let 关键字 const关键字 变量的解构赋值 模板字符串 简化对象写法 箭头函数 => 参数默认值 rest参数 扩展运算 ...

  2. 【ES6】变量的解构赋值

    [ES6]变量的解构赋值 一.什么叫解构赋值? 二.解构赋值有哪些分类?写法? 1)对数组的解构赋值 2)对对象的解构赋值 3)对字符串的解构赋值 4)对数值和布尔值的解构赋值 5)对函数参数的解构赋 ...

  3. ECMAScript6变量的解构赋值

    ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring) ###数组的解构赋值 //ES5 //var a = 1; //var b = 2; //va ...

  4. json解析 子类和父类同名属性如何赋值_想学变量的解构赋值?看完这一篇就够了...

    序言 ES6允许按照一定模式从数组和对象中提取值,然后对变量进行复制,这被称为解构(Destructuring) 数组的解构赋值 基本用法 像上面的例子,可以从数组中提取值,按照对应位置对变量赋值,这 ...

  5. ES6的新特性(3)——变量的解构赋值

    变量的解构赋值 数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). let a = 1; let b = 2; le ...

  6. Vue2.x—理解vuex核心概念action(使用到ES6的变量的解构赋值)

    Action Action 类似于 mutation,不同在于: Action 提交的是 mutation,而不是直接变更状态. Action 可以包含任意异步操作. 让我们来注册一个简单的 acti ...

  7. ECMAScript 6入门 - 变量的解构赋值

    定义 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 解构赋值不仅适用于var命令,也适用于let和const命令. 解构赋值的规则是,只要 ...

  8. es6—变量的解构赋值

    数组的解构赋值 /* 1.变量的解构赋值: * 数组的元素是按次序排列的,变量的取值由它的位置决定: * 从数组和对象中提取值,对变量进行赋值,这被称为解构; * 属于"模式匹配" ...

  9. ES6学习笔记二 新的声明方式和变量的解构赋值!

    新的声明方式 在ES5的时候,我们只有一个声明方式,var!但是在es6中,声明进行了扩展,我们加上ES5的var的申明方式,我们有了三种声明方式: var:它是variable的简写,可以理解成变量 ...

最新文章

  1. Python函数细节:多数量参数、强制参数传递、返回多值、匿名/内联函数
  2. CoreJava学习3——​基本类型的包装类
  3. 获取验证码canvas
  4. 每天一个Linux命令(17)--whereis命令
  5. 诺基亚正式收购阿朗:物联网时代再出发
  6. Web报表工具FineReport二次开发JS之字符串
  7. (转)查理·芒格:光靠已有的知识,你走不了多远
  8. (超详细)算法学习:STL和基本数据结构
  9. Java进销存管理系统
  10. mysql中怎么防止数据丢失
  11. ios开发——实用技术篇Block/KVO/通知/代理
  12. 安卓之父带来一款超长“带鱼”手机
  13. 服务器端口不稳定怎么解决,网络不稳定的原因分析,以及解决方法
  14. 杨卫华:新浪微博的架构发展历程(转)
  15. python写的程序怎么打包手机app_Python Kivy(App开发) Windows安装打包步骤
  16. 李白号称诗仙,为何七律连有些二流诗人都敌不过?
  17. 迄今为止最深刻分析家乐福的文章—从商业模式、公司制度、公司文化三方面
  18. centos 6.4 163yuan
  19. HDLBits-Circuits学习小结(六)移位寄存器(shift registers)
  20. Arduino与震动马达模块握手

热门文章

  1. BK7231U,WIFI(802.11b/g/n2.4G)+BLE5.2双模
  2. 澳鱼类大规模死亡 河面漂满鱼尸引发生态灾难担忧
  3. 类小米模式的高负载单品类商城开发实践
  4. 解决忽略无效分布的警告WARNING: Ignoring invalid distribution
  5. github-readme里添加动图
  6. Android调用系统拍摄视频
  7. 统计信号处理基础 习题解答3-6
  8. 处理json字符串中双引号转义
  9. 【人工智能】确定型推理
  10. html如何判断文本框是否为空,javascript怎么判断文本框是否为空?