JS基础知识
javascript的发展史
关于前端的发展史,推荐看阮一峰老师的这个解说,介绍了关于javascript语言的诞生、javascript与ECMAScript的关系、javascript与Java的关系(这就跟苹果与苹果手机的问题类似吧,哈哈)、javascript的版本以及它发展的过程等等;链接地址javascript.ruanyifeng.com/introductio…
浏览器
客户端通过网址去访问服务器,服务器返回的是前端代码,浏览器把返回的代码进行解析渲染,最后渲染成为用户可看见的页面 =>这就是浏览器的内核或者引擎做的事情,不同的浏览器渲染机制不一样,因为它们采用不同的内核来进行处理
按照不同的内核浏览器的分类
以谷歌浏览器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 BigIntES6新增的
- 数字
- 引用数据类型
- 对象数据类型
object- 普通对象
{ } - 数组对象
[ ] - 正则对象
/^$/ - 日期对象
new Date - 数学函数对象
Math - ...
- 普通对象
- 函数数据类型
function
- 对象数据类型
number数据类型
正数、零、负数、小数
NaN:not a number 不是一个有效数字,但是属于number类型的
Infinity:无穷大的值,也是number类型的
1. 验证n是不是有效数字
NaN和任何数都不相等,包括它本身isNaN验证一个值是否为非有效数字,如果是有效数字,则返回false,如果不是有效数字,则返回true。- 在使用
isNaN检测的时候,如果被检测的值是非数字类型的值,则需要先把其转化为数字类型,然后再进行检测;
规律:
- 结果不是
false就是true - 结合下方的
Number()方法来记:
Number()结果为NaN,isNaN的结果就是true;
Number()结果不为NaN,isNaN()结果为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 ,undefined为NaN - 不能把
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,undefined为NaN.
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. 字符串中的方法
字符串中无需记忆原始字符串是否改变,因为它是基本数据类型,每一个操作都是直接操作值,对原始字符串不会产生任何影响(数组之所以要记住是否改变,是因为数组是对象类型,操作的是堆内存,方法的执行很可能把原始堆内存中的信息改变了,所以需要记忆原始数组是否改变)
获取字符串中指定位置字符的办法
charAt([index]):根据索引获取指定位置的字符(charAt相对于直接基于索引获取的方式,在当前索引并不存在的情况下,字符串[索引]获取的结果是undefined,而charAt获取的结果是空字符串)charCodeAt:在charAt的基础上获取指定字符的Unicode编码String.fromCharCode([unicode编码]):和charCodeAt对应,他是基于编码获取编码前的字符
字符串查找和截取
最后的M不写就是截取到字符串的末尾
substr(n,m):从索引N开始截取M个字符substring(n,m):从索引N开始,找到索引为M处(不包含m),找到的部分截取slice(n,m):和substring一样,只不过slice支持负数索引
slice(-6,-3):从倒数第六个索引截取到倒数第三个索引(不包含倒数第三个)
字符串转化为数组的方法
split:和数组中的join方法对应,他是把字符串按照指定的分隔符号拆分为数组中的每一项,返回结果是一个数组
- 不指定分隔符时,逐个分隔开来
字符串中查找是否包含某个字符
indexOf / lastIndexOf:获取当前字符在字符串中第一次或者最后一次出现位置的索引。如果字符串中不包含这个字符,那么返回结果是-1includes:验证是否包含某个字符。true / false
字符串替换
replace(原始字符,新字符):把字符串中原始字符替换称为新字符,在不使用正则的情况下,每次执行replace只能替换一个
字符串大小写转换
toLowerCase:把字符串中所有的字符转化为小写toUpperCase:把字符串中所有的字符转化为大写
boolean数据类型
有两个值:true、false
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
- 当变量n不存在时,会报错
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. 数组的内置方法
关于数组的增删改 :原数组都会改变
push:向数组末尾追加元素
@params:参数个数不固定,类型也不固定,都是向数组末尾依次追加的内容@return :新增后数组的长度- 原数组改变
let arr = [10,20]; arr.push(20)
pop :删除数组中的最后一项
@params:无@return :被删除的那一项- 原数组改变
let arr = [10,20]; arr.pop()
unshift:向数组开头追加元素
@params:参数不定,类型不定,都是要依次新增的内容@return:新增后数组的长度- 原数组改变
let arr = [10,20]; arr.unshift(20)
shift:删除数组的第一项
@params:无@return:被删除的那一项- 原数组改变
let arr = [10,20]; arr.shift()
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的前面
关于数组查询和拼接 : 不会改变原数组
slice:实现数组的查询
slice(n,m):从索引n开始,查找到索引为m处(不包含m),把查找到的内容以新数组的方式返回,原数组不变- 第二个参数不写是直接查找到数组末尾
- 可以理解为把原数组中的每一项都查找到,以新数组返回,实现出‘数组的克隆’:得到的新数组和原始数组是两个不同的数组(不同的堆),但是堆内的内容一致
concat:实现数组的拼接,把多个数组(或者多个值)最后拼接为一个数组,原始的数组都不会变,返回结果是拼接后的新数组
转为字符串:原数组不变
tostring:把数组中的每一项按照‘逗号分隔’,拼接成对应的字符串join:指定分隔符
arr.join() :等价于tostringarr.join('+'):加号分隔,如果想实现加法:eval(arr.join('+'));
验证是否包含某一项 :原数组不变
indexOf / lastIndexOf:获取当前项在数组中第一次/最后一次出现位置的索引
- 如果数组中不包含这一项,返回值是-1
includes:验证数组中是否包含这一项,返回false/true
关于排序的
reverse:把原数组倒过来排列,返回的结果是排列后的原数组,原数组改变sort:把原数组按照规则进行排序,原数组会改变(返回结果也是改变后的原始数组)
sort支持传递回调函数,基于自定义的排序规则,进行排序的- 不能处理两位以及两位以上的内容排序
arr.sort(function(a,b){return b - a;})a - b升序b - a降序
关于数组迭代的方法
forEach:遍历数组的每一项(数组中有多少项,函数会相继被执行多少次)
- 每一次执行函数,都可以在函数中获取到当前遍历的这一项和对应的索引
map:forEach是不支持返回值的,而map可以在forEach的基础上支持返回值,把原来数组中每一项的值替换为新值,最后存储在一个新的数组中,但是原始数组是不变的
删除数组末尾项
arr.pop();arr.length--;arr.splice(arr.length - 1)
向数组末尾追加一项
ary.push(x);ary[ary.length] = xary.splice(ary.length,0,x)
日期对象
Math
Math作为一个对象数据类型值,在它的堆内存中,存储了很多的内置属性和方法,这些方法一般都是用来操作数字的,所以我们把Math称为‘数学函数对象’
console.log(typeof Math)console.log(Math)
Math中的内置方法
Math.PI / Math['PI'] :获取圆周率 =》 3.141592653589793Math.abs([N]):获取数字N的绝对值(绝对值都是正数)Math.ceil([N]) / Math.floor([N]) :把数字N向上或者向下取整Math.round(N) :把数字N四舍五入(结果都是整数)
- 正数中,小数点后面5以及5以上进一位
- 负数中,小数点后面5以及5以下是舍去
Math.max(N1,N2,...) / Math.min(N1,N2,...):获取一堆数值中的最大值和最小值Math.pow([N],[M]):获取数字N的M次幂Math.sqrt([N]):给数字N开平方Math.random():获取0~1之间的随机小数
- 获取
[N,M]之间的随机整数(包含N和M):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=>null和undefined两个等号比较是等的,三个等号比较是不相等的,除此之外,他们和任何值相比较都不相等- 对象 == 字符串 都转为字符串
正常的比较
- 数字 == 字符串 都转数字
- 数字 == 布尔 都转数字
- 数字== 对象 都转数字
- 字符串 == 布尔 都转数字
- 布尔 == 对象 都转数字
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中的基础知识,想要在这条路上走得更远,基础知识也是需要基础加深印象。
如果觉得写得还不错,请关注我的掘金主页。今后让我们一起成长。