JS基础知识(基础的不能再基础...)

在这里插入图片描述

javascript的发展史

关于前端的发展史,推荐看阮一峰老师的这个解说,介绍了关于javascript语言的诞生、javascriptECMAScript的关系、javascriptJava的关系(这就跟苹果与苹果手机的问题类似吧,哈哈)、javascript的版本以及它发展的过程等等;链接地址https://javascript.ruanyifeng.com/introduction/history.html

浏览器

客户端通过网址去访问服务器,服务器返回的是前端代码,浏览器把返回的代码进行解析渲染,最后渲染成为用户可看见的页面
=>这就是浏览器的内核或者引擎做的事情,不同的浏览器渲染机制不一样,因为它们采用不同的内核来进行处理

按照不同的内核浏览器的分类

以谷歌浏览器webkit内核为主 (V8引擎)

  • 谷歌浏览器 Chrome
  • 苹果浏览器 Safari
  • 国产浏览器
  • 360普通浏览器
  • 360极速浏览器
  • 猎豹浏览器
  • 搜狗浏览器
  • QQ浏览器
  • UC浏览器
  • 欧朋浏览器 Opera (v14版本的时候)

gecko内核

  • 火狐浏览器 Firefox

Trident内核

  • IE浏览器

Presto内核

  • 欧朋

控制台的使用

打开开发者工具:F12/FN + F12 (再或者浏览器页面: 右击–>检查)

  • Elements 包含了当前页面中所有的结构和样式,基于它可以快速查看和调整页面的样式和结构等
  • Console 控制台 ,在JS中,我们可以向控制台输出一些内容,来进行项目的调试;如果项目程序出现问题,也可以在控制台查看报错信息,也可以在控制台编写代码,做一些测试…
  • Network 包含了当前页面所有向服务器发送的HTTP请求信息,一般用于前后端数据交互中的BUG调试以及页面中的性能优化
  • Sources 包含了当前项目的源代码
  • Application 可以看到本地存储的信息(Cookie/LocalStorage/SessionStorage...)以及当前网站中所有加载的图片等信息(抓取一些图片下来)
  • 开启手机模拟器 Toggle Device Toolbar

职业习惯:打开浏览器,第一步就是F12打开控制台

JavaScript中的输出方式

1.console 控制在浏览器控制台输出的

  • console.log() 控制台输出日志(特点:输出任意数据类型的数据,控制台展示的也是对应的数据类型,可以一次性输出多个值)

  • console.dir() 控制台详细输出(特点:输出一个对象或者一个值的详细信息,但是dir不可以输出多个值)

  • console.table() 把数据以表格的形式输出在控制台(特点:把多维的JSON数据以表格的形式输出)

  • console.time() console.timeEnd() 计算出time/timeEnd中间所有程序执行所消耗的时间。预估时间:受到当前电脑性能的影响

  • console.warn() 以警告的方式输出

console.time('AA');
for (let i = 0; i < 99999999; i++) {}
console.timeEnd('AA'); //=>AA: 218.3701171875ms

2.window提示框

  • alert() 弹框输出
    • 是在浏览器窗口中弹出一个提示框,提示框中输出指定的信息
    • 需要等到alert弹出框,点击确定关闭后,后面的代码才会继续执行(alert会阻碍主线程的渲染)
    • alert弹出的内容都会默认转化为字符串
  • confirm()弹框输出
    • 相对于alert来说,给用户提供了 ‘确定’ 和 ‘取消’ 两种选择
    • 创建一个变量,用来接收用户选择的结果,true点击的是确定 false 点击的是取消
  • prompt()弹框输出
    • confirm的基础上给用户提供书写操作的原因等信息
    • 点击的是取消,返回结果是null,点击的是确定,会把用户输入的原因信息返回
let flag = confirm('今天大家都好好学了吗?');
console.log(flag);
let reason = prompt('确定要删除此信息吗?');
console.log(reason);

