js知识梳理一

数据类型的详细剖析

  1. number数字类型
    NaN:not a number 但是它是数字类型的
    isNaN:检测当前值是否不是有效数字,返回true代表不是有效数字,返回false是有效数字

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    //=>语法:isNaN([value])
    var num=12;
    isNaN(num); //->检测num变量存储的值是否为非有效数字 false

    isNaN('13') =>false
    isNaN('珠峰') =>true
    isNaN(true) =>false
    isNaN(false) =>false
    isNaN(null) =>false
    isNaN(undefined) =>true
    isNaN({age:9}) =>true
    isNaN([12,23]) =>true
    isNaN([12]) =>false
    isNaN(/^$/) =>true
    isNaN(function(){}) =>true

    重要:isNaN检测的机制
    1、首先验证当前要检测的值是否为数字类型的,如果不是,浏览器会默认的把值转换为数字类型

    把非数字类型的值转换为数字
    - 其它基本类型转换为数字:直接使用Number这个方法转换的

    [字符串转数字]
    Number('13') ->13
    Number('13px') ->NaN 如果当前字符串中出现任意一个非有效数字字符,结果则为NaN
    Number('13.5') ->13.5 可以识别小数

    [布尔转数字]
    Number(true) ->1
    Number(false) ->0

    [其它]
    Number(null) ->0
    Number(undefined) ->NaN

    - 把引用数据类型值转换为数字:先把引用值调取toString转换为字符串,然后再把字符串调取Number转换为数字

    [对象]
    ({}).toString() ->'[object Object]' ->NaN

    [数组]
    [12,23].toString() ->'12,23' ->NaN
    [12].toString() ->'12' ->12

    [正则]
    /^$/.toString() ->'/^$/' ->NaN

    Number('') ->0
    [].toString() ->''
    => isNaN([]):false

    2、当前检测的值已经是数字类型,是有效数字返回false,不是返回true(数字类型中只有NaN不是有效数字,其余都是有效数字)
  2. parseInt / parseFloat

    等同于Number,也是为了把其它类型的值转换为数字类型

和Number的区别在于字符串转换分析上

Number:出现任意非有效数字字符,结果就是NaN

parseInt:把一个字符串中的整数部分解析出来,parseFloat是把一个字符串中小数(浮点数)部分解析出来

1
2
3
4
parseInt('13.5px') =>13
parseFloat('13.5px') =>13.5

parseInt('width:13.5px') =>NaN 从字符串最左边字符开始查找有效数字字符,并且转换为数字,但是一但遇到一个非有效数字字符,查找结束
  1. NaN的比较
    1
    NaN==NaN:false NaN和谁都不相等,包括自己

布尔类型

只有两个值:true / false

如何把其它数据类型转换为布尔类型?

  • Boolean
  • !
  • !!

规律:在JS中只有“0/NaN/空字符串/null/undefined”这五个值转换为布尔类型的false,其余都转换为true


null && undefined

都代表空或者没有

  • null:空对象指针
  • undefined:未定义

null一般都是意料之中的没有(通俗理解:一般都是人为手动的先赋值为null,后面的程序中我们会再次给他赋值)

1
2
3
var num = null; //=>null是手动赋值,预示着后面我会把num变量的值进行修改
...
num = 12;

undefined代表的没有一般都不是人为手动控制的,大部分都是浏览器自主为空(后面可以赋值也可以不赋值)

1
2
3
var num; //=>此时变量的值浏览器给分配的就是undefined
...
后面可以赋值也可以不赋值

object对象数据类型

普通对象

  • 由大括号包裹起来的
  • 由零到多组属性名和属性值(键值对)组成

属性是用来描述当前对象特征的,属性名是当前具备这个特征,属性值是对这个特征的描述(专业语法,属性名称为键[key],属性值称为值[value],一组属性名和属性值称为一组键值对)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//=>对象的操作:对键值对的增删改查
语法:对象.属性 / 对象[属性]

[获取]
obj.name
obj['name'] 一般来说,对象的属性名都是字符串格式的(属性值不固定,任何格式都可以)

