欢迎来到js通关指南(第二章)-字面量与变量
字面量与变量
字面量:
是一些不可改变的值,字面量都是可以直接使用,但是我们一般不会直接使用字面量。 如: 1, 'a'
变量:
变量是程序在内存中申请的空间,用于存放数据的,通过变量名字进行修改或使用
变量的使用步骤 1声明变量,2赋值,3使用
变量的声明
var
1.var声明变量
JavaScript
// 1.单独定义并赋值
如:var age=18;
// 2.续定义
如:var a,b,c;
// 3. 连续定义并赋值
如:var a=1,b=2,c=3;
注意:
如果声明的变量未赋值时候使用,则值为 undefined 如果未声明直接使用会 报错: 变量名 is not defined
JavaScript
var a;
console.log(a) // undefined
-------------
console.log(b) // b is not defined
如果直接赋值 如: a=5; 也可以使用,会变成全局变量(非常不建议这么使用) 如果在浏览器环境会变成window下的一个属性也就是全局变量,再次重复这么使用是不规范的
JavaScript
a=5;
console.log(a)// 5
console.log(window.a) // 5
如下图就是将a挂到了全局上
2. var 定义变量的作用域
var 只有函数作用域没有块级作用域
javascript
if(true){
var a=10;
}
console.log(a) //10
javascript
function aa(){
var a =20
}
aa()
console.log(a) //a is not defined**
3. var 的变量提升
javascript
console.log(a) //undefined
var a=10;
----------------
上面代码这个等同于
var a;
console.log(a) //undefined
a=10
4. var 定义变量可以重复声明不会报错
javascript
var a=10;
var a=12;
console.log(a);//12不会报错
var 定义变量可以重复声明不会报错原因是
这个由于var的变量提升在实际运行会解析成
javascript
var a;
a=10;
a=12;
console.log(a) //12
5. var 的全局声明
javascript
如 var name ="zs"
console.log(window.name) //zs
console.log(10);//这个10会是全局变量
这个与 name="zs"一致 由于 var 没有块级作用域
let
1.let声明变量 没有变量提升
let 与var 的区别是 没有变量提升, 有块级作用域,全局声明不会成为window的属性
JavaScript
let 没有全局声明
如 let name ="zs"
console.log(window.name) //undefined
2. let 没有变量提升(暂时性死区)
JavaScript
//这个也叫做暂时性死区
console.log(a) // Cannot access 'a' before initialization
还有一种情况
JavaScript
let a=0;
function aa(){
console.log(a)
let a=1
}
a();// Cannot access 'a' before initialization
3.let 的重复定义
JavaScript
let a=0;
let a=10; // 'a' has already been declared
4. let 的块级作用域
JavaScript
if(true){
let a=0;
}
console.log(a) //报错a is not defined
5. let 和var 定义变量的实际场景(面试题)
循环问题
原因是变量提升问题
当延迟执行的setTimeout 输出var 定义的变量时, 内存地址是相同的,因此最后i变成了5再输出的
而 let 定义的采用的块作用域,相当于每个不同地址的变量
const 声明变量
const 没有变量提升 不会成为window的属性 有块级作用域
他与 let 不同的是 const 定义的变量不允许修改, 也就不不允许使用一个内存地址去覆盖他定义好的内存地址
JavaScript
const a=10;
a=20; // Assignment to constant variable.
而
const a={
name:"zs"
}
a.name="李四"可以// 为什么呢(因为内存地址没改)
}
如果想让整个对象都不能修改,可以使用 Object.freeze(),这样再给属性赋值时虽然不会报错(严格模式会报错)但会静默失败 如:
JavaScript
const o3 = Object.freeze({
name:'zs'
});
o3.name = 'Jake';
console.log(o3.name); // {name: 'zs'}
第二个不同是 他在声明变量的时候必须要赋值
JavaScript
如 const a; // syntaxError 注:常量声明时候没有初始化
注意 根据ESMA262的规范 let 和const 和var 一样再词法环境被创建时候就会赋值为undefined 但是let 和const定义的变量只有再被赋值时候才能访问 否则会报错,也就说执行定义变量之前这个变量就存在了只是不能被访问(详细可以看后面的js执行原理的词法分析)
那么let 和const 有没有作用域提升呢
社区名词
暂时性死区和 代码的定义位置无关而和代码的执行顺序有关 因为早期的代码 所以这里引擎的特殊处理 , 代码块不会形成新的上下文 但是会形成新的此法环境
变量名命名规范
1变量名只能由字母数字下划线和美元$组成 2严格区分大小写 3不能以数字开头 4不能为关键字 5变量名必须有意义 6遵循驼峰法
驼峰命名法 getName 帕斯卡命名法 DataBase
规范 如果是 常量应该定义为 全大写如 NAME 如果是 私有属性 则使用_ 开头命名 如 _firstName
注意: JS中严格区分大小写 js每一条语句以;结尾
如果不写分号,浏览器回自动添加分号,但是会消耗系统资源
而且有时浏览器回加错分号;(极少数情况下,现代开发应该不会出现这个问题了)
js回忽略多个空格和换行
详细请看第七章代码风格及开发准则