3.向页面指定的容器中插入内容

  • document.write()
    • alert一样,写入的内容最后都会转换为字符串,然后再写入
  • innerHTML/innerText
    • 向指定容器中插入内容(插入的信息也会变成字符串再插入)
    • innerHTML能够识别标签,而innerText会把所有内容当做普通的文本
    • 添加的内容会覆盖原来的内容,想要不覆盖使用+=
  • value向页面表单元素中输入内容
 document.write('AA');
 document.write(10);   
//结构
<div id="box">
   <h1>哈哈</h1>
</div> 
///*JS操作*//

let box = document.getElementById('box');
box.innerHTML = "内容1";  //=>覆盖原始的所有内容
box.innerText = "内容2";
box.innerHTML += "内容1"; //=>在原始内容上继续增加
box.innerText += "内容2";
box.innerHTML = "<strong>我是重点内容</strong>";
box.innerText = "<strong>我是重点内容</strong>";
//结构
<input type="text" id="userName">    

//JS操作 
let userName = document.getElementById('userName');
userName.value = "我是在JS中插入的内容";

JS组成的三部分

  • ECMAScript(ES3/ES6~9) 定义了JS的语法规范:定义了语言本身的变量、数据值、操作语句、内存管理、逻辑处理…等内容
  • DOM (document object model)文档对象模型,提供对应的属性和方法,可以让JS操作页面中的DOM元素
  • BOM (browser object model) 浏览器对象模型,提供操作浏览器的属性和方法

注意:现在项目开发,一般都是基于Vue/React完成的,基于这两个框架,我们已经不去操作DOM了,我们操作数据,由框架本身帮助我们完成DOM的操作

JS的变量 variable

变量:就是起了一个名字,用来存储(指向)或者代表某个值的(它是一个虚的东西,值才是实在的东西)

JS中创建变量的几种方式

  • ES3 : var
  • ES6 : let、const
  • function 创建函数
  • class 创建一个类
  • import 基于ES6Module或者Common.js规范导入模块

JS中变量命名规范

  • 严格遵循大小写
  • 使用驼峰命名法
  • 由有意义英文组成一个名字,第一个单词首字母小写,其余每一个有意义的单词首字母大写
    • add / insert / create 新增/插入/创建
    • del / delete / remove 删除/移除
    • update修改
    • select / query / get 查询/获取
    • info 信息
  • 由数字、字母、下划线、$组成,并且不能以数字开头
    • 基于$开头:一般代表使用JQ或者其它使用$的类库获取的内容
    • 基于_开头:一般代表是全局或者公共的变量
    • 基于数字区分相似名称的变量
    • 想要分隔单词,可以使用_或者驼峰,但是不能是-
  • 不能使用关键字和保留字
    • 关键字:在JS中有特殊含义的
    • 保留字:未来可能会成为关键字的

代码强迫症:良好的编程习惯、极客精神

JS的数据类型

  • 基本数据类型(值类型/原始值)
    • 数字 number
    • 字符串 string
    • 布尔 Boolean
    • 空对象指针 null
    • 未定义 undefined
    • ES6新增的唯一值类型 symbol
    • BigInt ES6新增的
  • 引用数据类型
    • 对象数据类型 object
      • 普通对象{ }
      • 数组对象[ ]
      • 正则对象/^$/
      • 日期对象 new Date
      • 数学函数对象Math
    • 函数数据类型 function

number数据类型

正数、零、负数、小数
NaN:not a number 不是一个有效数字,但是属于number类型的
Infinity:无穷大的值,也是number类型的

1. 验证n是不是有效数字
  • NaN 和任何数都不相等,包括它本身
  • isNaN 验证一个值是否为非有效数字,如果是有效数字,则返回false,如果不是有效数字,则返回true
  • 在使用isNaN检测的时候,如果被检测的值是非数字类型的值,则需要先把其转化为数字类型,然后再进行检测;

规律:

  • 结果不是false就是true
  • 结合下方的Number()方法来记:

    Number()结果为NaNisNaN的结果就是true;

    Number()结果不为NaNisNaN()结果为false
console.log(1 == 1)  //true
console.log(NaN ==NaN) //false
console.log(isNaN(1));   //=>false
console.log(isNaN(NaN));  //=>true
console.log(isNaN(Infinity)); //=>false