[增/改]
JS对象中属性名是不允许重复的,是唯一的
obj.name='zhangsan'; //=>原有对象中存在NAME属性,此处属于修改属性值
obj.sex='男'; //=>原有对象中不存在SEX,此处相当于给当前对象新增加一个属性SEX
obj['age']=28;

[删]
彻底删除:对象中不存在这个属性了
delete obj['age'];

假删除:并没有移除这个属性,只是让当前属性的值为空
obj.sex=null;

在获取属性值的时候,如果当前对象有这个属性名,则可以正常获取到值(哪怕是null),但是如果没有这个属性名,则获取的结果是undefined
obj[‘friends’] =>undefined

1
一个对象中的属性名不仅仅是字符串格式的,还有可能是数字格式的

var obj = {
name:’珠峰培训’,
0:100
};
obj[0] =>100
obj[‘0’] =>100
obj.0 =>Uncaught SyntaxError: Unexpected number


1
2
3
4
5
6
7
8
9
10
11
12
13
var obj = {
name:'hello',
0:100
};
obj[0] =>100
obj['0'] =>100
obj.0 =>Uncaught SyntaxError: Unexpected number

当我们存储的属性名不是字符串也不是数字的时候,浏览器会把这个值转换为字符串(toString),然后再进行存储

obj[{}]=300; =>先把({}).toString()后的结果作为对象的属性名存储进来 obj['[object Object]']=300

obj[{}] =>获取的时候也是先把对象转换为字符串'[object Object]',然后获取之前存储的300
1
2
3
4
5
6
7
8
9
10
数组对象(对象由键值对组成的)
var oo = {
a:12
};
var ary = [12,23]; //=>12和23都是属性值,属性名呢?

通过观察结果,我们发现数组对象的属性名是数字(我们把数字属性名称为当前对象的索引)
ary[0]
ary['0']
ary.0 =>报错

关于条件可以怎么写?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// >= / <= / == 常规比较
if(0){
//=>不管你在条件判断中写什么,最后总要把其计算出TRUE/FALSE来判断条件是否成立(把其它类型的值转换为布尔类型,只有 0/NaN/''/null/undefined 是false,其余都是true)
}

if('3px'+3){
//=>在JS中,+ - * / % 都是数学运算,除 + 以外,其余运算符在运算的时候,如果遇到了非数字类型的值,首先会转换为数字类型(Number),然后再进行运算

//=>+ 在JS中除了数学相加,还有字符串拼接的作用(如果运算中遇到了字符串,则为字符串拼接,而不是数学相加)

'3px'+3 =>'3px3'
}
if('3px'-3){
'3px'-3 =>NaN
}

typeof

js中常用的检查数据的方式之一,还有以下几种:

  • instanceof
  • constructor
  • Object.prototype.toString.call()
1
2
3
4
5
6
7
8
9
10
11
12
13
语法:typeof [value] =>检测value的数据类型
返回值:使用typeof检查数据出来的结果是字符串类型。
"number"/"string"/"boolean"/"undefined"/"object"/"function"

typeof null =>"obejct" 因为null代表空对象指针(没有指向任何的内存空间)
typeof检测数组/正则/对象,最后返回的都是"object",也就是基于这种方式无法细分对象

console.log(typeof []);
//=>"object"

console.log(typeof typeof []);
//=>typeof "object"
//=>"string"

switch case中每一种case情况的比较都是基于”===”绝对相等来完成的

1
2
3
4
5
'10'==10 
=>true 相等比较,如果等号左右两边的类型不一样,首先会转换为一样的数据类型,然后再进行比较
=>当前案例中,就是把字符串'10'转换为数字了,然后再比较的

'10'===10 绝对比较,如果两边的数据类型不一样,则直接不相等,它要求类型和值都完全一样才会相等(真实项目中为了保证代码的严谨性,我们应该更多使用绝对比较)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ES3标准中:
//=>创建函数
function 函数名([参数]){
函数体:实现功能的JS代码
}
//=>函数执行
函数名();

