JavaScript类型、值和变量
概述
计算机是通过操作值(如数值字面量3.14)或文本(如“hello”)来工作的,编程语言中这些可以"表示"和"操作"的值(values)被称为类型(types)。
程序在需要把某个值保存下来以方便将来使用时,会把这个值赋给(或存入)变量(Variable)。
类型Types
原始类型(primitive types):原始值是不可修改的
数值Number
字符串值String
布尔值Boolean
null
undefined
BigInt
Symbol
对象类型(object types)
一个普通的JavaScript对象是一个个命名值(properties属性)组成的无序集合。
值Values
数值Number
JavaScript的主要数值类型Number用于表示整型和近似实数。JavaScript使用的是
IEEE 754
标准定义的64位浮点格式
表示数值整数字面量
0 //默认十进制 1 99 0xff // => 255 十六进制以0x开头 //ES6后的二进制和八进制表示 0b10101 // 0b开头 0o43 // 0o开头
浮点字面量
[digits].[digits][(E/e)[(+|-)]digits]
0.314 .33333 6.02e23 // => 6.02x10^23 1.41415415E-32// => 1.41415415x10^(-32)
数值字面量分隔符_
let billion = 1_000_000_000; // _作为千分位分隔符 let bytes = 0x89_AB_CD_ef // _作字节分隔符 let bits = 0b0001_1101_1100 // _作半字节分隔符 let fraction = 0.123_456_789 // 小数中也可用
浮点数丢失精度
let sum1 = .3 - .2; let sum2 = .2 - .1; console.log(sum1 === sum2); // => false !!
BigInt
ES2020为JavaScript定义了一种新的数值类型BigInt。该数值类型的值也是整数,能够表示64位整数,但由于没考虑方式时序攻击而不适合加密。
字面量:
1234n // 一个BigInt类型字面量 0b1101101n //二进制BigInt 0o7171 //八进制 0x12354abf //十六进制
构造函数BigInt(Number/String) 用于转换为BigInt类型的值。
文本Text
JavaScript中表示文本的类型是String,即字符串。字符串是
16位(UTF-16)
不可修改的有序序列,每一个值都表示一个Unicode字符。字符串字面量
"" //空字符串 'myblog' "3.1415926" 'name = “Zenyet”' "Whould't u perfer Zenyet's blog?" "with space " 'inside is "you"' //ES5 \ 可以让一行字符串分成若干行 "one\ two\ three"
模版字面量Template Literals
ES6及之后版本中,字符串字面量可以用反引号(``)来定界。
let name = "Zenyet"; // get value by ${varName} let greeting = `Hello, ${name}`; // => Hello, Zenyet
String.raw()
`\n`.length // => 1: 字符串中只包含一个换行符 String.raw`\n`.length // => 2: 一个反斜杠和一个字母n
布尔值Boolean
布尔值表示真或假、开或关、是或否。这个类型只有两个值:true/false.
null和undefined
null是一个语言关键字,求值为一个特殊值,通常用于表示某个值不存在。
undefined也表示值不存在,但undefined表示一种更深层次的不存在,一般地,未初始化的值就是undefined。
console.log(undefined == null); // => true console.log(undefined === null); // => false console.log(typeof undefined); // => undefined console.log(typeof null); // => object
符号Symbol
符号是ES6新增的一种原始类型,用作非字符串的属性名。因为js对象是一个属性(properties)的无序集合,每个属性都是name/value对。属性名在ES6之前必须是字符串,在符号出现后可以作为属性名。
Symbol没有字面量语法。可以使用构造函数Symbol(optional String parameter)获取一个永远不会返回同一个值的值。
let strname = "string name"; let symname = Symbol("propname"); typeof strname; // => String typeof symname;// => Symbol let obj = {}; // 字面量方式创建一个对象obj obj[strname] = 1; //使用字符串名定义一个属性 obj[symname] = 2; //使用符号名定一个一个属性
全局对象
全局对象的属性(properties)是全局性定义的标识符,可以在JavaScript程序的任何地方使用。JavaScript解析器启动后,都会创建一个新的全局对象并为其添加一组初始的属性:
全局常量:undefined、Infinity和NaN
全局函数:isNaN()、parseInt()、 eval()...
构造函数:Date()、RegExp()、Object()、Array()...
全局对象:Math、JSON...
Node和浏览器中:
Node: global属性引用全局对象
浏览器: window属性引用该全局对象
ES2020: globalThis
变量声明和赋值Variable Declaration and Assignment
计算机编程中最基本的一个技术就是使用名字(或标识符)表示值。
let和const
let a; let b;// 未初始化的值为undefined const PI = 3.14; //const修饰的变量必须要初始化 const KEY = 124; // 建议用大写名字表示
常量不可改变其值。
scope作用域
通过let和const声明的变量和常量具有块作用域,这意味它们只在let和const语句所在的代码块中有定义。通俗来说,{}里面的属于代码块,但形式参数不在{}内也属于代码块内。
var声明的变量
var声明的变量不再具有作用域。
函数外部使用var,则该变量为全局变量。var和let声明的全局变量的重要区别:通过var声明的全局变量被实现为全局对象的属性(不能使用delete操作符)。
var多次声明同名变量合法
var声明的最重要特性:作用域提升(hoisting)
- 在使用var声明变量时,该声明会被提高(或提升)到包含containing function的顶部
解构赋值(destructuring assignment)
ES6实现了一种复合声明与赋值语法为解构赋值。
在解构赋值中,等号右边的值是数组或对象("结构化"的对象),而左边通过模拟数组或对象字面量语法指定一个或多个变量。
其中左边多余的值被设置为undefined;右边多余的被忽略。
let [x,y] = [1,2]; // 相当于 let x = 1;let y = 2; [x,y] = [x+1,y+1]; // increment [x,y] = [y,x]; //exchange
in Array:
function exchange(x,y){ return [y,x]; } function square(y,x){ return [y*y,x*x]; } let [a,b] = exchange(1,2); // => a=2,b=1 let [y,x] = square(a,b); // => x=4,y=1
in Object:
let obj = {x:1,y:2}; for(const[name,value] of Ojbect.entries(obj)){ console.log(name,value); }