变量
var关键字
-
使用var声明作用域
function test(){ var message = "hi"; // 这是一个局部变量 console.log(message) } test(); function test2(){ message = "hi"; // 省略var之后就变成全局变量了 console.log(message) } test2();
-
var声明提升
-
例子
function foo(){ console.log(age); var age = 15; } foo(); // 运行之后不会报错,会返回undefined
- 上述例子中,var将所有变量声明都提升到了函数作用域顶部
-
var声明的范围是函数作用域
可以使用var重复声明同名的变量
-
使用var在全局作用域中声明的变量会成为window对象的属性
var name = "Jack"; console.log(window.name); // 输出Jack
let关键字
-
let声明的范围是块作用域
if (true){ let name="Tom"; console.log(name); } console.log(name); // 这里提示name没有定义,因为let声明的变量只在if块内部起作用
let不允许在同一个块作用域中声明同名变量
-
let声明的变量不会在作用域中被提示
console.log(name); // 这里会提示name没有定义 let name ="Tom";
- 在解析上述代码的时候,JS引擎会注意到块后面的let声明,但是在此之前不能以任何方式来引用未声明的变量
- 在let声明之前的执行瞬间被称为暂时性死区
-
使用let在全局作用域中声明的变量不会成为window对象的属性
let name="Tom"; console.log(window.name); // 提示未定义
-
在for循环中使用let关键字
for (let i = 0; i < 5; i++) { console.log(i); } console.log(i); // 此时提示i没有定义
- let声明的变量i只在for循环这个块中起作用
const语句
- 在声明变量的时候必须同时初始化变量,尝试修改const声明的变量时会报错
- const也不允许重新赋值
- 如果const变量引用的是一个对象,那么修改这个对象内部的属性是可以的
数据类型
- 简单数据类型(原始类型)
- Undefined
- Null
- Boolean
- Number
- String
- Symbol(ECMAScript6新增的)
- 复杂数据类型
- Object
- ECMAScript中不能自定义数据类型,所以所有的值都可以使用上面那七种类型之一来表示
typeof操作符
- 对一个数据类型使用typeof操作符会返回下面的结果
- undefined:未定义
- boolean:布尔值
- string:字符串
- number:数值
- object:对象或null
- function:函数
- symbol:符号
- 特殊值null被认为是一个对空对象的引用
Undefined类型
只有一个值,就是undefined
-
当使用var或let声明变量但是没有初始化赋值的时候,就相当于给变量赋了undefined值
let message; console.log(typeof(message)); // 结果是undefined
undefined的布尔值是false
Null类型
只有一个值,就是null
-
null表示一个空对象指针
let cat = null; console.log(typeof cat); // 返回object
如果要定义一个用来保存对象值的变量,那么可以使用null来初始化,这样就可以知道变量是否在之后的代码中被重新赋予了一个对象的引用
null的布尔值是false
Boolean类型
有两个字面值:true和false
-
将其他类型的值转成布尔值
let message = "Hello World"; console.log(message); // 结果是Hello World let messageToBoolean=Boolean(message); console.log(messageToBoolean); // 结果是true
-
转换规则
数据类型 转换结果是true 转换结果是false Boolean true false String 非空字符串 空字符串 Number 非零的数值 0,NaN Object 任意对象 null Undefined 不存在 undefined
Number类型
整数可以使用八进制或十六进制字面量表示
-
如果字面量中包含的数字超出了应有的范围,会忽略前缀的0,后面的数字当成十进制
let octalNumber1 = 070 ; // 八进制56 let octalNumber2 = 079;; // 无效的八进制,当成79处理
-
浮点数
必须有小数点,因为存储浮点数使用的内存控件是存储整数值的两倍,所以如果小数点后没有数字或者小数点后是0,就会被转成整数
-
对于非常大或非常小的数字,使用科学计数法
let floatNumber1 = 3.12e7; // 等于31200000 let floatNumber2 = 3e-12;
-
极值
最小值保存在Number.MIN_VALUE中
最大值保存在Number.MAX_VALUE中
-
如果数值结果超过了极值的范围,那么这个值会被自动转换为Infinity值
- 任何无法表示的负数以-Infinity表示
- 任何无法表示的正数以Infinity表示
-
例子
console.log(Number.MIN_VALUE); // 5e-324 console.log(Number.MAX_VALUE); // 1.7976931348623157e+308 // 确定一个数字是不是有限大的 let result = 10; console.log(isFinite(result));
-
NaN
不是数值(Not a Number)
用来表示要返回数字的操作失败了,但不是报错
任何涉及到NaN的操作始终返回NaN
NaN不等于包括NaN在内的任何值,需要使用isNaN()函数来判断某个值是否“不是数值”,如果不能转换为数字,就返回true
-
例子
console.log(0/0); // 返回NaN console.log(-0/+0); // 返回NaN console.log(5/0); // 返回Infinity console.log(5/-0); // 返回-Infinity console.log(isNaN(NaN)); // true console.log(isNaN("hello")); // true,不能转成数字 console.log(isNaN("10")); // false,可以转成数字
-
数值转换
-
Number():转型函数,用于任何数据类型
布尔值:true转成1,false转成0
数组:直接返回
null:返回0
undefined:返回NaN
-
字符串
- 如果字符串包含数字字符,那么包括数字字符前面的符号会转成一个十进制数
- 如果字符串包含有效的浮点数格式,那么转成相应的浮点数
- 如果字符串包含有效的十六进制格式,那么转成与它值对应的十进制整数
- 空字符串返回0
- 如果字符串包含除了上述情况之外的其他字符,那么返回NaN
-
例子
let n1 = Number("Hello"); console.log(n1); // NaN let n2 = Number(""); console.log(n2); // 0 let n3 = Number("001"); console.log(n3); // 1 let n4 = Number(true); console.log(n4); // 1
-
parseInt()
在需要得到整数的时候优先使用
字符串最前面的空格会被忽略,从第一个非空格字符开始转换
如果第一个字符不是数字,加号或减号,那么直接返回NaN(空字符串也返回NaN)
如果第一个字符是数字,加号或减号,那么继续依次检测,直到字符串末尾或者碰到非数值字符
如果字符串第一个字符是数字,那么可以识别不同的整数格式,比如以0x开头就解释为十六进制整数,如果以0开头且紧跟数字,非严格模式下可以解释为八进制整数
为了避免混淆,parInt()第二个参数用于指定进制数
-
例子
let n5 = parseInt("123blue"); console.log(n5); // 转成123 let n6 = parseInt("24.56"); console.log(n6); // 返回24,因为小数点不是有效的整数字符 let n7 = parseInt("0xf"); console.log(n7); let n8 = parseInt("000123",8); // 指定按照八进制进行解析 console.log(n8);
-
parseFloat()
只解析十进制的值,不能指定进制数
只有第一次出现的小数点有效
它始终忽略字符串开头的零,十六进制数值始终返回0
如果字符串表示整数(没有小数点,或小数点只有一个0),那么就返回整数
-
例子
let f1 = parseFloat("123blue"); console.log(f1); // 返回123 let f2 = parseFloat("24.2.3"); console.log(f2); // 返回 24.2 let f3 = parseFloat("0xA"); console.log(f3); // 返回0
-
String类型
表示零或多个16位的Unicode字符序列,可以使用单引号,双引号,反引号表示
-
使用length查看字符串中16位字符的长度
let str1 = "hello world"; console.log(str1.length); // 结果是11 let str2 = "hello world \u03a3"; console.log(str1.length); // 结果是13,\u03a3表示希腊字母Σ,占两个长度
字符串是不可变的,一旦创建了,它们的值就不能变了
-
转换为字符串
- toString()方法
- 返回当前值的字符串类型
- 数字,布尔值,对象,字符串都可以用
- null和undefined值没有这个方法
- 当对数字使用这个方法的时候,可以接收一个底数参数,用来表示以什么底数输出结果
- String()转型函数
- 始终会返回表示相应类型值的字符串
- 如果值有toString()方法,就调用这个方法并返回结果
- 如果值是null,返回"null"
- 如果值是undefined,返回"undefined"
- toString()方法
-
模板字面量
保留换行符
-
例子
let page = ` <div> <a href="#"> <span>Tom</span> </a> </div> `
-
字符串插值
所有插入的值都会使用toString()方法强制转成字符串
-
例子
let name = "Tom"; let age = 18; let str11 = `我的名字是${name} ,我今年${age}岁`; console.log(str11);
Symbol类型
符号是原始值
符号实例是唯一的,不可变的
用来确保对象属性使用唯一标识符
-
例子
let sym = Symbol("这是一个描述"); console.log(typeof sym); // 返回symbol
-
全局符号注册表
-
如果运行的时候不同部分需要共享和重用符号实例,那么可以使用一个字符串作为键,在全局符号注册表中创建并重用符号
let sym1 = Symbol.for("ok"); // 创建全局注册表中的新符号 let sym11 = Symbol.for("ok"); // 重用已有符号 console.log(sym1 === sym11); // 返回true
全局注册表中的符号必须使用字符串键来创建,Symbol.for()的任何值都会被转换为字符串
-
使用Symbol.keyFor()来查询全局注册表,这个方法接收符号,返回这个全局符号对应的字符串键,如果找不到就返回undefined,如果传递的不是符号,就报错
let sym1 = Symbol.for("ok"); console.log(Symbol.keyFor(sym1)); // 返回ok let sym2 = Symbol("yes"); console.log(Symbol.keyFor(sym2)); // 返回undefined
-
-
使用符号作为属性
凡是可以使用字符串或数字作为属性的地方,都可以使用符号
-
例子
let s1 = Symbol("foo"), s2 = Symbol("bar"), s3 = Symbol("yes") s4 = Symbol("no"); let p = {}; p[s1] = "foo值"; console.log(p); // {Symbol(foo): 'foo值'} Object.defineProperty(p, s2, {value: 'bar值'}); console.log(p); //{Symbol(foo): 'foo值', Symbol(bar): 'bar值'} Object.defineProperties(p, { [s3]: {value: "yes值"}, [s4]: {value: "no值"} }); Object.defineProperties(p,{ "abc":{value:"abc的值"}, "qwe":{value:"qwe的值"} }); console.log(p); // {Symbol(foo): 'foo值', Symbol(bar): 'bar值', Symbol(yes): 'yes值', Symbol(no): 'no值'} // 返回对象实例的符号属性数组 console.log(Object.getOwnPropertySymbols(p)); // [Symbol(foo), Symbol(bar), Symbol(yes), Symbol(no)] // 返回对象实例的常规属性数组 console.log(Object.getOwnPropertyNames(p)); // ['abc', 'qwe'] // 返回同时包含常规和符号属性描述符的对象 console.log(Object.getOwnPropertyDescriptors(p)); // 返回符号类型和常规类型的键 console.log(Reflect.ownKeys(p)); // ['abc', 'qwe', Symbol(foo), Symbol(bar), Symbol(yes), Symbol(no)]
Object对象
- 对象就是一组数据和功能的集合
- 通过new操作符后跟对象类型的名称来创建对象
- Object是派生其他对象的基类
- 每个Object的实例都有属性和方法
- constructor:用于创建当前对象的函数
- hasOwnProperty(propertyName):用于判断当前对象实例中是否存在给定的属性
- isPrototypeOf(object):判断当前对象是否是另一个对象的原型
- propertyIsEnumerable(propertyName):判断给定的属性是否可以使用for-in语句枚举
- toLocaleString():返回对象的字符串表示,这个字符串返回对象所在的本地化执行环境
- toString():返回对象的字符串表示
- valueOf():返回对象对应的字符串,数字,布尔值表示