书籍:
JS高级程序设计
es6.ruanyifeng.com
你不知道的 javascript(底层源码,但不够底层)
javascript 权威指南
1.1 什么是 JS
JS 做客户端语言
按照相关的 JS 语法,去操作页面中的元素,有事还要操作浏览器里面的一些功能
JS 的构成部分
- ECMAScript3/5/6...: JS 的语法规范
包含变量 数据类型 操作语句 ...
- DOM (Document object model)文档对象模型
提供一些 JS的属性和方法来操作页面中的 DOM 元素
- BOM (Browser object model) 浏览器对象模型
提供一些 JS的属性和方法,用来操作浏览器
1.2 JS 中的变量(Variable)
变量:可变的量,用于存储不同的字面量
1.2.1 创建变量的几种方式(简单介绍)
- var
- let
- const
- function
- class
- import
- Symbol
// ES3
var a = 12;
a = 13;
console.log(a); // 输出的是变量a 代表的值 13
// ES6
let b = 100;
b = 200;
const c = 1000;
c = 2000; // 报错 因为 const 创建的变量存储的值不能被修改(特殊变量 '常量')
//创建函数也相当于在创建变量
function fn(){}
//创建类也相当于在创建变量
class A{}
// ES6 的模块导入也可以创建变量
import B from './B.js'
//Symbol 创建唯一值
let n = Symbol(100);
let m = Symbol(100);
n == m false
1.3 JS 的命名规范
- 严格区分大小写
let Test = 100;
console.log(test); // 无法输出,因为第一个字母小写了
- 使用数字 字母 下划线和$,数字不能作为开头
let $box; // 可以;一般用 JQuery获取的元素以$开头
let _box; // 可以;一般公共变量都是以_开头
let 1box; // 不可以
// 很多命名方式都是约定俗成的
-
使用驼峰命名法
首字母小写,其余每一个有意义单词的首次吗都要大写
命名尽可能语义化明显,使用英文单词
常用的缩写: 新增 add insert create new 修改 update 删除 delete del remove rem 查询 sel select query get 信息 info -
不能使用关键字或保留字
当下有特殊含义的是关键字,未来可能会成为关键字的叫做保留字
摘自 JavaScript高级程序设计(第四版)
1.4 JS 常用数据类型
基本数据类型
- 数字 number
- 常规数字和 NaN(not a number)
- 字符串 string
- 所有用单引号 双引号 反引号 包起来的都是字符串
反引号包起来的叫模板字符串(ES6)
- 布尔 boolean
- true / false
- 空对象指针 null
- 未定义 undefined
引用数据类型
- 对象数据类型 object
- {} 普通对象
- [] 数组对象
- /^$/ 正则对象
- Math 数学函数对象
- Date 日期对象
- ...
- 函数数据类型 function
1.4.1 基本数据类型
1.4.1.1 number 数字类型
-
包含: 常规数字 NaN
- NaN not a number 不是一个数,但是隶属于数字类型
-
验证一个值是不是数字类型
-
== : 进行比较
-
是否 == NaN ?
NaN 和任何值(包括自己)都不相等: NaN != NaN
所以不能用相等的方式判断是否为有效数字
console.log('AA' == NaN); //false console.log(NaN == NaN); //false -
isNaN
检测一个值是否为非有效数字,如果不是有效数字,返回 TRUE,反之返回 FALSE
语法: isNaN([val]) [val]参数占位符
底层机制: 在使用 isNaN 进行检测时,首先会验证检测的值是否为数字类型,如果不是,先基于 Number()这个方法,把值转换为数字类型,然后在检测
console.log(isNaN(10)); // false console.log(isNaN('AA')); //true console.log(isNaN('10')); // false ==> isNaN 的底层机制 Number('10') => 10 isNaN(10) => FALSE -
-
把其他类型值转换为数字类型 - Number([val])
-
把字符串转换为数字类型
把字符串转换为数字,只要字符串中包含任意一个非有效数字(第一个小数点除外)结果都是 NaN.
注意,空字符串会变为数字零.
console.log(Number('12.5')); // => 12.5 console.log(Number('12.5px')); // => NaN console.log(Number('12.5.5')); // => NaN console.log(Number('')); // => 0 console.log(Number(' ')); // => 0 -
把布尔值转换为数字类型
console.log(Number(true));//1 console.log(Number(false));//0 console.log(isNaN(false));//=> false console.log(isNaN(true));//=> false -
null
-
undefined
console.log(null); //=> 0 空指针还是有东西的 console.log(undefined); //=> NaN 未定义表示没有赋值,没有赋值就没有值,所以是 NaN -
把引用数据类型转为数字类型
先把它基于 toString 方法转换为字符串,然后再转换为数字
console.log(Number({name: '10'}));//=> NaN
console.log(Number({}));//=> NaN
//-------------------原理------------------------
//{}/ {xxx:"xxx"}.toString => "[object Object]" => NaN
console.log(Number([]));//=> 0
console.log(Number([12]));//=> 12
console.log(Number([12,23]));//=> NaN
//-------------------原理------------------------
//[].toString([]) => ''
//[].toString([12]) => 12
//[].toString([12,23]) => '12,23'
- 用其他方法把其他数据类型转换为数字
- parseInt([val],[进制])
- 识别整数
- parseFloar([val],[进制])
- 能识别到小数
主要针对字符串转换为数字的方法
对于非字符串,先转换为字符串
对于字符串来说,是从左到右依次查找有效数字字符,直到遇到非有效数字字符,停止查找(不管后面是否还有数字,都不再找了),把找到的当做数字返回.如果一开始就遇到非有效数字,直接返回 NaN.
let str = '12.5px';
console.log(Number(str));//=> NaN
console.log(parseInt(str));// => 12
console.log(parseFloat(str));// => 12.5
console.log(parseFloat('width:12.5px'));// => NaN
- == 进行比较的时候
- 可能要出现把其他类型值转换为数字再比较 ==============================比较区别============================= Number([val])走V8底层机制
parseInt/parseFloar走额外方法,用于处理字符串;如果不是字符串就先变成字符串再进行查找
console.log(Number(true)); // 1
console.log(parseInt(true)); // => NaN
1.4.1.2 string 字符串数据类型
所有用单引号 双引号 反引号(撇 ES6模板字符串)包起来的都是字符串
- 把其他类型值转换为字符串
-
[val].toString()
-
字符串拼接
-
[val].toString()
//=================数字转直接加引号=================
console.log(12.toString());// 会报错 sytexError 语法错误
let a = 12 ;
console.log(a.toString()); // => '12'
console.log((NaN).toString()); // => 'NaN'
//=================布尔转直接加引号=================
console.log(true.toString()); // => 'true'
console.log(false.toString());// => 'false'
//null 和 undefined 禁止直接 toString
// 主要原因是浏览器保护不让使用 toString
// 可以使用 string 强制转换 null 和 undefined
// 转换为字符串的结果是'null' 'undefined'
console.log(null.toString()); // => 报错 TypeError 禁止使用
console.log(undefined.toString());// => 报错 TypeError 禁止使用
//=================引用类转=================
//普通对象是例外
//普通对象.toString() 的结果是"[object Obkect]"
//因为 Object.prototype.toString 方法不是转换为字符串的,二是用来检测数据类型的
//数组 去[]加引号变成字符串
[].toString() => '';
[12].toString() => '12';
[12,23].toString() => '12,23';
// 正则 直接加引号
/^$/.toString() => '/^$/';
-
字符串拼接
四则运算法则中除 + 加法以外,其余都是数学计算,只有加法可能存在字符串拼接
一旦遇到字符串, 则不是数学运算,而是字符串拼接
console.log('10'+ 10); // => '1010'
console.log('10'- 10); // => 0
// 先转换为数字再进行数学计算,使用浏览器内置的 Number('10') => 10
// 10 - 10 => 0
console.log('10px'- 10); // => NaN
// 先转换为数字再进行数学计算,使用浏览器内置的 Number('10') => NaN
// NaN - 10 => NaN
- 练习
let a = 10 + null + true + [] + undefined + '字符串' + null + [] + 10 + false
console.log(a);
/* null 转换为number,数学运算
10 + 0 => 10
true 转换为 number, 数学运算
10 + 1 => 11
[]转换为数字,先转换为空串,出现字符串与+ ,停!!! 立刻拼串,不再往下转数字
11+'' => '11'
'11' + undefined => '11undefined'
...拼串... => '11undefined字符串null10false'
*/
1.4.1.3 boolean 布尔数据类型
只有两个值 true / false
-
把其他类型值转换为布尔类型
只有 0、 NaN、 null、 ' '(不可以有空格) 、undefined 五个值转换为 FALSE,其余都转换为 TRUE,没有任何特殊情况
- Bollean([val])
console.log(Boolean(0)); // => false
console.log(Boolean('')); // => false
console.log(Boolean(' ')); // => true
console.log(Boolean(null));// => false
console.log(Boolean(undefined));// => false
console.log(Boolean([]));// => true
console.log(Boolean([12])); // => true
console.log(Boolean([-1])); // => true
- !/!!
! : 取反,转为布尔,然后再取反,并返回布尔值类型
!! : 取反再取反,相当于转换为布尔值 等价于 Boolean
console.log(!1); // => false
console.log(!!1); // => true
- 条件判断
如果条件只是一个值,不是 == / === / != / >= 等这些比较运算符,
是要把这个值先转换为布尔类型,然后验证真假
if(1){
console.log('哈哈'); //'哈哈'
}
if('3px' + 3){
// 拼串=> '3px3' => true
console.log('喝喝'); //'喝喝'
}
if('3px' - 3){
// Number() => NaN - 3 => NaN => false
console.log(' 嘿嘿'); //不打印
}
1.4.1.4 null 和 undefined
null 和 undefined 都代表的是没有
- null : 意料之中(一般都是开始不知道值,先手动设置为 null,后期再给予赋值)
let num = null ;
...
num = 12;
// VS
let num = 0
// 一般最好用 null 作为初始空值,因为 0 不是空值,在栈内存中有自己的存储空间(占了位置)
- undefined : 意料之外(不是我能决定的)
let num ; // => 创建一个变量不赋值,默认值是 undefined
...
num = 12 ;
- 暂时的总结(未完待续) null
1) 在我们不确定一个变量具体数据类型的时候,我们可以先赋值为null,后面可以再给具体的值。
2) 作为对象原型链的终点。
3) 获取 DOM 获取不到的时候。
undefined
1)定义了变量没有给值,显示 undefined。
2)定义了形参,没有传实参,显示 undefined。
3)对象属性名不存在时,显示 undefined。
4)函数没有写返回值,即没有写return,拿到的是 undefined。
5)写了return,但没有赋值,拿到的是 undefined。