变量和常量
变量variable:值是可以变的;
变量不是具体的值,只是一个用来存储具体值的容器或者代名词,因为它存储的值可以改变,所以称为变量,变量其实只是一个无意义的名字,他代表的意义都是其存储的那个值;
一个变量只能代表一个值
创建变量
1、var
2、function创建函数(函数名也是变量,只不过存储的值是函数类型而已)
3、let
4、const创建ES6常量
5、import基于ES6的模块规范导出需要的信息
6、class基于ES6创建类
var 和let的区别
1、var有变量提升,let没有变量提升
2、let不能重复命名
3、全局作用域下let声明的变量和window没关系
4、let存在暂时性死区
5、let能形成块级作用域
1  | //语法:  | 
常量:值是不可变的,任何一个具体的数据值都是常量,例如12就是一个常量
不能给一个常量重新赋值
1  | //var 变量名=变量值;  | 
数据类型分类和检测
JS中的数据类型
基本数据类型(值类型)
number:数字string:字符串(单引号双引号都行)boolean:布尔null空对象指针undefined未定义
引用数据类型
object对象数据类型{}普通数据类型[]数组/^$/正则- 日期对象
 Math数学对象- 。。。
 
function函数数据类型- ES6中新增一个特殊数据类型:
Symbol,唯一的值 
数据类型检测
typeof :检测数据类型的运算符,返回的结果是字符串
返回的结果是字符串,字符串中的内容证明了这个值是属于什么类型的
1、基础数据类型除了typeof null是'object'以外,typeof都是自己的数据类型
2、引用数据类型分为:对象数据类型和函数数据类型
3、对象数据类型分为:{} 普通对象型,[]  数组, /^$/  正则,日期对象等
4、对象数据类型和null的typeof都是‘object’
5、函数数据类型的typeof都是‘function’
局限性:
1、typeof null  不是'null'  而是  'object' :因为null虽然是单独的一个数据类型,但是它原本意思是空对象指针,浏览器用typeof  检测  的时候会把它当做对象来检测
2、使用typeof 无法具体细分出  到底是数组还是正则 ,因为返回结果 都是  'object'
面试题:
1  | typeof typeof [] => string  | 
1  | typeof 12 => 'number'  | 
XX  instanceof  YY,检测当前实例是否属于某个类
解决了typeof无法识别是数组还是正则的问题
1  | function Fn(){  | 
xxx.constructor: 获取当前实例的构造器
1  | var test=1;  | 
1  | function employee(name,job,born) {  | 
Object.prototype.toString.call : 获取当前实例的所属类信息
Object.prototype.toString方法,判断某个对象之属于哪种内置类型。分为
null、string、boolean、number、undefined、array、function、object、date、math
判断基本类型:
1  | Object.prototype.toString.call(null); // "[object Null]"  | 
判断原生引用类型:
1  | //**函数类型**  | 
字符串
在
js当中单引号和双引号包起来的都是字符串:"aa" =>string;'[1,2,3]' => string
常用方法:
charAt
chartCodeAt
substr
substring
slice
toUpperCase
toLowerCase
indexOf
lastIndexOf
split
replace
match…
其他类型转换为字符串:除了普通对象都是直接加引号(数组也很特殊)
发生情况
1、基于alert、confirm、prompt、document.write等方法输出内容的时候,会把输出的值转化为字符串然后输出,这些输出答案必须加单引号
2、基于+进行字符串拼接的时候
3、把引用数据类型值转化为数字的时候,首先会转化为字符串,然后再转换为数字
4、给对象设置属性名,如果不是字符串,首先转化为字符串,然后再当做属性存储到对象中(对象的属性名只能是数字或者字符串)
5、手动调用toString、toFixed、join、String等方法的时候,也是为了转化为字符串
1  | var n=Math.PI; => 3.141592654  | 
转换规律
1、浏览器默认转换`的时候调用的都是 toString
2、除了普通对象都是直接加引号(数组也很特殊)
1->'1'(手动调用toString不行);NaN->'NaN';null->'null'(手动调用toString不行) ;[] -> '';[12] -> '12';[12,13] -> '12,13';function fn(){}->'function fn(){}';new Date().toString()->'2018.08.27'
3、不管是啥样的普通对象,最终结果都是'[object Object]'
普通对象:{ name:'name'}  ->  '[object Object]'
| 数据类型 | 例子 | return | 
|---|---|---|
| 字符串 | “foo”.toString() | “foo” | 
| 数字 | 1.toString() | Uncaught SyntaxError: Invalid or unexpected token | 
| 布尔值 | false.toString() | “false” | 
| undefined | undefined.toString() | Uncaught TypeError: Cannot read property 'toString' of undefined | 
| null | null.toString() | Uncaught TypeError: Cannot read property 'toString' of null | 
| String | String.toString() | “function String() { [native code] }” | 
| Number | Number.toString() | “function Number() { [native code] }” | 
| Boolean | Boolean.toString() | “function Boolean() { [native code] }” | 
| Array | Array.toString() | “function Array() { [native code] }” | 
| Function | Function.toString() | “function Function() { [native code] }” | 
| Date | Date.toString() | “function Date() { [native code] }” | 
| RegExp | RegExp.toString() | “function RegExp() { [native code] }” | 
| Error | Error.toString() | “function Error() { [native code] }” | 
| Promise | Promise.toString() | “function Promise() { [native code] }” | 
| Obejct | Object.toString() | “function Object() { [native code] }” | 
| Math | Math.toString() | “[object Math]” | 
手动调用toString不行的情况
1  | 1.toString() //报错  | 
number数字
JS除了常规数字 增加了一个number类型的数据NaN
Number(),把其它数据类型的值转换为number类型的
1、字符串转数字,从左到右只要出现任何一个非有效数字字符,最后结果都是NaN
Number(‘12’) => 12
Number(‘12px’) => NaN
Number(‘’) => 0
Number(‘ ‘) => 0 Space
Number(‘\n’) => 0 换行符
Number(‘\t’) => 0 制表符(Tab)
2、布尔转数字
- Number(true) => 1
 - Number(false) => 0
 
3、其他转数字
- Number(null) =>0
 - Number(undefined) => NaN
 - Number(‘’) => 0
 - Number(NaN) => NaN
 
4、引用数据类型转数字,首先需要把引用数据类型转换为字符串
把
引用数据类型转换为number,首先需要把引用数据类型转换为字符串(用toString),再把字符串转换为number即可;数组:[] => ‘’ => 0; [12] => ‘12’ => 12; [12,23] => ‘12,13’ => NaN;
对象Number({aaa:’aaa’}) => NaN : Number({}) => ‘[object Object]’ => NaN
正则:
/^$/.toString()-> ‘/^$/‘ ->NaN
1  | Number('12') => 12  | 
parseInt():转化为整数
1、只使用一个参数时,从左到右依次查找有效数字字符,直到遇到非有效数字字符为止
把其他数据类型的值转换为number,把一个字符串中的整数部分解析出来
提取规则:
从左到右依次查找有效数字字符,直到遇到非有效数字字符为止(不管后面是否还有,都不找了),把找到的转换为数字;parseInt(‘12px13’) => 12;parseInt(‘px12’) => NaN识别不了小数点后面的数字 转化为整数
转化的不是字符串时先转化为字符串
1  | Number('12px') => NaN  | 
2、使用两个参数时parseInt(string, radix),radix :2 ~ 36
| 参数 | 描述 | 
|---|---|
| string | 必需。要被解析的字符串。 | 
| radix | 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。 | 
示例:
parseInt(17, 8) 相当与8进制的17转为 10进制的数据
1  | 1 7  | 
parseInt(157, 8) 8进制157 转10进制
1  | 1 5 7  | 
parseInt(154, 6) 6进制154 转10进制
1  | 1 5 4  | 
依次类推
8进制 一个bit最大到 7
2进制 一个bit最大到 1
10进制 一个bit最大到 9
超出的都不是有效字符(可以当做不存在)
8进制18 =》 余数8超出是无效的 删除后 只剩 1, 相当于 8进制的1转10进制 =》1
1  | let arr=[1,2,3]  | 
parseFloat():转化为小数,可以识别小数点
在parseInt的基础上可以识别小数点,把一个字符串中小数(浮点数)部分解析出来
1  | parseInt('12.5px') => 12  | 
NaN:
not a number :不是一个有效的数字,但是属于number类型
1、typeof NaN => ‘number’
2、NaN和任何其他值都不相等包括他自己
NaN === NaN => false ;
3、NaN加任何数据(除了字符串)结果都是NaN
isNaN:检测是否为有效数字的唯一方法
用来检测
是否是非有效数字,如果是非有效数字,返回结果是true;是数字false检测是否为有效数字的唯一方法
当我们使用isNaN检测值的时候,如果检测的值不是number数据类型的时候,浏览器会默认的把值先转换为number类型(使用Number()),然后再去检查
isNaN(‘12’) =》 false
数字类型中只有NaN不是有效数字,其余都是有效数字
用
isNaN检测是false(是数字的):true,false,null,纯数字字符串,只有一项并且为数字的数组,因为这几个调用Number结果都是数字
1  | isNaN([]) => isNaN(Number([])) => isNaN(Number(toString([]))) => isNaN(Number('')) => isNaN(0) => false  | 
布尔值(JS真假)
只有两个值:true false
Boolean():把其它数据类型转换为布尔数据类型
假(false)只有以下五种: 0 、 NaN、空字符串、null、undefined
真(true):除了以上五种都是true
其他值转化为布尔值
只有“0、NaN、‘’、null、undefined”五个值转化为false,其余都转化为true
基于!/!!/Boolean等方法转换
条件判断中的条件都会转换为布尔值
1  | if(n){  | 
!,取反,先把值转换为布尔类型值,然后取反
叹号在JS中还有一个作用叫
取反,先把值转换为布尔类型值,然后取反
!1=>false;![]=>false;!0=>true
!!,取两次反相当于没有取反
在一个叹号取反的基础上再取反 ,取两次反相当于
没有取反,但是已经把其他的类型转换为了布尔类型,效果和Boolean一样 :!![]=>true;!!null=>false;!!1=>true;
null 和undefined
null: 空,没有
undefined:未定义 没有‘’:空字符串 没有
0:也可以理解为没有
undefined:未定义
1、变量提升阶段只声明不定义:默认值  undefined
2、严格模式下:没有明确的执行主体,this就是undefined
3、对象没有这个属性名,属性值是undefined
4、函数定义形参不传值:默认是undefined
5、函数没有返回值(没有return或者 直接return;),默认返回就是 undefined
null:空
1、手动设置变量的值或者对象某一个属性值为null(此时不赋值,后边会赋值)
2、在JS的DOM元素获取中,如果没有获取到指定的元素对象,结果一般都是null
3、Object.prototype.__proto__的值也是null
4、正则捕获的时候,没有捕获到结果,默认也是null
document.parentNode =>
有这个属性但是找不到 是 nulldocument.parentnode =>
没有这个属性是 undefined(parentnode是不存在的 )
空字符串和null的区别
都是去种树
空字符串属于挖了坑没有种,
null 是坑都没挖
空字符串相对于null来说开辟了内存,消耗了一点点性能
null和undefined的区别
null 一般都是暂时没有赋值,预期中以后会有
在js中null一般是手动先赋值值为null,后期再给其赋具体值
undefined:完全没在预料之内,一般都不是人为手动控制的,大部分都是浏览器自主为空;后面可以赋值也可以不赋值
普通对象object
var obj={name:’aa’,age:19}
每一个对象都是由0到多组
属性名(key、键):属性值(value、值)组成的,或者说是由多组键值对组成的,每一组键值对中间用逗号分隔
属性是用来描述当前对象特点特征的,属性值是对这个特征的描述对象的
属性名只能是字符串或者数字格式的,存储的属性值可以是任何的数据类型
当我们存储的属性名不是字符串也不是数字的时候,浏览器会把这个值转化为字符串(toString),然后 进行存储;obj[{}]=300 把{}.toString()后的结果作为属性名存储进来obj[‘[object Object]’]=300obj[{}] =>获取的时候也是先把对象转换为字符串’[object Object]’,然后获取之前存储的300
操作:
属性名.属性值;忽略了属性名的单双引号,obj.name
属性名[属性值],不能忽略单双引号,obj[‘name’]
如果属性名是数字:
obj.0 不行 ; 只能用中括号方式获取:obj[0] 或者 obj[‘0’],obj[0] === obj[‘0’]
如果操作的属性名在对象中不存在,获取的结果是undefined
设置、修改:一个对象的属性名是不能重复的,如果之前存在就是修改属性值的操作,如果不存在就是新设置属性的操作:obj.aaa=18;obj[‘aaa’]=19;
删除:delete obj.aaa
假删除:让其属性值为null,但是属性还在对象中:obj.aaa=null
真删除:把整个属性都在对象中移除,delete obj.aaa;
1  | var obj={name:'aaa',age:18}  | 
数组
var arr=[12,13]
中括号包裹起来,包含0到多项内容
数组对象的属性名是数字,我们把数字属性名称为当前对象的索引
获取
arr[0]
arr[‘0’]
arr.0 不行 报错
正则
var reg=/^$/
由元字符组成一个完整的正则
Symbol
创建出来的是唯一的值,没有和他相等的
1  | var a=Symbol('aaa')  |