es6 新增变量声明方式
let 与 var
var
var声明的变量拥有全局作用域
或者局部作用域
在全局中声明变量即为全局变量
在函数中声明变量即为局部变量
而var在使用过程中也逐渐暴露出许多问题
var的几大问题
变量提升
使用var来声明变量会出现变量提升的问题,即在声明变量之前就调用变量
console.log(info);//undefined
var info = 10;
出现上面情况其实是非常不好的,因为在声明之前使用的话应该去报出一个错误而不是用一个undefined给这个变量赋值。
这个问题在函数中尤为明显
var info = 10;
function fn1(){
console.log(info);//undefined
var info = 20;
}
fn1();
在循环中的问题
var在循环中的问题也是相当严重
下面我遇到的一个情况
//html中有四个span
var oSpan = document.getElementsByTagName('span');
for(var i = 0 ; i < oSpan.length ; i++ ){
oSpan[i].onclick = function(){
console.log(this);//点击出现 你点的那个span
}
}
我们发现在这时是可以获得点击的元素的
但是我们把this
换成oSpan[i]
时就会出问题
for(var i = 0 ; i < oSpan.length ; i++ ){
oSpan[i].onclick = function(){
console.log(oSpan[i]);//点击出现 undefined
console.log(i);//点什么都是4
}
}
我们这个时候会发现我们已经选取不到事件处理函数中i的瞬时值了。而这又是因为什么呢
我们可以把代码拆开
//拆开for
var i = 0;
oSpan[i].onclick = function(){
console.log(i);
}
var i = 1;
oSpan[i].onclick = function(){
console.log(i);
}
...
var i = 3;
oSpan[i].onclick = function(){
console.log(i);
}
var i = 4;
//在你点击的时候是在页面加载完才调用的函数
上面的会看出来由于var声明的变量是全局变量,所以函数中的变量接收是4
解决办法是在循环中写一个闭包函数,模拟一个块级作用域
for(var i = 0 ; i < 4 ; i++){
oSpan[i].onclick = function(arg){
return function(){
console.log(arg);//出现 0,1,2,3
}
}(i);
}
然而es6给我们提供了更好的声明变量的方式
let
在es6中,let声明的变量是块级作用域
块级作用域是指在{}中间可以有效使用
for(let i = 0; i < 4 ; i++){
oSpan[i].onclick = function(){
console.log(i);
}
}
上面的就可以找到i的瞬时值原因是每个i与下面的都是同一块作用域,而与另几个循环中的函数互不影响。所以每个函数调用的都是与其同一块作用域的i值。
let其他作用
在let声明的变量不可重复声明否者会报错
let b = 10;
let b = 20;//报错
let不会有变量提升这个问题,let会产生暂时性死区
console.log(a);//报错
let a = 20;
顶层对象的属性
在浏览器的顶层对象是window
,在Node环境中是global
。
在es5中顶层的属性与全局变量是等价的
window.a = 1;
a = 2;
console.log(window.a)//2
由于顶层对象的属性与全局变量相关,就会产生许多问题
无法再编译时就提示变量未声明的错误,只有运行在会知道
容易不知不觉的就创建出全局变量,导致顶层对象的属性到处都可以读写,这非常不利于模块化编程
window对象有实体含义,指的是浏览器窗口对象,这样也是不合适的
但是let声明的变量不属于顶层对象的属性
var a = 1;
console.log(this.a);//1
let b = 1;
console.log(this.b);//undefined
const
const
也是es6的声明方式之一
const
声明的变量大多数是做为一个常量,而作为常量时不可对值进行修改,变成只读模式
const INFO = 10;
INFO = 20; //报错
const INFO = 20;//报错
而当const
声明的是一个引用数据类型的时候,引用类型内的值是可以修改的,因为引用类型的值存放在堆中的。修改操作是在堆中进行,而变量储存的是地址,不会被修改,而地址指向的数据已经发生改变,故而const声明的变量的值被修改了
const arr = [1,2,3,4];
arr.push(5);
console.log(arr);//[1,2,3,4,5]
es6 新增变量声明方式的更多相关文章
- ES6 - 基础学习(2): 新的变量声明方式 let 与 const
ES6)新增加了两个重要的 JavaScript 关键字:let 和 const.以前声明变量时只有一种方式:var,ES6对声明方式进行了扩展,现在可以有三种声明方式了. 1.var:variabl ...
- 哟,来看看JS里面变量声明方式
点点点点点点进来.点击此处领取双十一梦想大礼包. 终于被我忽悠进来了?老弟,不骚一下你不往里面点是吧,还想大礼包?想着吧. 今天要说的如题,JS里面变量声明方式.可能一提到这个话题大家能很快的打出来, ...
- javascript中var let const三种变量声明方式
javascript中var let const三种变量声明方式 1.var ①var表示声明了一个变量,并且可以同时初始化该变量. ②使用var语句声明的变量的作用域是当前执行位置的上下文:一个函 ...
- es6系列-变量声明
es6系列所有文章都是阅读阮一峰老师的<ES6标准入门>(第2版)所做的读书笔记.方便日后查阅相关基础知识. git地址: https://github.com/rainnaZR/es6- ...
- 二.ES6新的声明方式
前言: 以前我们在声明时只有一种方法,就是使用var来进行声明,ES6对声明的进行了扩展,现在可以有三种声明方式了. 字面理解ES6的三种声明方式: var:它是variable的简写,可以理解成变量 ...
- JS变量声明方式
在JavaScript中有三种声明变量的方式:const var let const:用于声明常量.注意:定义的变量的时候,必须同时初始化,且其值之后不可以修改. var:最常用的声明变量关键字. ...
- ES6新增变量
声明let let 声明的变量不存在预解析 console.log(flag) var flag = 123 //123 let flag = 456 //undefined let声明的变量不允许重 ...
- 怎样理解"不推荐不使用var的变量声明方式"这句话
答: 因为不使用var声明的变量不会被预解析, 如下: console.log(a); console.log(b); var a = 1; b = 2;
- es6变量声明和解构赋值
/*声明: * 本文内容多为学习借鉴性内容,大部分非原创 * 特别感谢阮一峰的 ECMAScript6 入门,推荐大家学习 */ 一.es5变量声明的不足 1.变量提升和函数声明提升 es5的代码加载 ...
随机推荐
- 你为什么不来了解一下Python?
一.什么是Python Python [1](英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum发明. ...
- iMacros 入门教程-基础函数介绍(2)
imacros 的 pos 参数是什么意思 position的缩写,如果有 2 个以上的元素共用完全相同的属性(比方说同一个小区的同一栋楼),这个 POS 的参数可以借由不同位置来帮助明确定位(也就是 ...
- Badusb 简易制作
Badusb easy_make 0x00 basic knowledge and equip arduino IDE download address: https://www.arduino.cc ...
- matlab中的输出显示函数
matlab中的输出显示函数 在matlab中使用的显示函数有disp.sprintf.fprintf比较常用.下面来介绍一下他们的用法. 1.disp()函数: disp(x)主要是用来输出变量x的 ...
- SSH自动断开后重连的解决方案
注:本文出自博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 本文源链接:https://www.cnblogs.com/chloneda/p/ssh-conn ...
- 疑问:Iterator 遍历器和数据集合各种遍历方法的区别
https://es6.ruanyifeng.com/#docs/iterator Iterator(遍历器)的概念 Iterator 接口主要供for...of消费 Iterator 的遍历过程是: ...
- tensorflow高阶操作
本篇内容有:如何根据坐标有目的的选择(where).如何根据坐标有目的的更新(scatter_nd).如何生成一个坐标系() 1.where where针对的tensor是一个bool类型的tenso ...
- 【spring boot】SpringBoot初学(1) - Hello World
前言 此文只是记录自己简单学习spring boot的笔记.所以,文章很多只是初步理解,可能存在严重错误. 一.Spring boot的初步理解 1.spring boot的目标 (摘自:spring ...
- python之路(内存,小数据池,编码等)
代码块: python真正的代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块. 但是,在python终端交互模式下,每一条代码都是一个代码块 python在同一个代码块中的变量,初始化对象 ...
- 咸鱼的ACM之路:动态规划(DP)学习记录
按挑战程序设计竞赛介绍的顺序记录一遍学习DP的过程. 1. 01背包问题 问题如下: 有N个物品,每个物品(N[i])都有一定的体积(W[i]),和一定的价值(V[i]) 现在给定一个背包,背包的容量 ...