=====
ES6标准中创建箭头函数:
let 函数名(变量名)=([参数])=>{
函数体
}
函数名();

let fn=()=>{
let total=10;
...
};
fn();

[创建函数]

  1. 函数也是引用类型,首先会开辟一个新的堆内存,把函数体中的代码当做“字符串”存储到内存中(对象向内存中存储的是键值对)
  2. 把开辟的堆内存地址赋值给函数名(变量名)

此时我们输出fn(切记不是fn())代表当前函数本身
如果我们执行fn(),这是把函数执行
所以是否加小括号是两种不同本质的操作

[函数执行]
目的:把之前存储到堆内存中的代码字符串变为真正的JS代码自上而下执行,从而实现应有的功能

1.函数执行,首先会形成一个私有的作用域(一个供代码执行的环境,也是一个栈内存)
2.把之前在堆内存中存储的字符串复制一份过来,变为真正的JS代码,在新开辟的作用域中自上而下执行

函数中的参数

参数是函数的入口:当我们在函数中封装一个功能,发现一些原材料不确定,需要执行函数的时候用户传递进来才可以,此时我们就基于参数的机制,提供出入口即可

1
2
3
4
5
6
7
8
9
10
11
12
13
//=>此处的参数叫做形参:入口,形参是变量(n/m就是变量)
function sum(n,m){
//=>n和m分别对应要求和的两个数字
var total = 0;
total = n + m;
console.log(total);
}

//=>此处函数执行传递的值是实参:实参是具体的数据值
sum(10,20); //=>n=10 m=20
sum(10); //=>n=10 m=undefined
sum(); //=>n和m都是undefined
sum(10,20,30); //=>n=10 m=20 30没有形参变量接收

【ECMAScript】

1.变量

可变的量称之为变量,在编程语言中,变量是一个虚拟的概念,变量是用来存储和代表具体值的,只不过它存储和代表的值是可以修改的

JS中定义变量的方式:
不管变量存储的值是什么类型的,统一用以下关键词都可以创建

  • var 创建变量
  • function 创建一个函数
  • let (这个及以下是ES6语法中创建变量) 创建变量
  • const 创建常量
  • class 创建类
  • import ES6中的模块导入
1
2
3
4
5
6
var num = 12; //=>创建了一个变量num,给他存储了一个值12
num+10 //=>把num存储的值12获取到,然后再加上10
num = 100; //=>所谓变量,就是一个名字存储和代表的值能发生改变

const m = 100;
m = 200; //=>Uncaught TypeError: Assignment to constant variable. 基于const声明的名字,存储的值是不可以被修改的,我们把它叫做常量

====
【基本类型操作机制 =>值类型】

值类型操作都是“按照值来操作的”

  • 赋值的时候,也是直接的把这个值赋值给变量(或者说和变量关联)
  • 一个变量把自己的值赋值给另外一个变量的时候,也是重新开辟一个新的位置,把原有变量存储的值放到新位置一份(新老位置各有相同的值,但是是独立分开的,没有关联),在把新位置上的值赋值给新变量

====
【引用数据类型】

引用数据类型,操作的时候,都是按照“空间的引用地址来操作的”

  1. 首先不能像基本基本值一样在作用域中开辟位置存储,需要额外单独开辟一个新的空间(有一个16进制的地址,通过地址可以找到空间)
  2. 对于对象数据类型来说,它会把自己本身的键值对依次存储到这个空间中(对于函数来说,在空间中存储的是函数体中的代码字符串)
  3. 引用类型是按照引用地址来操作的,所以给变量赋的值是空间的地址,而不是对象本身,以后的操作都是通过地址找到空间然后再操作

====

【堆占内存】
在JS中有两个重要的内存:堆内存/栈内存

  • 栈内存
    • 提供代码执行的环境
    • 基本类型值都是直接的存储在栈内存中的
  • 堆内存
    • 引用类型值都存储在堆内存中

===========================

-------------本文结束感谢您的阅读-------------