console.log(isNaN('AA')); //=>true
console.log(isNaN('12.5')); //=>false
console.log(isNaN('12.5px')); //=>true
console.log(isNaN([])); //=>false
console.log(isNaN([10])); //=>false
console.log(isNaN([10, 20])); //=>true
console.log(isNaN({})); //=>true
console.log(isNaN(null)); //=>false
console.log(isNaN(undefined)); //=>true
console.log(isNaN(Symbol(1))); //=>报错
2. 把其他类型转化为数字类型
  • Number([value])
  • parseInt ([value])
  • parseFloat([value])
3. Number([value]) 转数字

(是JS内置的转换方法,可以把其他数据类型‘强制转换为数字类型’)

  • 把字符串转化为数字:一但字符串中出现非有效数字字符,则结果为NaN,只有都是有效数字字符,才能转化为具体的数字
  • 把布尔转化为数字:true为1,false为0
  • 把空转化为数字:null 为0 ,undefinedNaN
  • 不能把Symbol()类型转化为数字,否则会报错
  • 对象转化为数字:先把对象转化为字符串,再把字符串转化为数字
    • 普通对象(都为NaN

      • 先把obj转化为字符串,'[object Object]'
      • 把字符串转化为数字 Number('[object Object]')
    • 数组对象( 当数组中有2个或者2个以上的时候为NaN,)

      ary = [10];

      • 先把ary转化为字符串 ‘10’
      • 在把’10’转化为10 //10

      ary = [10,20];

      • 先把ary转化为字符串 ‘10,20’
      • 在把’10,20’转化为数字 //NaN
    • 其余对象格式基本上都会变成数字NaN

  • 函数转化为数字,结果都是NaN

规律:

1 、字符串里面有非数字就是NaN,空字符串为0;true为1,false为0,null为0,undefinedNaN.

2、 引用数据类型先变字符串toString()再转数字

     数组变字符串,各项之间使用逗号分隔,整体包起来。因此当数组中长度大于等于2时,结果为NaN

     普通对象转字符串都为'[object Object]',因此都为NaN

console.log(Number('12')); //=>12
console.log(Number('12.5')); //=>12.5
console.log(Number('12px')); //=>NaN
console.log(Number('12.5.0')); //=>NaN
console.log(Number(true)); //=>1
console.log(Number(false)); //=>0
console.log(Number(null)); //=>0
console.log(Number(undefined)); //=>NaN
console.log(Number(Symbol(13))); //=>Cannot convert a Symbol value to a number
console.log(Number(function func() {})); //NaN
4. parseInt()/parseFloat()

处理原理和Number不一样,他们是把字符串转化为数字类型(如果处理的值不是字符串,需要先转为字符串然后再去转化为number类型)
从字符串最左边开始查找,把找到的有效数字字符转化为数字,一直遇到一个非有效数字字符为止,则结束查找

  • parseInt不能识别小数点
  • parseFloat可以识别一位小数点

规律:

当数字开头时:结果为到遇到非数字字符之前的所有值

当不是数字开头时:不管中间有多少个数字,结果都为NaN

引用数据类型变为字符串再查找

console.log(Number('12px')); //=>NaN
console.log(parseInt('12px')); //=>12
console.log(parseInt('12px24')); //=>12
console.log(parseInt('width:12px')); //=>NaN
console.log(parseInt('12.5px')); //=>12
console.log(parseFloat('12.5px')); //=>12.5  parseFloat比parseInt多识别一个小数点

console.log(Number(true)); //=>1
console.log(parseInt(true)); //=>先把TRUE转换为字符串"TRUE"  parseInt('true') =>NaN
console.log(parseInt(NaN)); //=>NaN
console.log(Number(null)); //=>0
console.log(parseInt(null)); //=> parseInt('null') =>NaN
console.log(isNaN(Number(parseInt("0.8")))); //=>parseInt("0.8")->0   Number(0)->0  isNaN(0)->false

console.log(Number('')); //=>0
console.log(parseInt('')); //=>NaN

string数据类型

在JS中用 单引号/双引号/反引号 包起来的都是字符串:每一个字符串都是由零到多个字符组成的,和数组类似,每一个字符也都有自己的索引。

str.length存储了一共有多少个字符,也就是字符串的长度

1. 把其他数据类型转化为字符串类型
  • String([value])
  • [value].toString()

其他数据类型转为字符串的规律

  • 基本数据类型直接加引号
  • 普通对象转为字符串都是 '[object Object]'
  • 数组对象转为字符串是’第一项,第二项…’ 逗号分隔数组中的每一项
2. 在JS中常用的数学运算

数学运算:+ - * / %
不管是什么运算,只要有一项转为数字是NaN,那么结果必定为NaN

  • 除了加法以外,其余的情况都是数学运算(如果遇到非数字类型,需要基于Number把其强制转换为数字类型,然后再进行运算)
  • 加号在JS中既有数学运算,也有字符串拼接的意思(只要加号两边的任意一边出现字符串,或者有一边是引用数据类型,则变成字符串拼接)
    • 不是数字就先转数字:引用数据类型先转为字符串再转数字,但是当它转为字符串的时候,也就可以拼接了
    • 在拼接的时候:基本数据类型直接拼进去,引用数据类型转为字符串再拼进去。

规律:

遇到字符串开始拼接

基本数据类型不用变,直接加进去

引用数据类型变为字符串再加进去

//腾讯的面试题
console.log(100 + true + 21.2 + null + undefined + 'Tencent' + [] + null + 9 + false); // 'NaNTencentnull9false'


console.log(3 - "3px"); //=>NaN
console.log(3 + "3px"); //=>"33px"  字符串拼接
console.log(1 + "1"); //=>"11" 字符串拼接
console.log(1 + {}); //=>"1[object Object]"  在把{}转换为数字过程中,先把他转换为字符串"[object Object]",此时右侧出现了字符串,则不再是数学运算,而是字符串拼接了
console.log(1 + []); //=>'1'
console.log([10] + true); //=>"10true"  在转换[10]到数字的过程中,先把其转换为字符串"10",此时操作变为字符串拼接(和数学运算没关系了)
console.log(true + [10]); //=>"true10"
console.log(1 + true); //=>2 
3. 字符串中的方法

字符串中无需记忆原始字符串是否改变,因为它是基本数据类型,每一个操作都是直接操作值,对原始字符串不会产生任何影响(数组之所以要记住是否改变,是因为数组是对象类型,操作的是堆内存,方法的执行很可能把原始堆内存中的信息改变了,所以需要记忆原始数组是否改变)

获取字符串中指定位置字符的办法
  1. charAt([index]):根据索引获取指定位置的字符(charAt相对于直接基于索引获取的方式,在当前索引并不存在的情况下,字符串[索引]获取的结果是undefined,而charAt获取的结果是空字符串)
  2. charCodeAt:在charAt的基础上获取指定字符的Unicode编码
  3. String.fromCharCode([unicode编码]):和charCodeAt对应,他是基于编码获取编码前的字符
字符串查找和截取

最后的M不写就是截取到字符串的末尾

  1. substr(n,m):从索引N开始截取M个字符

  2. substring(n,m):从索引N开始,找到索引为M处(不包含m),找到的部分截取

  3. slice(n,m):和substring一样,只不过slice支持负数索引

  • slice(-6,-3):从倒数第六个索引截取到倒数第三个索引(不包含倒数第三个)
字符串转化为数组的方法
  1. split:和数组中的join方法对应,他是把字符串按照指定的分隔符号拆分为数组中的每一项,返回结果是一个数组
  • 不指定分隔符时,逐个分隔开来
字符串中查找是否包含某个字符
  1. indexOf / lastIndexOf:获取当前字符在字符串中第一次或者最后一次出现位置的索引。如果字符串中不包含这个字符,那么返回结果是-1

  2. includes:验证是否包含某个字符。true / false

字符串替换
  1. replace(原始字符,新字符):把字符串中原始字符替换称为新字符,在不使用正则的情况下,每次执行replace只能替换一个
字符串大小写转换
  1. toLowerCase:把字符串中所有的字符转化为小写
  2. toUpperCase:把字符串中所有的字符转化为大写

boolean数据类型

有两个值:truefalse

1. 如何把其他数据类型转化为布尔类型
  • Boolean([value])
  • ![value] 把指定的值转化为布尔类型后再取反
  • !![value] 取反再取反,相当于没有取反;只是把他转化为布尔类型值

规律:只有 0/NaN/null/undefined/'' 最后是false,其余都是true

console.log(!!-1);   //true
console.log(!!0);     //false
console.log(!!undefined);   //false
console.log(!!Number('12px'));  //false
console.log(!![]);    //true
console.log(!!'');    //false
console.log(!!{});    //true
2. 在条件判断中的应用:

条件判断中,每一个条件最后结果一定是true/false
其中一个值,也就是要把这个值转化为布尔,然后校验程序的真假

if(3 + '3px'){}   //true
if(3 - '3px'){}   //false

普通对象object

1. 普通对象
  • 用键值对(key:value 俗称属性名和属性值) 来描述一个对象的特征(每一个对象都是综合体,存在零到多组键值对)
  • {key:vlaue,....}每一组键值对是key:value 的格式,多组键值对之间使用逗号分隔
  • key不能是引用数据类型value可以是任何的数据类型
var obj = {
  name:'lili',
  age:15
};
2. 操作属性的两种方法
  • 对象.属性名 = 属性值 : ‘.’ 是‘的’的意思, 这一种获取方式,对象的属性名不能是数字
  • 对象[‘属性名’] = 属性值
3. 关于对象中键值对的增删改查
  • 新增或者修改属性和属性值
    • 对象的属性名是不允许重复的,之前没有这个属性则为新增,之前有这个属性,则是修改对应的属性值
  • 获取对象中的属性名和属性值
    • 获取指定属性名的属性值
      • console.log(obj.sex)
      • console.log(obj['sex'])
    • 如果指定的属性不存在,获取到的属性值是undefined
    • 获取当前对象中所有的属性名:返回结果是包含所有属性名的数组
      • console.log(Object.keys(obj));
  • 删除对象中指定的属性
    • 假删除:当前属性还存在,只不过属性值为空 对象名.属性名 = null
    • 真删除:彻底把属性从对象中移除 delete 对象名.属性名
4. 对象中的属性名的知识点
  • 基于 对象[属性名] 的方式操作,需要保证属性名是一个值(字符串/数字/布尔等都可以),如果不是值而是一个变量,它会把变量存储的值作为对象的属性名进行操作
  • 基于 对象.属性名 的方式操作,属性名就是点后面的

如果对象的属性名是一个引用数据类型,那么会去隐性的转为字符串再去操作

let a={}, b={n:'1'}, c={m:'2'};  
a[b]='今天';
a[c]='明天';  
console.log(a[b]);

obj[ n ] = 100 和 obj [‘n’] = 100的区别

  • obj[ n ] =100 它是去找变量名是n所指的值
    • 当变量n不存在时,会报错Uncaught ReferenceError: n is not defined n这个变量没有被定义
    • 当这个变量存在时,这个变量的值是新增对象中的属性名,属性值是100
  • obj ['n'] = 100 它是去找这个对象中是否有属性名是n的键值对
    • 如果没有,结果是undefined
    • 如果有,会修改里面值,把属性名是n的值改为100,(因为对象中的属性名不能重复)
let n = 10;
let obj = {}
obj[n] = 200;  //这里的是n是变量n  ,因此这里是为obj对象加了一个属性名为10,属性值为200的键值对
obj['n'] = 100;  //这里的n是属性名

数组对象

1. 数组是特殊的对象

对象都是由键值对组成的,每项之间是有逗号隔开,但是数组是特殊的对象

  • 数组中我们看到的每一项都是属性值,默认的属性名是数字,数字从零开始递增,数字代表当前是第几项,我们把代表位置的数字属性称为‘索引’:数组是以数字为索引,索引从零开始递增的结构;
  • 默认存在一个length属性,代表数组的长度(有多少项)
  • 数组中存在的每一项可以是任何数据类型

    在项目中,我们从服务器获取到的数据,一般都是对象或者数组(JSON格式),而且结构层级一般也都是多级结构,所以学会数组/对象的相关操作,能够根据需求把获取到的数据进行有效的解析和处理,是当下前端开发中非常重要的知识点:尤其是Vue/reat开发的时候,我们都是在不断的操作数据,来控制视图的渲染,而操作的数据也是以对象和数组偏多;

2. 数组的维级
  • 一维数组
    • let arr = [10,20,30]
  • 二维数组(多维数组)有两级或者多级结构
    • let arr = [{x:100},10]
3. 数组的内置方法
关于数组的增删改 :原数组都会改变
  1. push:向数组末尾追加元素
  • @params:参数个数不固定,类型也不固定,都是向数组末尾依次追加的内容
  • @return :新增后数组的长度
  • 原数组改变
  • let arr = [10,20]; arr.push(20)
  1. pop :删除数组中的最后一项
  • @params:
  • @return :被删除的那一项
  • 原数组改变
  • let arr = [10,20]; arr.pop()
  1. unshift:向数组开头追加元素
  • @params:参数不定,类型不定,都是要依次新增的内容
  • @return:新增后数组的长度
  • 原数组改变
  • let arr = [10,20]; arr.unshift(20)
  1. shift:删除数组的第一项
  • @params:
  • @return:被删除的那一项
  • 原数组改变
  • let arr = [10,20]; arr.shift()
  1. splice:实现数组指定位置的增删改
  • arr.splice(n,m):从数组中索引为n开始,删除m个元素,返回结果是以新数组的方式,把删除的内容进行存储(m不写就是删除到末尾)
  • arr.splice(n,m,x1,x2,...):从索引n开始,删除m个元素,并且使用x替换删除的内容,返回结果是一个数组,存储删除的内容
  • arr.splice(n,0,x1,x2,...):从索引n开始,不删除,把x的值插入到索引n的前面
关于数组查询和拼接 : 不会改变原数组
  1. slice:实现数组的查询
  • slice(n,m):从索引n开始,查找到索引为m处(不包含m),把查找到的内容以新数组的方式返回,原数组不变
    • 第二个参数不写是直接查找到数组末尾
    • 可以理解为把原数组中的每一项都查找到,以新数组返回,实现出‘数组的克隆’:得到的新数组和原始数组是两个不同的数组(不同的堆),但是堆内的内容一致
  1. concat:实现数组的拼接,把多个数组(或者多个值)最后拼接为一个数组,原始的数组都不会变,返回结果是拼接后的新数组
转为字符串:原数组不变
  1. tostring:把数组中的每一项按照‘逗号分隔’,拼接成对应的字符串

  2. join:指定分隔符

  • arr.join() :等价于tostring
  • arr.join('+'):加号分隔,如果想实现加法:eval(arr.join('+'));
验证是否包含某一项 :原数组不变
  1. indexOf / lastIndexOf:获取当前项在数组中第一次/最后一次出现位置的索引
  • 如果数组中不包含这一项,返回值是-1
  1. includes:验证数组中是否包含这一项,返回false/true
关于排序的
  1. reverse:把原数组倒过来排列,返回的结果是排列后的原数组,原数组改变

  2. sort:把原数组按照规则进行排序,原数组会改变(返回结果也是改变后的原始数组)

  • sort支持传递回调函数,基于自定义的排序规则,进行排序的
  • 不能处理两位以及两位以上的内容排序
  • arr.sort(function(a,b){return b - a;})
    • a - b升序 b - a降序
关于数组迭代的方法
  1. forEach:遍历数组的每一项(数组中有多少项,函数会相继被执行多少次)
  • 每一次执行函数,都可以在函数中获取到当前遍历的这一项和对应的索引
  1. map: forEach是不支持返回值的,而map可以在forEach的基础上支持返回值,把原来数组中每一项的值替换为新值,最后存储在一个新的数组中,但是原始数组是不变的
删除数组末尾项
  • arr.pop();
  • arr.length--;
  • arr.splice(arr.length - 1)
向数组末尾追加一项
  • ary.push(x);
  • ary[ary.length] = x
  • ary.splice(ary.length,0,x)

日期对象

Math

Math作为一个对象数据类型值,在它的堆内存中,存储了很多的内置属性和方法,这些方法一般都是用来操作数字的,所以我们把Math称为‘数学函数对象’

  • console.log(typeof Math)
  • console.log(Math)
Math中的内置方法
  1. Math.PI / Math['PI'] :获取圆周率 =》 3.141592653589793
  2. Math.abs([N]):获取数字N的绝对值(绝对值都是正数)
  3. Math.ceil([N]) / Math.floor([N]) :把数字N向上或者向下取整
  4. Math.round(N) :把数字N四舍五入(结果都是整数)
  • 正数中,小数点后面5以及5以上进一位
  • 负数中,小数点后面5以及5以下是舍去
  1. Math.max(N1,N2,...) / Math.min(N1,N2,...):获取一堆数值中的最大值和最小值
  2. Math.pow([N],[M]):获取数字NM次幂
  3. Math.sqrt([N]):给数字N开平方
  4. Math.random():获取0~1之间的随机小数
  • 获取[N,M]之间的随机整数(包含NM):Math.round(Math.random()*(m-n) + n)

数据类型的检测(会专门写一个关于数据类型检测的文章来详细说明)

JS中的数据类型检测

  • typeof [value] 检测数据类型的运算符
  • [example] instanceof [class] 检测某一个实例是否属于这个类
  • [example].constructor === [class] 检测实例和类关系的,从而检测数据类型
  • Object.prototype.toString.call([value]) 检测数据类型

typeof [value]

细节点:

  • 返回值是字符串,字符串中包含了对应的数据类型
    被检测的数据类型返回值
    number‘number’
    string‘string’
    Boolean‘boolean’
    null‘object’
    undefined'undefined ’
    symbol()‘symbol’
    BigInt‘bigint’
    对象‘object’
    函数‘function’

特殊的检测结果

  • NaN / Infinity 都是数字类型,检测出来的结果是'number'
  • typeof null 的结果是'object' (这个是浏览器的BUG:所有的值在计算机中都以二进制编码存储,浏览器把前三位是000的当做对象,而null的二进制前三位就是000。所以被识别为对象,但是它不是对象,它是空对象指针,是基本数据类型)
  • typeof 普通对象/数组对象/正则…结果都是'object' ,这样就无法基于typeof区分是普通对象还是数组对象等
console.log(typeof []);                 //=>"object"
console.log(typeof typeof typeof []);   //=>'string'
//由于typeof返回的结果永远是一个字符串(字符串中包含了对应的类型),
//所以连续出现两个及两个以上typeof检测的时候,最后结果都是 "string"

数据类型的比较

== 左右两边数据类型不一致,先默认转化为一致的,再进行比较

=== 数据类型 和 值都相等

基于== 进行比较的时候,左右两边数据类型不一致,隐性转换规则

  • NaN == NaN => false => 因为 NaN和任何值(包含自己本身)都不相等
  • Infinity == Infinity => true => Infinity只和自己相等,和其他值不相等
  • Symbol(1) == Symbol(1)=> false
  • 对象 == 对象 比较的是内存地址
  • null == undefined=> true => nullundefined两个等号比较是等的,三个等号比较是不相等的,除此之外,他们和任何值相比较都不相等
  • 对象 == 字符串 都转为字符串

正常的比较

  • 数字 == 字符串 都转数字
  • 数字 == 布尔 都转数字
  • 数字== 对象 都转数字
  • 字符串 == 布尔 都转数字
  • 布尔 == 对象 都转数字
console.log([10] == '10'); //=>'10'=='10'   true
console.log({} == '{}'); //=>'[object Object]'=='{}'  false
console.log(1 == true); //=>1==1   true
console.log(2 == true); //=>2==1   false
console.log(-1 == false); //=>-1==0  false
console.log(0 == false); //=>0==0  true
console.log(1 == '1'); //=>1==1  true
console.log(true == '1'); //=>1==1  true  
console.log(false == ''); //=>0==0  true
console.log([] == 0); //=>0==0 true 

总结

这是javascript中的基础知识,想要在这条路上走得更远,基础知识也是需要基础加深印象。

如果觉得写得还不错,请关注我的掘金主页。今后让我们一起成长。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值