【原创】码路工人 Coder-Power

大家好,这里是码路工人有力量,我是码路工人,你们是力量。

github-pages

博客园cnblogs


今天的内容是,关于 JavaScript 中定义变量的变化(其实不确切,函数,常量表示被冷落)。


首先,回顾下 var 定义存在的问题

1. 哇。。var 好乱。。

1.1 可以重复定义

/* eg.0
* multi-definition of var-variable
*/
//--------------------------------------
var band = "The Beatles"
var band = "The Scorpions" console.log(band) // Scorpions
//--------------------------------------

以上代码没有报错,而是打印出了第二次定义的内容Scorpions。这..在C#等其它语言中必然是无法想象的。

JS:哎悲惨的童年,往事不堪回首。虽然被设计的简陋粗糙了些,但用起来方便啊,通过努力,一样成为Web时代的高富帅。现在有钱了,美容养生造起来~~~

1.2 可以先使用后定义

/* eg.1
* use before be definied
*/
//--------------------------------------
age = 18
console.log(age) // 18
var age = 10
console.log(age) // 10
//--------------------------------------

这就是变量提升啦。在编译的时候,会先将var定义的变量放到最上面,但这时候值并没有,还是undefined,赋值顺序为 18->10,所以有了一上例示例注释中的打印结果。

这里,还有一个优先级的问题,function > variable,即函数大于普通变量。

1.3 没有块级作用域

/* eg.2
* [var]use before variable be definied
*/
//--------------------------------------
function foo() {
var band = "Michael Learn To Rock"
} console.log(band) // Michael Learn To Rock
//--------------------------------------

块级作用域应该有:if(boolVal){ 这里 }for(...){ 这里 },还有function(){ 这里 },其实即使不是函数直接一对花括号也是产生块级的地方。

var没有块级作用域,意味着在块级外面也能够访问。上例中的结果说明了这一点。

IIFE(Immediately Invoked Function Expression) 立即执行函数了解一下(这个准备在后面的文章中单独介绍)。


然后咱们来看看 ES6 带来了什么

2. let const 来拯救

2.1 letconst 都有块级作用域

码麻再也不担心我在暗处受伤害了:

限定在块级作用域内不会被外部访问修改。

/* eg.3
* can not access out of block
*/
//--------------------------------------
// eg.3.1
function music() {
let band = "Mr. Big"
const songs = ["The chain", "To be with you", "Wild world"] this.data = {
band,songs
}
}
console.log(band, songs)
// Uncaught ReferenceError: band is not defined
//--------------------------------------

上面的打印直接报错,函数外是不能访问到内部用let/const声明的变量/常量的。

扩展一下:但可以绑定到对象属性上,属性本身外部可见。如下面的示例(在上例的基础上):

// eg.3.2
let m = new music()
console.log(m.data)
// { band: 'Mr. Big', songs: [ 'The chain', 'To be with you', 'Wild world' ] }

2.2 letconst 都有不存在变量提升

不给糖就捣蛋。要想使用先定义。

/* eg.4
* [let/const]use after be definied
*/
//--------------------------------------
// eg.2.1
band = "Queen"
let band
// Uncaught ReferenceError: Cannot access 'band' before initialization // eg.2.2
song = "Bohemian Rhapsody"
const song
// Uncaught SyntaxError: Missing initializer in const declaration
//--------------------------------------

未定义先使用?直接报错给你看。(看,报的错还不一样,下面还会提到)

2.3 letconst 都不能重复定义

/* eg.4
* [let/const]can not defined duplicately
*/
//--------------------------------------
// eg.4.1
let band = "Guns&Rose"
let band = "Nirvana"
// Uncaught SyntaxError: Identifier 'band' has already been declared // eg.4.2
const song = "November Rain"
const song = "Smells Like Teen Spirit"
// Uncaught SyntaxError: Identifier 'song' has already been declared
//--------------------------------------

