资讯专栏INFORMATION COLUMN

ES6学习笔记(一)--------------------------------------le

Carson / 660人阅读

摘要:命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。因此,将一个对象声明为常量必须非常小心。不可变的只是这个地址,即不能把指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。

let和var一样也是用来定义变量,不同之处在于let是块级作用域,只在所定义的块级作用域中生效,一个花括号便是一个块级作用域

{var a="我是var定义的";let b="我是let定义的"}
console.log(a);  //我是var定义的
console.log(b); //b is not defined

可以看出let定义的变量在全局作用域内并没有生效

如果我们在全局作用域中定义,试一下看在函数或者流程控制语句中是否会输出

let a="我是let定义的"
var b=0;
while(b<5){b++;console.log(a)}//⑤我是let定义的变量
if(true){console.log(a)}//我是let定义的变量

我们发现这样可以输出

如果我们反向来一下呢

for(let i=0;i<5;i++){
let a="流程控制语句花括号中的let";
var b="流程控制语句花括号中的var";
console.log(i)}
//0,1,2,3,4
console.log(a);
//a is not defined
console.log(b);
//流程控制语句中的var
for(var j=0;j<1;j++){
console.log(j)}
// 0
console.log(j);
//1

我们发现let定义的变量不会被提升,只要有块级括号存在,它就只在该块级中有意义

如果在函数中呢

function test(){console.log(a)}() //报错

我们发现并不能输出

我们可以得出结论,流程控制语句中的变量均属于全局变量,但是在流程控制语句中的括号中定义则为块级,不会提升为全局变量

for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个多带带的子作用域

for(let i=0;i<3;i++){
let i="abc";
console.log(i)}
//abc,abc,abc

let在for循环声明的变量每一次循环的值都会被引擎内部记下,但是var声明的变量则会刷新覆盖掉上一次的值

var a=[];
for(var i=0;i<10;i++){
a[i]=function(){return i};}
console.log(a)//[f,f,f,f,f,f,f,f,f,f]
a.forEach((e)=>{console.log(e())})
//⑩10

我们可以看出,这种方式其实将未执行的函数push进数组了,当每次调用时候发现此刻的i早已经被循环覆盖掉,最终输出都为此刻的i值10

var a=[];
for(let i=0;i<10;i++){
a[i]=function(){return i};}
console.log(a)//[f,f,f,f,f,f,f,f,f,f]
a.forEach((e)=>{console.log(e())})
//0,1,2,3,4,5,6,7,8,9

但是对于let声明的变量,每一次引擎都会自动存储记录i的值,而不会覆盖掉,因此每次输出都是push当时的i值

let不存在变量提升,只有在定义后再使用才不会报错

console.log(a);var a=1;//undefined
console.log(b);let b=2;//报错

let具有强制性绑定变量的能力,原先var声明的变量,当被let重新声明的时候会被强制性绑定,原先var声明的所有被let所管辖的块级作用域里的变量均被let强制为自己声明的值,形成暂时性死区,let所处块级作用域中let声明之前的该变量均报错

var a=1;
{console.log(a);
let a=2;}
//a is not defined
var a=1;
{let a=2;
console.log(a);//2
};
console.log(a)//1
var a=1;
console.log(a);//1
{let a=2;
console.log(a);//2
};

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

{var a=0;
let a=1;
console.log(a)}//报错
{let a=0;
var a=1;
console.log(a)}//报错
{
let a=2;
let a=3;
console.log(a)}//报错
{let a=2;
console.log(a);
let a=3;}//报错

上面的最后一个例子可以看出当再次声明该变量之前调用的变量都会炸掉

我们可以看到let声明的变量可以引用块级作用域外面的函数

let a=f();
function f(){
return 1
}
console.log(a)// 1
{let a=f();
console.log(a)// 1
function f(){
return 1
}

const声明的变量为永恒变量,不能更改,而且声明以后必须初始化

const a;//报错
const b=1;
b=2//报错

const的作用域与let命令相同:只在声明所在的块级作用域内有效。
const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
const声明的常量,也与let一样不可重复声明。
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

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

const foo={};
foo.prop=123;
console.log(foo.prop)//123

常量a是一个数组,这个数组本身是可写的,但是如果将另一个数组赋值给a,就会报错。

const a=[];
a.push(1);
console.log(a)//[1]
console.log(a.length)//1
a=[]//报错

再来验证以下引用

var a=1;
b=a;
console.log(b);//1
a=2;
console.log(b)//1
b=3;
console.log(a)//2

可以看出var定义的变量,b=a时候,是直接复制了一份a,并不是a的引用

let a=1;
b=a;
console.log(b);//1
a=2;
console.log(b);//1
b=3;
console.log(a);//2
console.log(b);//3
var b=4;
console.log(b)//4

可以看出let也一样
const也是复制一份

const a=1;
b=a;
console.log(b);//1
b=3;
console.log(a);//1
console.log(b);//3
var b=4;
console.log(b)//4

还有很多不甚明朗的地方,各位大佬可以指点一二,互相学习,加深理解

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88349.html

相关文章

  • es6学习笔记-字符串的扩展_v1.0_byKL

    摘要:学习笔记字符串的扩展字符的表示法允许使用的形式表示一个字符,但在之前,单个码点仅支持到,超出该范围的必须用双字节形式表示,否则会解析错误。返回布尔值,表示参数字符串是否在源字符串的头部。,是引入了字符串补全长度的功能。 es6学习笔记-字符串的扩展_v1.0 字符的Unicode表示法 JavaScript 允许使用uxxxx的形式表示一个字符,但在 ES6 之前,单个码点仅支持u00...

    JaysonWang 评论0 收藏0
  • Json-path学习笔记<>

    摘要:简介是用于结构化数据序列化的一种文本格式,包含种基础类型字符串,数字,布尔和和两种结构类型对象和数组。对象是一个由零或者多个名值对组成的无序集合,其中名值对中名是字符串类型,值则可以是字符串,数字,布尔,,对象或数组类型。 Json JavaScript Object Notation (JSON)是一个轻量级的,基于文本的,跨语言的数据交换格式。它从ECMAScript编程语言标准(...

    Vicky 评论0 收藏0
  • Python 进阶之路 (十) 再立Flag, 社区最全的itertools深度解析(下)

    摘要:将每一行作为返回,其中是每行中的列名。对于每一行,都会生成一个对象,其中包含和列中的值。它返回一个迭代器,是迭代结果都为的情况。深度解析至此全剧终。 简单实战 大家好,我又来了,在经过之前两篇文章的介绍后相信大家对itertools的一些常见的好用的方法有了一个大致的了解,我自己在学完之后仿照别人的例子进行了真实场景下的模拟练习,今天和大家一起分享,有很多部分还可以优化,希望有更好主意...

    tomorrowwu 评论0 收藏0
  • python 学习笔记 关于切片

    摘要:我们还可以给切片进行命名,有名字的切片,显然更具有可读性。对切片赋值时,赋值符号右侧必须是一个可迭代对象,即使这个对象只包含一个元素,否则会提示错误。注以上内容主体来自于流畅的一书中切片和切片原理 切片是python中列表(list)、元组(tuple)、字符串(str)等序列类型都支持的一种操作,但实际上切片的功能比人们所想象的要强大的多。 切片区间为什么会忽略最后一个元素 当只有...

    jerryloveemily 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<