写在前面
SAST2020前端组授课——JavaScript基础学习教程系列
变量声明
命名规则
JS中的变量是弱类型可以保存所有类型的数据,即变量没有类型而值有类型。变量名以字母、$、_ 开始,后跟字母、数字、_。(区分大小写,避免使用关键字和保留字!)
驼峰式命名规则:第一个字母小写,之后每个单词首字母大写。
动态弱类型语言
别的编程语言会对变量的类型有严格的限制,之间的转换也有规定。你开始定义一个变量,是整型它就只能是整型,是字符串它就必须是字符串。而JS就不同了。变量声明的时候不用规定是什么类型的,用的时候它自己根据你赋的值判断。
参考资料:https://blog.csdn.net/xo3ylAF9kGs/article/details/102812991
可以思考一下:动态VS静态,强VS弱,之间是什么关系?
类型检查确保一个表达式中的变量类型是合法的。在静态类型语言中,类型检查发生在编译阶段;动态类型语言,类型检查发生在运行阶段。
强类型语言有更强的类型检查机制,表达式计算中会做严格的类型检查;而弱类型语言允许各种变量类型间做一些运算。
下面都是合法的命名:
1 | let name = 'sast'; |
JS语言关键字不能用来做变量名,比如 true、if、while、class
等。
1 | let class = 'sast'; |
奇怪的JS
下面是JS这种动态弱类型语言的有趣之处:
1 | console.log(0 == "0"); |
运算符
一元运算符 ++ – !
算术运算符 * / % + -
关系运算符 >= <= > <
相等运算符 == != === !==
逻辑运算符 && ||
赋值运算符 =三目运算符:表达式1?语句1:语句2
运算符 | 说明 |
---|---|
== | 强制类型转换比较 |
=== | 不强制类型转换比较 |
声明方式
可以使用多种方式定义变量比如var、let
等(后面作用域会再讨论变量)。
1 | let name = 'sast'; |
以上代码是声明和赋值的结合
1 | let name; |
使用,
可以同时声明多个变量
1 | let n = 2,f = 3; |
下面演示了变量可以更换不同类型的数据
1 | let sast = 'sast.com'; |
ES6中,新增了常量的定义方法:
1 | const name = 'SAST'; |
数据类型
类似C++,JavaScript有着类似的数据类型。
基本数据类型
Number(NaN)、String、Boolean
数值强制转换。
String:转义字符(当成一个字符长度)
转义字符 含义 \n 换行 \t 制表 \b 退格 \\ \ " " \u03b1,\u03b2,\u03b3,\u03b4,\u03b5 α,β,γ,δ,ε
Undefined、Null
undefined:未定义
null:空对象
1
2 console.log(typeof null);
>> Object
引用数据类型
Object:对象——对象是包括属性与方法的数据类型。
1 | var web = "sast.njupt.edu.cn"; |
在W3School中,JavaScript对象有着这样一句定义:
在 JavaScript 中,对象是王。如果您理解了对象,就理解了 JavaScript。
Javascript是一个典型的面向对象变成语言(OOPL)
什么是面向对象OOP?
- 由过程到对象
- 由具体到抽象
- 由高耦合到低耦合
四大基本特性:封装、抽象、继承、多态
- 对象是属性和方法的集合即封装
- 将复杂功能隐藏在内部,只开放给外部少量方法,更改对象内部的复杂逻辑不会对外部调用造成影响即抽象
- 继承是通过代码复用减少冗余代码
- 根据不同形态的对象产生不同结果即多态
在 JavaScript 中,几乎“所有事物”都是对象。
- 布尔是对象(如果用 new 关键词定义)
- 数字是对象(如果用 new 关键词定义)
- 字符串是对象(如果用 new 关键词定义)
- 日期永远都是对象
- 算术永远都是对象
- 正则表达式永远都是对象
- 数组永远都是对象
- 函数永远都是对象
- 对象永远都是对象
所有 JavaScript 值,除了原始数据类型的值,都是对象。
变量提升
解析器会先解析代码,然后把声明的变量的声明提升到最前,这就叫做变量提升。
下面代码在解析过程中发现while
不能做为变量名,没有到执行环节就出错了,这是一个很好的解析过程的体验。
1 | var web = 'sast.njupt.edu.cn'; |
使用 var
声明代码会被提升到前面
1 | console.log(a); //undefined |
下面是 if()
中定义的var也会发生变量提升,注释掉if
结果会不同
1 | var web = "sast.njupt.edu.cn"; |
变量提升:提升的是变量的定义;
函数提升:提升的是函数的定义;
提升指的是函数及变量的声明都将被提升到函数的最顶部,且函数优先级大于变量。
而且变量的赋值不会提升。
使用 var
定义的代码,声明会被提升到前面,赋值还在原位置
1 | fn(); |
作用域
一个简单的实例:
1 | console.log(sast); |
var
使用 var
声明的变量存在于最近的函数或全局作用域中,没有块级作用域的机制。
没有块作用域很容易污染全局。
如果声明变量的时候,没有声明,直接赋值,在某种程度上也会被解释器执行,但是不建议这么写:
1 | function sast() { |
没有块作用作用域时var也会污染全局
1 | for (var i = 0; i < 10; i++) { |
使用let
有块作用域时则不会
1 | let i = 100; |
下例中体验到 var
没有块作用域概念, do/while
定义的变量可以在块外部访问到
1 | var num = 0; |
var
全局声明的变量也存在于 window
对象中
1 | var sast = "SAST!"; |
这同样会导致污染到windows对象!
以往没有块任用时使用立即执行函数模拟块作用域
1 | (function() { |
有了块作用域后实现就变得简单多了
1 | { |
let
与 var
声明的区别是 let/const
拥有块作用域,下面代码演示了块外部是无法访问到let
声明的变量。
- 建议将
let
在代码块前声明 - 用逗号分隔定义多个
let
存在块作用域特性,变量只在块域中有效
1 | if (true) { |
块内部是可以访问到上层作用域的变量.
每一层都是独立作用域,里层作用域可以声明外层作用域同名变量,但不会改变外层变量
1 | function run() { |
共同点:
var/let/const
共同点是
-
全局作用域中定义的变量,可以在函数中使用
-
函数中声明的变量,只能在函数及其子函数中使用
-
函数中声明的变量就像声明了私有领地,外部无法访问
TDZ
TDZ 又称暂时性死区,指变量在作用域内已经存在,但必须在let/const
声明后才可以使用。
TDZ可以让程序保持先声明后使用的习惯,让程序更稳定。
- 变量要先声明后使用
- 建议使用let/const 而少使用var
使用let/const
声明的变量在声明前存在临时性死区(TDZ)使用会发生错误
const
使用 const
用来声明常量,这与其他语言差别不大,比如可以用来声明后台接口的URI地址。
- 常量名建议全部大写
- 只能声明一次常量
- 声明时必须同时赋值
- 不允许再次全新赋值
- 可以修改引用类型变量的值
- 拥有块、函数、全局作用域
1 | try { |
改变常量的引用类型变量的值
1 | const INFO = { |
在不同作用域中可以重名定义常量
1 | const NAME = 'ZLH'; |
重复定义
使用 var 可能造成不小心定义了同名变量.
使用let
可以避免上面的问题,因为let声明后的变量不允许在同一作用域中重新声明
1 | let web = 'sast.njupt.edu.cn'; |
不同作用域可以重新声明
1 | let web = 'sast.njupt.edu.cn'; |
let
全局声明的变量不存在于 window
对象中,这与var
声明不同
1 | let web = "sast.njupt.edu.cn"; |
Object.freeze
如果冻结变量后,变量也不可以修改了,使用严格模式会报出错误。
1 |
|
传值与传址
基本数据类型指数值、字符串等简单数据类型,引用类型指对象数据类型。
基本类型复制是值的复制,互相不受影响。下例中将a变量的值赋值给b变量后,因为基本类型变量是独立的所以a的改变不会影响b变量的值。
1 | let a = 100; |
对于引用类型来讲,变量保存的是引用对象的指针。变量间赋值时其实赋值是变量的指针,这样多个变量就引用的是同一个对象。
1 | let a = { |
undefined
对声明但未赋值的变量返回类型为 undefined
表示值未定义。
1 | let sast; |
对未声明的变量使用会报错,但判断类型将显示 undefined
。
1 | console.log(typeof sast); |
我们发现未赋值与未定义的变量值都为 undefined
,建议声明变量设置初始值,这样就可以区分出变量状态了。
函数参数或无返回值是为undefined
1 | function sast(web) { |
null
null
用于定义一个空对象,即如果变量要用来保存引用类型,可以在初始化时将其设置为null
1 | var sast = null; |
严格模式
严格模式可以让我们及早发现错误,使代码更安全规范,推荐在代码中一直保持严格模式运行。
主流框架都采用严格模式,严格模式也是未来JS标准,所以建议代码使用严格模式开发
基本差异
变量必须使用关键词声明,未声明的变量不允许赋值
1 | ; |
强制声明防止污染全局
1 | ; |
关键词不允许做变量使用
1 | ; |
变量参数不允许重复定义
1 | ; |