JavaScript声明变量详解
前言
如果文章中有出现纰漏、错误之处,还请看到的小伙伴多多指教,先行谢过
在ES5
阶段,JavaScript
使用 var
和 function
来声明变量, ES6
中又添加了let
、const
、import
、 Class
这几种声明变量的方式。那么,他们各自都有什么样的特点呢?
下面,就让我们一起去探究一下吧
以下↓
变量就是存储信息的容器。
ECMAScript
的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据
var 声明
一直以来,我们都是使用var关键字来声明变量
var a = 1;
var b;console.log(a) // 1
console.log(b) // undefined
console.log(c) // undefinedvar b = 2;
var c = 3;
console.log(b) // 2
console.log(c) // 3function f() {var c = 4;console.log(c) // 4c = 5;console.log(c) // 5
}
f();
console.log(c) // 3function fun() {c = 6
}
fun();
console.log(c) // 6复制代码
从上面的结果我们不难看出,使用var声明的变量具有以下特点:
- 变量可以没有初始值,会保存一个特殊的值
undefined
- 变量可以重复定义,且可以修改值
- 变量声明语句从自动提升到所在作用域的顶端
- 函数内重复定义对函数外无影响(局部变量)
- 函数内重新赋值对函数外有影响
function 关键字声明
在ES5中,除了使用var声明变量,我们也可以使用 function
关键字声明变量
f();
function f() {console.log(1)}
var f;console.log(f) // function f
复制代码
特点:
- 使用
function
声明的是函数对象,也存在声明提升 - 函数声明要优于变量声明
let声明
由于 ES5
中使用 var
声明变量存在着一些很让人迷惑的特性(比如变量提升,重复定义等),ES6
中新增 let
命令,用来声明变量。它的用法类似于 var
,但是所声明的变量,只在 let
命令所在的代码块内有效
{var a = 1;let b = 2;
}
console.log(a) // 1
console.log(b) // Uncaught ReferenceError: b is not definedconsole.log(c) // Uncaught ReferenceError: c is not definedlet c = 3let a = 4console.log(a) // Identifier 'a' has already been declared
复制代码
通过以上的代码,我们很容易发现使用 let
声明变量的特点:
- let声明的变量只在它所在的代码块有效
- 不存在变量提升
- 不可以重复声明
由于 let
声明变量的这些特点,所以 for
循环的计数器,就很合适使用 let
命令
for(let i = 0; i < 10; i++) {//
}console.log(i) // Uncaught ReferenceError: c is not defined// 如果使用var声明,则在这里输出的就是10
复制代码
let
实际上为JavaScript
新增了块级作用域
const声明
const
也是 ES6
新增的声明变量的方式,const
声明一个只读的常量。一旦声明,常量的值就不能改变
const API;console.log(API) // SyntaxError: Missing initializer in const declarationconsole.log(MAX); // Uncaught ReferenceError: MAX is not defined
const MAX = 1;const MAX = 2;console.log(MAX); // Identifier 'MAX' has already been declaredconst PI = 3.1415;console.log(PI) // 3.1415PI = 3; // TypeError: Assignment to constant variable.const f = {}
f.name = 'HELLO' // 正常执行f = {name: 'World'} // 报错
复制代码
所以,使用 const
声明的变量具有以下特点:
const
一旦声明变量,就必须立即初始化,不能留到以后赋值- 不允许重复声明
- 不存在变量提升
const
实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动
如果真的想将对象冻结,应该使用
Object.freeze
方法
import 声明
ES6
新增的模块的概念。
模块功能主要由两个命令构成:
export
和import
。export
命令用于规定模块的对外接口,import
命令用于输入其他模块提供的功能
所以在一定程度上来说,import
也具有声明变量的功能。只是在使用 import
的时候,具有一些限制
export { first, last } import { first, last } from './xxx'first = {} // Syntax Error : 'a' is read-only;first.name = 'Hello' // 成功执行,但是不建议这样使用export default function(){} // a.jsimport xxx from 'a.js'import { New as $ } from './xxx'
复制代码
特点:
import
命令接受一对大括号,大括号里面的变量名,必须与被导入模块对外接口的名称相同import
命令输入的变量都是只读的,因为它的本质是输入接口- 当使用
export default
命令,为模块指定默认输出的时候,import
命令可以为该匿名函数指定任意名字 import
命令具有提升效果,会提升到整个模块的头部,首先执行- 如果想为输入的变量重新取一个名字,
import
命令要使用as
关键字,将输入的变量重命名
本质上,
export default
就是输出一个叫做default
的变量或方法,然后系统允许你为它取任意名字
class 声明
ES6
引入了类的概念,有了 class
这个关键字,作为对象的模板。通过 class
关键字,可以定义类
class Point {constructor(x, y) {this.x = x;this.y = y;}toString() {return '(' + this.x + ', ' + this.y + ')';}
}
复制代码
ES6
的class
可以看作只是一个语法糖,它的绝大部分功能,ES5
都可以做到,类的实质还是函数对象,类中的方法和对象其实都是挂在对应的函数对象的prototype
属性下
所以就可以改写成下面这种ES5的方式
function Point(x, y) {this.x = x;this.y = y;
}Point.prototype.toString = function() {return '(' + this.x + ', ' + this.y + ')';
}
复制代码
特点:
- 所有类都有
constructor
函数,如果没有显式定义,一个空的constructor
方法会被默认添加。当然所有函数对象都必须有个主体 - 生成类的实例对象的写法,与
ES5
通过构造函数生成对象完全一样,也是使用new
命令
class B {}let b = new B();
复制代码
- 在类的实例上面调用方法,其实就是调用原型上的方法
- 与函数对象一样,
Class
也可以使用表达式的形式定义 Class
其实就是一个function
,但是有一点不同,Class
不存在变量提升,也就是说Class
声明定义必须在使用之前
全局变量
在浏览器环境指的是
window
对象,在Node
指的是global
对象。ES5
之中,顶层对象的属性与全局变量是等价的
var
命令和function
命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let
命令、const
命令、class
命令声明的全局变量,不属于顶层对象的属性。也就是说,从ES6
开始,全局变量将逐步与顶层对象的属性脱钩
var a = 1;window.a // 1let b = 2;window.b // undefined
复制代码
隐式声明
在 JavaScript
中还存在着隐式声明。
a = 1;
console.log(a) // 1
复制代码
当没有声明,直接给变量赋值时,会隐式地给变量声明,此时这个变量作为全局变量存在。这个时候就不存在声明提前的问题了
最后
其实只要我们理解并掌握了这几种声明变量的方式,记住它们的特点,那么在实际使用的过程当中就很容易能够找到最合适的方式去定义
每天学习分享,不定期更新
最后,推荐一波前端学习历程,这段时间总结的一些面试相关,分享给有需要的小伙伴,欢迎 star
关注 传送门
参考文档
ECMAScript 6入门
ES6变量声明
转载于:https://juejin.im/post/5cc65a21f265da03904c21c2
JavaScript声明变量详解相关推荐
- Java简单类、变量详解(概念和分类、声明、命名、初始化)
1初识JAVA简单类 (1)创建第一个Java程序的具体步骤: 第一步:创建一个工程,在Package Explorer空白区域中右击New->点击Java Project->填写Proj ...
- php的 静态变量,PHP之static静态变量详解
在看别人项目过程中,看到函数里面很多static修饰的变量,关于static修饰的变量,作用域,用法越看越困惑,所以查了下资料. static用法如下: 1.static 放在函数内部修饰变量 2.s ...
- javaScript函数模块详解
javaScript函数模块详解 函数实际上是对象,每个函数都是Function类型的实例,而Function也有属性和方法,和其他引用类型一样 可以将函数名想象成指针,函数想象成对象 注意, ...
- JavaScript的函数详解
JavaScript的函数详解 一.什么是函数 二.函数的使用 1.函数的声明 2.函数的调用 3.函数的参数:参入运算的数据 (1)形参(形式参数) (2)实参(实在参数): (3)参数之间的数据传 ...
- JavaScript Class类详解
ECMAScript 6 提供了更接近传统语言的写法,新引入的class关键字具有正式定义类的能力.类(class)是ECMAScript中新的基础性语法糖结构,虽然ECMAScript 6类表面上看 ...
- php之static静态变量详解
php之static静态变量详解 一.总结 把局部变量改变为静态变量后是改变了它的存储方式,即改变了它的生存期. 把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围. 二.php之sta ...
- 嵌入式c语言为什么变量定义在前面,嵌入式C语言数据类型和变量详解
原标题:嵌入式C语言数据类型和变量详解 一般来讲,标准的C语言类型在嵌入式编译器中是合法的.但由于嵌入式控制器的受限环境.嵌入式c语言的变量和数据类型具有新的特征,这些特征体现在如下方面. 嵌入式C语 ...
- swift. 扩展类添加属性_swift中的声明关键字详解
原起 学习swift,swift中的关键字当然要了解清楚了,最近在网上看到了关于声明关键字的文章,整理记录一下. 关键字是类似于标识符的保留字符序列,除非用重音符号(`)将其括起来,否则不能用作标识符 ...
- Linux环境变量详解
Linux环境变量详解 环境变量是操作系统环境设置的变量,适用于整个系统的用户进程. 环境变量分类 按照权限分类 系统级:系统级的环境变量是每个登录到系统的用户都要读取的系统变量 用户级:用户级的环境 ...
最新文章
- 【转】AVAudioPlayer播放音乐,最清晰明了
- 解析深度学习:语音识别实践电子书
- php图标按钮,CSS如何创建图像图标按钮(附代码)
- matlab实时脚本使用
- Linux 安装composer
- java+enum+devicetype_JSF web编程:通过enum数组生成
- python-水仙花数
- 设置Windbg符号文件路径
- mysql集群搭建教程-mysql+windows篇
- 多位诺贝尔奖获得者推荐的精品力作:《大数据时代的调查师》
- C# winform程序怎么打包成安装项目(图解)
- 快速排序算法c语言lomuto,快速排序(N.Lomuto版)
- 5G 是否能让国产手机回到群雄割据时代?
- 剑指offer面试题[49]-把字符串转化为整型
- 2021-06-27 方法的调用
- Win XP 经典壁纸拍摄地 24 年后变样了
- 做数据分析不得不看的书有哪些?
- HTTPS中的数字证书是什么?数字签名又是什么?
- html页面如何拉长,HTML可以拉长的logo
- bind9 dlz mysql_利用BIND+DLZ+MYSQL构建企业智能DNS