简单的规则无需解释。我就是你的唯一!

2.4 let 定义变量

/* eg.5
* [let/const]can not defined duplicately
*/
//--------------------------------------
let singer = "Bob Dylan"
console.log(singer) // Bob Dylan singer = "Bryan Adams"
console.log(singer) // Bryan Adams
//--------------------------------------

变量确实是可变的。

注:像字符串与数值,栈中存放地址,堆中保持常量池,比较两个字面量的时候,比的是地址所以会全等(===),而再次给变量赋值的时候,改变的是地址指向,常量池中的原字符串/数值还是存在的(等没有引用会回收)。

关于 ===== 可以看之前发的另一篇[传送][AboutEqual]。

2.5 const 定义常量

JS: 终于咱也有常量了(C#里也叫const

2.5.1 常量定义后不可变

/* eg.6
* use before be definied
*/
//--------------------------------------
// eg.6.1
const band = "The Eagles"
band = "The Beatles"
// TypeError: Assignment to constant variable. // eg.6.2
const age = 18
age = 10
// TypeError: Assignment to constant variable.
//--------------------------------------

以上两个小例子中,说明字符串或数值的常量在定义后都是不能再改变的。

注意:这里不可变是指简单类型,复杂类型/对象里面的成员/属性是可以改变的。

/* eg.7
* change the value of const-object's property
*/
//--------------------------------------
const person = {
name = "Eagles",
age = 18
}
console.log(person)
// { name: 'Eagles', age: 18 } person.name = "Chicken"
person.age = 10
console.log(person)
// { name: 'Chicken', age: 10 }
//--------------------------------------

以上打印结果显示,const对象的属性name/age修改成功。

2.5.2 常量在且仅在定义时赋值(=定义时必须赋初始值,赋值后不能改)

/* eg.8
* exception on define const
*/
//--------------------------------------
const foo
foo = "bar"
// SyntaxError: Missing initializer in const declaration
//--------------------------------------

不用解释,报异常了。定义const必须给值。(上面已经提到过了,就当加深印象再说一遍吧)


(示例中好像暴露了部分播放历史。。感兴趣的同学可以搜搜瞧下)


希望对你能有帮助,下篇再见。


欢迎关注分享,一起学习提高吧。


最新文章

  1. Thinking in java学习笔记之LinkedList 与Stack
  2. HTML JavaScript的DOM操作
  3. 第二百一十一天 how can i 坚持
  4. 实例讲解Linux系统中硬链接与软链接的创建
  5. MSBuild编译扩展
  6. [Node.js] Introduction to apiCheck.js
  7. Objective-C学习篇09—NSNumber与笑笑语法
  8. 给你的网页添加一个随机的BGM
  9. crontab定时执行shell脚本失败的原因
  10. 合并两个有序数组的golang实现
  11. notepad++ 注释
  12. 4.0-uC/OS-III目录结构
  13. 2-SAT问题的方案输出
  14. 20145322 《网络对抗》 MSF基础应用1
  15. [微信小程序直播平台开发]___(三)Nginx-rtmp事件回调
  16. Java中创建实例化对象的几种方式
  17. [Hadoop大数据]--kafka入门
  18. 利用 Task\Query 实现定位 , FeatureLayer 的属性查询
  19. 【小程序】微信小程序开发—弹出框
  20. java代码----equals和==区别

热门文章

  1. 网络流中的图像转化为OpenCV中的Mat类型
  2. 学习笔记之pip的基本使用
  3. uniapp 踩坑
  4. Spring学习笔记(八)Spring Data JPA学习
  5. linux下在用python向文件写入数据时'\n'不起作用
  6. Coursera课程笔记----P4E.Capstone----Week 4&5
  7. Spring 中基于 AOP 的 @AspectJ注解实例
  8. 【HBase】底层原理
  9. 初探Redis-基础类型Hash
  10. [hdu4627 The Unsolvable Problem]数论