JavaScript 基础(超详细)
前言
这篇笔记大概囊括了 JavaScript 基础的所有知识点。知识点的梳理参照了《JavaScript 高级程序设计》的内容,所以这算是一篇读书笔记。知识点的具体介绍主要有书中重要讲述、代码示例、思维图表、重难点解析、个人思考总结和他人的启发。虽不敢说这是最详细的笔记,但对于每个知识我都会尽力将自己的所思所想清楚地记录下来并分享。适合 js 初学者去查看特定知识点或者已经自学完 js 的伙伴去完成查漏补缺的过程。觉得对你有用的话记得点赞。 其他相关笔记还有如下几篇:
- JavaScript 基础(超详细)
- js 中的引用类型(内置对象)
- js 中的对象属性——configurable、writable 等(数据属性和访问器属性)
- js 中原型、原型链和继承概念(详细全面)
- 函数使用进阶——递归——闭包
目录
- 前言
- 1. JavaScript 简介
- 1.1 概述
- 1.2 ECMAScript 的实现
- 1.3 JavaScript 的使用
- 1.3.1 在网页中使用 javaScript
- 1.3.2 代码屏蔽
- 2. 基础概念
- 2.1 语法
- 2.1.1 区分大小写
- 2.1.2 标识符
- 2.1.3 关键字和保留字
- 2.1.4 注释
- 2.1.5 语句中可选的分号
- 2.1.6 严格模式
- 2.2 变量
- 2.2.1 变量声明和初始化
- 2.3 数据类型
- 2.3.1 typeof 操作符
- 2.3.2 Undefined 类型
- 2.3.3 Null 类型
- 2.3.4 Boolean 类型
- 2.3.5 Number 类型
- 2.3.6 String类型
- 2.3.7 Object 类型
- 2.3.8 数据类型转换
- 2.4 操作符
- 2.4.1 算数运算符(含++、- -)
- 2.4.2 赋值运算符
- 2.4.3 比较运算符
- 2.4.3 逻辑运算符
- 2.4.4 三元运算符
- 2.4.5 位运算符
- 2.4.6 其他运算符
- 2.4.7 运算符优先级
- 2.5 语句
- 2.5.1 分支语句
- 2.5.2 循环语句
- 2.5.3 label、break 和 continue 语句
- 2.5.4 其他语句
- 2.6 初识函数
- 2.6.1 函数声明
- 2.6.2 函数的参数
- 2.6.3 js 中函数没有重载
- 3. 变量、作用域链和内存问题
- 3.1 变量
- 3.1.1 基本类型和引用类型的值
- 3.1.2 变量复制
- 3.1.3 参数传递
- 3.1.4 instanceof 操作符
- 3.2 执行环境及作用域
- 3.2.1 执行环境
- 3.2.2 全局执行环境和函数执行环境
- 3.2.3 作用域链
- 3.2.4 延长作用域
- 3.2.5 变量预解析
- 3.3 垃圾收集
- 3.3.1 垃圾收集机制及变量的生命周期
- 3.3.2 标记清除(mark-and-sweep)
- 3.3.3 引用计数(了解)
- 3.3.4 内存的管理
- 总结
1. JavaScript 简介
1.1 概述
JavaScript 是 Netscape 公司的布兰登 · 艾奇(Brendan Eich)为 1995 年 2 月发布的 Netscape Navigator 2 开发的一种名为 LiveScript 脚本语言。在 Netscape Navigator 2 浏览器发布前夕将名字改为 JavaScript 。由于 Javascript1.0 取得巨大成功,Netscape 又在 Netscape Navigator3 中发布了 Javascript1.1 。1996 年 8 月,微软在 Internet Explorer3 中加入名为 JScript 的 Javascript 实现。1997年欧洲计算机制造商协会(ECMA,European Computer Manufacturers Association)以 Javascript1.1 为蓝本完成了 ECMA-262 — 定义一种名为 ECMAScript(发音为 “ek-ma-script”)的新脚本语言标准。 自此浏各览器开发商就开始致力于将 ECMAScript 作为各自 javascript 实现的基础。
JavaScript 诞生时,其主要目的是处理一些由服务器负责的输入验证操作(前端验证)。如今,JavaScript 的用途早已不再局限于简单的数据验证,而是具备了与浏览器窗口及其内容等几乎所有方面的交互的能力。
1.2 ECMAScript 的实现
ECMAScript 代表的是一种语法标准,而我们常说的 javaScript 指的是该标准在不同浏览器环境下的实现。JavaScript 的实现包括下列三个部分组成。
- 核心(ECMAScript)
- 文档对象模型(DOM)
- 浏览器对象模型(BOM)
还有在 node 环境下的实现使其具备了服务器端编程语言的能力,其在node 环境下的实现(node.js)包括两个部分组成。
- ECMAScript
- Node 模块API
1.3 JavaScript 的使用
1.3.1 在网页中使用 javaScript
想要在网页中使用 JavaScript 有三种方式
- 通过在
<script></script>
标签中直接编写 JavaScript 程序代码, script 标签可以放在 html 文档的任何位置。 - 作为某个元素的事件属性或者超链接的 herf 属性值。
- 通过
<script src="目标文档的URL"></script>
引入外部的 js 文件。
注意:方式三中的 script 标签中不允许再编写脚本。
1.3.2 代码屏蔽
在浏览器不支持 JavaScript 脚本或者脚本被禁用的时候,为了让页面平稳地退化可以使用一个 <noscript></noscript>
标签。这个元素可以包含能够出现在文档 body 元素中的任何 html 元素(script 标签除外)。其包含的内容只有在上述特殊情况下才会呈现。
<html><head>...</head><body><noscript><p>本页面需要浏览器支持(启用)JavaScript。</p></noscript></body>
</html>
2. 基础概念
2.1 语法
2.1.1 区分大小写
ECMAScript 中的一切(变量、函数名和操作符)都区分大小写。例如 temp 和 Temp 指的是两个不同的变量。typeof 不能作为变量名或者函数名,但是 typeOf 则可以。
2.1.2 标识符
标识符是指变量、函数或者对象属性的名字,或者函数的参数等。遵循以下命名规则:
- 由字母、数字、美元符号 $ 和下划线(_)组成。
- 不能以数字开头。
- 一般采用驼峰命名方法,即第一个字母小写,其余每个单词的首字母大写。例如:userName、averageTemp 等。
- 不能使用关键字或者保留字作为标识符。
2.1.3 关键字和保留字
关键字是在 ECMA 中已经规定好用途的一组特殊标识。关键字可用于表示控制语句的开始或结束,或者用于执行特定的操作等。关键字是语言保留的,不能用作标识符。以下就是 ECMAScript (ES5) 的全部关键字。
/*
* break do instanceof typeof
* case else new var
* catch finally return void
* continue for switch while
* debugger function this with
* default if throw delete
* in try
*/
保留字是指一组在这门语言中还没有任何特定的用途,但是可能在将来被用作关键字的标识,所以也不能用作标识符。以下是 ES3 定义的全部保留字。
/*
* abstract enum int short boolean export interface
* static byte extends long super char final
* native synchronized class float package throws
* const goto private transient debugger implements
* protected volatile double import public
*/
// es5在非严格模式下运行时的保留字缩减为下列这些:
// class enum extends const export import super
// es5在严格模式下运行时还对以下保留字施加了限制
// implements package public interface private static let
// protected yield
学过 ES6 或者更高版本后会发现 ES3 ES5 的很多保留字已经作为关键字使用。保留字和关键字不需要我们特别去学习记忆,只做一些了解,避免在以后变量、函数等命名时误用。
2.1.4 注释
ECMAScript 里面的单行注释以两个斜杠开头不能换行;块级注释以 /* 开头,以 */ 结尾表示,可以换行。为提高块级注释的可读性可以像上面示例一样在每行前面添加一个星号。
// 这是单行注释内容(双斜杠后面要加一个空格)
/*这里是多行注释的内容可以换行
*/
2.1.5 语句中可选的分号
ECMAScript 中的语句以一个分号结尾。但分号并不是必须的,如果省略则由解释器来确定语句的结尾(不推荐不写分号)。加上分号可以避免很多错误,或者可以更加放行地对代码进行压缩。加上分号解释器就不必要花时间判断推测应该在哪里插入分号了,提高了代码性能。况且解释器也可能推测加错分号的位置导致程序出错。总而言之为了代码更加清晰准确建议使用分号结尾。有关分号的详细说明可以阅读 JavaScript 权威指南章节2.5 。
2.1.6 严格模式
ES5 引入了严格模式(strict mode)的概念。严格模式是为 JavaScript 定义了一种不同的解析与执行模型。在严格模式下,一些不确定的行为将得到处理,对某些不安全的操作也会抛出错误。严格模式可以在整个脚本启用,也可以只在某个函数块作用域中启用严格模式。
- 整个脚本启用严格模式,可以在脚本顶部添加代码
"use strict";
- 只在某个函数块作用域启用严格模式则在函数体顶部添加代码
"use strict";
个人对严格模式的理解:严格模式只是要求开发者以更加严谨的语法和逻辑去编写更加安全程序,而并不是大量的更改了我们学习的语法。例如严格模式下无法再意外创建全局变量。在普通的JavaScript里面给一个错误命名的变量名赋值会使全局对象新增一个属性并继续“工作”(尽管将来可能会失败:在现代的JavaScript中有可能)。严格模式中意外创建全局变量被抛出错误。要了解严格模式的详细介绍可以查阅 MDN 文档。
2.2 变量
ECMAScript 的变量是松散类型的,所谓松散类型是指变量声明时不用指明数据类型,在变量更新时也可以改变变量的数据类型。变量仅仅是一个用于保存值得占位符而已。
2.2.1 变量声明和初始化
// 变量的声明使用关键字 var(variable的前三个字母)
var temp;
temp = 30;
// 更新变量的值,可以改为不同类型的值但是不提倡这么做
temp = 'TKOP_';
// 声明的同时进行赋值,即变量的初始化
var flag = true;
// 同时声明或者初始化几个变量
var a = 10,b = '扬尘',c,d = false;
2.3 数据类型
ECMAScript 中一共有 6 种数据类型,有 5 种简单数据类型(也称基本数据类型):Undefined、Null、Boolean、Number 和 String,还有 1 种复杂数据类型 Object。ECMAScript 不支持任何创建自定义类型的机制,而所有值最终都将是上述 6 种数据类型之一。(ES6 中新增一种 Symbol 类型,那个是 ES6 的内容暂不在此记录)
2.3.1 typeof 操作符
typeof 操作符可以用来检测字面量或者变量的数据类型。对一个值使用 typeof 操作符返回表示该值数据类型的字符串。typeof 是一个操作符而不是函数,其操作数可以是变量也可以是字面量。
var a, b = null,c = true,d = 10,e = 'TKOP_',f = {};a = typeof(a);b = typeof(b);c = typeof(c);d = typeof(d);e = typeof(e);f = typeof(f);console.log(a, b, c, d, e, f); // ->undefined object boolean number string objectfunction fn() {};console.log(typeof fn); // ->function
问题1:为什么使用 typeof 检测 null 的数据类型不是 null 而是 Object ?
问题2:在 6 大数据类型中没有 function 数据类型,为什么使用 typeof 检测函数的数据类型返回 function ?
2.3.2 Undefined 类型
Undefined 类型只有一个值,即特殊的 undefined 。在使用 var 声明变量但未对变量加以初始化时,该变量的值就是 undefined 。当然我们也可以使用 undefined 值显式初始化一个变量。
var udf0;
console.log(udf0); // ->undefined
var udf1 = undefined;
console.log(udf1); // ->undefined
- 一般而言,不存在需要显式地把一个变量初始化为 undefined 值的情况。字面值 undefined 的主要目的是用于比较,而 ES3 之前并没有规定这个值。ES3 引入这个值是为了区分空对象指针(空对象指针会使用 null 进行初始化,表示这个变量会用以保存一个对象类型的数据)与未经初始化的变量。
- 但即使未初始化的变量会自动被赋值未 undefined 值,但提倡显示初始化变量。如果能够所有的变量都进行了初始化,typeof 操作符返回 undefined 值时被检测的变量还没有声明,而不是没有初始化。
2.3.3 Null 类型
Null 类型是第二个只有一个值的数据类型,这个特殊的值是 null 。从逻辑的角度来看,null 值表示一个空对象指针,而这也是使用 typeof 操作符检测 Null 型数据时会返回 Object 的原因。
var myGirlFriend = Null;
if (myGirlFriend !=null) {console.log('我有对象了');
}
// null 与 undefined 返回 true 因为undefined派生自null
console.log(myGirlFriend == undefined); // ->true
如果定义的变量准备用于保存对象(但是还不确定数据的具体值),那么最好将该变量初始化为 null 而不是其他的值。这样直接检查 null 值就可以知道相应的变量是否已经保存了一个对象的引用。
总结:
- 不要也不需要显示将一个变量初始化为 undefined 。
- 尽量做到所有变量在声明的同时进行初始化,这样在使用 typeof 检测到的变量为 undefined 则表示该变量未声明(函数形参除外)。
- 如果声明用以保存某个对象的变量,但是还不确定其内容时,可以同时将其初始化为 null 。
2.3.4 Boolean 类型
Boolean 类型只有两个字面值:true 和 false 。但是其他所有类型的值都有与之对应等价的一个布尔值。可以调用转型函数 Boolean() 将其他类型数据转换成对应的布尔值。
var succeed = true;
var fail = false;
var num = 1;
var numBoolean = Boolean(num); // true
2.3.5 Number 类型
Number 类型即数字类型数据。这里主要学习他们的表示方法、运用时需要注意的一个问题、几个特殊的数值和将其他类型转换为数字类型的方法。
1、Number 类型数据的表示
(1) number 类型数据的字面量除了可以使用十进制表示外还可以使用八进制(在严格模式下无效并抛出错误)和十六进制表示。
// 第一位为 0 的数会被解析为八进制数。但是如果字面值中的数值超出了范围
// 那么前导 0 将会被忽略,数值将被当作十进制数值解析
var octalNum1 = 070; // 56
var octalNum1 = 080; // 无效的八进制数值,解析为 80
var octalNum1 = 081; // 无效的八进制数值,解析为 81
// 十六进制字面量的前两位必须是 0x,后跟任何十六进制数字(0~9及A~F或a~f)
var hexNum1 = 0xb; // 11
var hexNum1 = 0x2a; // 42
(2) 在表示浮点数值时可以使用通用的表示方法也可以使用科学计数法。浮点数值的最高精度是 17 位小数,但是在使用浮点数计算或者测试变量的浮点数值(永远不要这么做)时要注意舍入误差的问题。这是使用基于 IEEE754 数值浮点计算的编程语言的通病,ECMAScript 并非独此一家,例如 python 浮点数计算也有舍入误差。
// 浮点数数值中必须包含一个小数点且小数点后面至少有一位数字
var floatNum1 = 0.1;
var floatNum2 = 0.2;
var floatNum3 = .1415; // 有效但是不推荐使用
var floatNum4 = 2. // 小数点后面没有数字,解析为 2
var floatNum5 = 2.0 // 整数,为节约内存会解析为 2
if (floatNum1 + floatNum2 == 0.3) { // falseconsole.log('true');
}
// 使用科学计数法
var a = 3.12e4; // 31200
var b = 3.12e-4 // 0.000312
计算机内部存储数据的编码的时候,0.1在计算机内部根本就不是精确的0.1,而是一个有舍入误差的0.1。当代码被编译或解释后,0.1已经被四舍五入成一个与之很接近的计算机内部数字,以至于计算还没开始,一个很小的舍入错误就已经产生了。这也就是 0.1 + 0.2 不等于0.3 的原因。另外要注意,不是所有浮点数都有舍入误差。二进制能精确地表示位数有限且分母是2的倍数的小数,比如 0.5,0.5 在计算机内部就没有舍入误差。所以 0.5 + 0.5 === 1
可以先都将浮点数通过乘以10 n转化为整数计算后结果再除以相应的倍数来解决这个问题。
也可以在浮点计算后使用 Number 的内置方法在保证不会改变计算结果的前提下保留小数点后特定的位数作为结果解决这个问题。
2、Infinity 和 -Infinity
由于内存的限制,ECMAScript 并不能毫无限制地保存所有数值。它能够表示(保存)的最小值保存在 Number.MIN_VALUE 中,最大值保存在 Number.MAX_VALUE 中。当超过最大值时若为负则其值将被转换为 -infinity(负无穷),若为正则其值将被转换为 infinity(正无穷)。使用 isFinity() 函数可以判断一个变量的数值是否位于负无穷和正无穷之间,如果参数是无穷的返回 false,反正返回 true 。
访问 Number.NEGATIVE_INFINITY 和 Number.POSITIVE_INFINITY 也可以得到负和正的 infinity 值。
如图,各个数值的含义如下:
- x : -infinity
- y : +infinity
- a : -Number.MAX_VALUE
- d : +Number.MAX_VALUE(在大多数浏览器中这个值约为1.797e+308)
- b : -Number.MIN_VALUE
- c : +Number.MIN_VALUE (在大多浏览器中这个值为 5e-324)
3、NaN
NaN,即非数值(Not a Number)是 infinity 之外的另一个特殊的数值。NaN 用于表示一个本来要返回数值的操作数未返回数值的情况(这样可以避免抛出错误)。Number 型数值 NaN 有以下两个特点:
- 任何涉及 NaN 的操作都会返回 NaN。
- NaN 与任何值都不相等,包括 NaN 本身。
为此需要用到 isNaN() 函数来确定传入该函数的参数是否 “不是数值”。isNaN() 函数在接收到一个值后,会尝试将这个值转换为数值。不是 Number 类型的值若可以转换为数值则也会返回 false ,例如 “10” 或者 true 等。如果不能转换为数值的值都会导致这个函数返回 true 。
var a = NaN / 10; // a = NaN
console.log(NaN == NaN); // false
alert(isNaN(NaN)); // true
alert(isNaN(10)); // false
alert(isNaN('10')); // false
alert(isNaN('abc')); // true
4、数值转换
有 3 个函数可以将其他数据类型的数据转换为数字型数据,它们分别是Number()、parseInt() 和 parseFloat() 。第一个函数即转型函数 Number() 可以用于任何数据类型,而另外两个函数则专门用于把字符串类型值转换为数字型值。将其他类型数据转换为数字型数据在类型转换那节专门介绍,下面主要讨论它们将字符串转换为数字时的区别。
- Number()
- parseInt()
- parseFloat()
// Number()
/*
* 1、从字符串中的第一个非空字符开始解析,如果为空字符串则返回 0
* 2、遇到非数字型字符则返回 NaN ,前面的正负号和第一个小数点正常解析。
* 3、前导 0 会被忽略(无法识别八进制数)
* 4、如果字符串中包含有效的十六进制格式,例如从 "0x" 开始解析则转换为对
* 应的十进制数(可以识别十六进制数)
*/
var a = [Number(''), Number(' '), Number(' -01'), Number(' 0.2'), Number('3a'), Number('0.2.0'), Number('0xab')];
console.log(a); // ->[0, 0, -1, 0.2, NaN, NaN, 171]// parseInt(str, x); 参数str为要解析的字符串,x指定以多少进制对字符串进行解析(重要理解)
/*
* 1、也是从字符串中的第一个非空字符开始解析,但是空字符串返回 NaN
* 2、遇到非数字型字符(第一个负号除外)或者小数点则结束解析并返回已经解析得到的数值。
* 3、一般都明确指明第二个参数。
*/
var a = [parseInt(''), parseInt('a1'), parseInt(' -01'), parseInt(' 0.2'), parseInt('3a'), parseInt('13a0', 8), parseInt('0xab', 16)];
console.log(a); // ->[NaN, NaN, -1, 0, 3, 11, 171]
// parseFloat()
/*
* 1、只以十进制方式解析,所以可以以十六进制解析的字符串会被解析为0
* 2、解析遇到一个无效的浮点数字字符为止,注意科学计数法
*/
var a = [parseFloat(''), parseFloat('a'), parseFloat(' 00.2f'), parseFloat('03a'), parseFloat('1.3e2a'), parseFloat('0xab')];
console.log(a); // ->[NaN, NaN, 0.2, 3, 130, 0]
2.3.6 String类型
String 类型用于表示由零个或多个 16 位 Unicode 字符组成的序列,即字符串。在 JavaScript 中,字符串可以使用双引号或者单引号表示。一般习惯在 html 中使用双引号,在 js 中习惯使用单引号。需要注意的是左右引号必须匹配,且使用时不能换行(在 ES6 中引入模板字符串可以换行)。
1、转义字符
String 数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或者具有其他用途的字符。常用的转义字符如下:
- \n 换行
- \t 制表
- \b 退格
- \r 回车
- \\ 斜杆
- \" 双引号(同理可以得到单引号),例如:‘i say \‘hi,friend\’’
- \unnnn 以十六进制代码 nnnn 表示的一个 unicode 字符。
- \xnn 以十六进制代码 nn 表示的一个字符。
2、字符串不可变的特点
ECMAScript 中字符串是不可变的,即字符串一旦创建,他们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。
var str0 = 'hello';
str0 = str0 + ' friend';
// 操作:
// 1、分别创建(开辟内存保存)两个字符串 'hello' 和 ' friend' 并将前者赋值给变量 str0
// 2、再创建(开辟内存保存)一个新的字符串 'hello friend'(两者相加)
// 3、将步骤二的值赋值给变量 str0
// 4、将前两个字符串销毁,因为他们已经没用了。
字符串的不可变性是我们在使用 innerHTML 创建多个元素时,避免使用字符串拼接的方式,使用数组元素追加的方式实现效率提高很多的原因。
3、其他类型转换为字符串的方式
将其他类型的数据转换为字符串类型数据的方式有两种。
方式一:使用几乎每个值都有的 toString() 方法,该方法只有 null 和 undefined 值没有。
方式二:使用转型函数 String()
// toString() 方法,只示范数字型数据转换为字符串型数据,其他的在类型转换那节介绍
var num = 11;
var str0 = num.toString(); // '11'
var str1 = num.toString(16); // 'b'
// String()
var str2 = String(num); // '11'
两者的区别:toString() 方法 null 和 undefined 值没有该方法,可以传递一个参数指定转换为什么进制(默认十进制)的数值后再转换为字符串。String() 函数可以转换任何类型数据。
2.3.7 Object 类型
ECMAScript 中把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数”。形象的说对象就是一组没有特定顺序的值和功能的集合。
1、 对象的创建方式
// 1、通过对象字面量创建对象
var obj0 = {uname:'TKOP_', age: 18};
// 2、通过执行new操作符后跟要创建的对象类型的名称来创建
var obj1 = new Object();
// 通过以上两种方法创建Object类型的实例后,就可以为其添加属性或者方法,即创建自定义对象
obj1.uname = '扬尘';
obj2.age = 19;
// 3、当然我们可以创建自定义类对象(使用构造函数或者 class),这是面向对象编程(进阶)部分的内容,后面再详细总结
2、 Object 类对象实例具有的属性和方法
如果仅仅创建 Object 的实例并没有什么用处,但关键是要理解一个重要的思想:即在 ECMAScript 中 Object 类型是所有它的实例的基础。换句话说,Object 类型所具有的任何属性和方法也同样存在于更具体地对象中。(书中原话,但个人认为严谨地说是实例成员)。这些知识是面向对象编程的重难点后面详细总结。
Object 地每个实例都具有下列属性和方法:
- constructor : 保存着用于创建当前对象地函数。 对于前面的例子而言,构造函数(constructor)就是 Object()
- hasOwnProperty(propertyName) : 用于检查给定属性在当前对象中是否存在(而不是在对象原型__proto__中,即继承自类)。其中作为参数的属性名必须以字符串的形式指定。例如 obj0.hasOwnProperty(‘name’)。
- isPrototypeOf(object) : 用于检查当前对象是否是传入的对象的原型 (这个地方个人觉得书上写反了所以私自换了过来)。
- propertyIsEnumerable(propertyName) : 用于检查给定属性是否能够使用 for-in 语句来枚举。
- toLocaleString() : 返回对象的字符串表示,该字符串与执行环境的地区对应,区别明显的是时间对象。
- toString() : 返回对象的字符串表示。
- valueOf() : 返回对象的字符串、数值或者布尔值表示。通常与 toString() 方法的返回值相同。
3、 初步整体理解对象(引用类型)
2.3.8 数据类型转换
数据类型转换是指在开发时我们可以根据需要可预见地将一种类型的数据转换为另一种类型的数据。例如使用 prompt() 得到地用户输入均为 String 类型数据,但由于想得到的是数字型数据,则可以通过显式将其进行类型转换得到 Number 类型数据,这种为显式转换数据类型。再例如,分支语句中的判断条件不是返回 Boolean 类型值表的达式而是其他类型的值时,解释器会自动将其转换为 Boolean 类型的值,这种为隐式转换。
1、显式转换总结
- 转型函数 Boolean() : 将其他类型的值转换为 Boolean 类型。
- 转型函数 Number() : 将其他类型的值转换为 Number 类型。
- parseInt() : 将 String 类型的值转换为 Number 类型(整型)。
- parseFloat() : 将 String 类型的值转换为 Number 类型(浮点型)。
- 转型函数 String() : 将其他类型数据转换为 String 类型。
- toString() 方法 : 将除了 null 和 undefined 外的其他类型转换为 String 类型。
他们具体用法已在前面介绍过了
2、隐式转换总结
- 一元操作符加和减可以实现字符串转数字类型
- 二元操作符 - / * 可以实现字符串转数字类型
- 二元加法可以实现数字类型转换为字符串类型(字符串拼接)。
除了可以使用 typeof 判断数据类型外,还可以在控制台输出数据后进行判断。例如 10 和 ‘10’ 的颜色是不一样的,true 和 ‘true’ 在控制台输出的颜色一不一样。
// 字符串隐式转换为数字类型var num0 = '20' / '2'; //10var num1 = '20' * '2'; // 40 var num2 = -'20'; // -20var num3 = '20' - 0; // 20var num3 = +'20'; // 20var num4 = true / '2'; // 0.5// 数字类型隐式转换为字符串类型var str0 = '' + 20 // '20' var str0 = 20 + 10 + '' + undefined; // '30undefined'
3、各类型数据间转换规则总结
这是我在看视频学习时有关类型转换的思维导图笔记。在这里就不花费时间以表格形式展示了,直接贴图。
// 1、其他类型转换为布尔类型:null undefined NaN 0 空字符串均会转换为false;
// 其他对象均转换为 true; 需要注意的是这里空字符串是指 str.length = 0var b = ' ';if (b) {console.log('true');} else {console.log('false');}// 输出的是 truevar b0 = Boolean({}); // truevar b1 = Boolean(' '); // truevar b2 = Boolean(''); // falsevar b3 = Boolean(undefined); // falsevar b4 = Boolean(null); // falsevar b5 = Boolean(NaN); // falsevar b6 = Boolean(0); // falsevar b7 = Boolean(0.0); // falsevar a = [b0, b1, b2, b3, b4, b5, b6, b7]console.log(a)
// 2、其他类型转换为数字类型:null false 空字符串转换为 0;undefined 转换为 NaN。
// 内容为数字的字符串转换为相应的数字类型,true 转换为1,其他转换为 NaNvar num0 = ' ' / 1; // 0var num1 = null / 1; // 0var num2 = false / 1; // 0var num3 = undefined / 1; // NaNvar num4 = '20' / 1; // 20var num5 = true / 1; // 1var num6 = '20 ' / 1; // 20var num7 = '20a ' / 1; // NaN
// 其他类型转换为字符串类型则非常简单:相当于在两边加引号。var str0 = '' + undefined; // 'undefined'var str1 = '' + null; // 'null'var str2 = '' + NaN; // 'NaN'var str3 = '' + 10; // '10'var str4 = '' + true; // 'true'
2.4 操作符
表达式是用于 JavaScript 脚本运行时进行运算的式子,可以包含常量、变量和运算符。操作符的分类主要有算数运算符、赋值运算符、比较运算符、逻辑运算符和三元运算符,当然还有其他运算符,例如位运算、一元加减运算符等。这里不去记录所有操作符的用法细节。只去记录某些操作符的使用细节。
注意:在写代码时操作符与操作数间要加一个空格,一元操作符除外。
2.4.1 算数运算符(含++、- -)
算数运算符有 +、-、*、/、%、++、-- 等。后面两个是一元操作符,+、- (取反)也可以当成一元操作符,在数据类型转换那节有用到。
注意:只要使用 ‘+’ 连接两个操作数中有一个为字符串类型,js 就会自动把非字符串类型数据隐式转换为字符串类型处理。但是在遇到字符串之前所有的数字型数据仍会做为数值型数据处理。为避免这种情况,我们可以在表达式前面拼接一个空串。
// 1、++ -- 的前置递增递减与后置递增递减的区别var num0 = 0;++num0; // num0此时为1num0++; // num0此时为2console.log(num0); // ->2var a = num0++; // 先将先执行表达式后num0自加1,即先执行a=num0;后num0++console.log(a, num0); // ->2,3var b = ++num0; // num0先自加1后执行表达式,即先执行++num0;后执行b=num0console.log(b, num0); // ->4,4
// 2、判断以下结果var a = 10;++a;var b = ++a + 2;console.log(b);var c = 10;c++;var d = c++ + 2;console.log(d);var e = 10;var f = e++ + ++e;console.log(f);
// 3、总结:前置递增递减和后置递增递减单独使用时结果一样,都是使操作数自增1或者自减1
// 在与其他代码联用时,前置递增递减会先执行自增自减操作后执行表达式;后置递增递减则相反var str = '10';console.log(+str); // 数值型的 10
2.4.2 赋值运算符
赋值运算符有 =、+=、-=、*=、/=、%=、.= 等。
// 复合型赋值运算符说明:例如 a += b 相当于 a = a + b; 其他同理
2.4.3 比较运算符
比较运算符有 >、>=、<、<=、==、!=、===、!== 等。注意 == 和 === 的区别。
2.4.3 逻辑运算符
逻辑运算符 &&、||、! 。主要是理解逻辑中断(逻辑与和逻辑或操作均属于短路操作)。
- 对于逻辑与,如果第一个操作数逻辑为 false ,则不会再去判断第二各操作数的逻辑值,而会直接返回第一个操作数。反之则返回第二个操作数。
// 1、由于a=0,即与的第一个操作数逻辑为false,所以不会再判断(执行)第二各操作数,而直接返回第一个操作数0var a = 0;var b = a && ++a; console.log(b, a); // ->0 0 注意:a的值不变,还是0
// 2、由于a=1,即与的第一个操作数逻辑为true,所以需要判断(执行)第二各操作数,并返回第二个操作数a = 1;b = a && a++;console.log(b, a) // ->1 2 注意a的值已经改变,但是由于是后置递减,所以b的值是 1 (但不是第一个操作数的值)c = b && --b;console.log(c, b) // ->0 0 这里验证确实返回的是第二个操作数
- 对于逻辑或,如果第一个操作数逻辑为 true ,则不会再去判断第二各操作数的逻辑值,而会直接返回第一个操作数。反之则返回第二个操作数。
// 使用类似的代码验证或运算var a = 1;var b = a || --a;console.log(b, a); // 1 1a = 0;b = a || a++;console.log(b, a) // 0 1c = b || --b;console.log(c, b) // ->-1 -1
如下图,这是我在看视频学习时老师讲了一句误导性的话
JavaScript 基础(超详细)相关推荐
- Python的零基础超详细讲解(第十三天)-Python的类与对象
基础篇往期文章如下: Python的零基础超详细讲解(第一天)-Python简介以及下载 Python的零基础超详细讲解(第二天)-Python的基础语法1 Python的零基础超详细讲解(第三天)- ...
- Python的零基础超详细讲解(第十二天)-Python函数及使用
基础篇往期文章: Python的零基础超详细讲解(第一天)-Python简介以及下载_编程简单学的博客-CSDN博客 Python的零基础超详细讲解(第二天)-Python的基础语法1_编程简单学的博 ...
- Python的零基础超详细讲解(第七天)-Python的数据的应用
往期文章 Python的零基础超详细讲解(第一天)-Python简介以及下载_编程简单学的博客-CSDN博客 Python的零基础超详细讲解(第二天)-Python的基础语法1_编程简单学的博客-CS ...
- Python的零基础超详细讲解(第五天)-Python的运算符
往期文章 Python的零基础超详细讲解(第一天)-Python简介以及下载_编程简单学的博客-CSDN博客 Python的零基础超详细讲解(第二天)-Python的基础语法1_编程简单学的博客-CS ...
- 大学计算机基础超详细知识点(高手总结),大学计算机基础超详细知识点(高手总结).doc...
大学计算机基础超详细知识点(高手总结).doc 第一章 计算机及信息技术概述 电子计算机的发展历程 ①1946年2月由宾夕法尼亚大学研制成功的ENIAC是世界上第一台电子数字计算机."诞生了 ...
- JavaScript基础(详细总结)
目录 1.JavaScript简介 1.2.JavaScript的发展史 1.3.JavaScript的功能 1.4.JavaScript的特点 1.5.JavaScript组成 2.JavaScri ...
- 深度学习基础 | 超详细逐步图解 Transformer
作者 | Chilia 整理 | NewBeeNLP 首先,请阅读先修知识: 深度学习基础 | 从Language Model到RNN 深度学习基础 | RNN家族全面解析 深度学习基础 | Seq2 ...
- Javascript设计模式-超详细笔记
Javascript设计模式 什么是设计模式 1. 什么是设计模式 设计模式是前人总结出的,解决开发中某类问题的方法: 我们在过去的代码编写中已经接触过很多的设计模式了,只不过当时咱们不知道这就是一种 ...
- Python的零基础超详细讲解(第三天)-Python的基础语法
多行语句 Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠 \ 来实现多行语句,例如: duohang = item_one + \item_two + \item_three ...
- Python的零基础超详细讲解(第二天)-Python的基础语法1
Python 基础语法 打开python的编辑器 这里注意的是,之前下载的python在电脑主页上没有快捷方式,需要在win开始界面中打开 最终打开效果是一个白色的跟终端类似的编辑器,我们输入的时候是 ...
最新文章
- 数组名和数组名取地址的区别
- C将十六进制数字字符串转成数字
- ViewPager之引导界面---实现欢迎引导页面
- 中用BBP公式计算_【真课堂】7年级信息技术:数据计算
- vue 使用了浏览器的刷新之后报错_Laravel 7 + vue.js 学习笔记(一)
- leetcode刷题 162.寻找峰值
- java executequery,JDBC中的execute(),executeQuery()和executeUpdate()方法有什么区别?
- (3)[wp7数据存储] WP7 IsolatedStorage系列篇——通过XmlSerializer读写XML文件 [复制链接]...
- 定损是保险公司定还是4s店定的?
- 私塾在线精品原创系列文章
- php如何开发阅读器,微信小程序阅读器的简单实例开发
- qcom usb驱动下载_艾肯Mobile Q驱动-艾肯Mobile Q usb外置声卡驱动下载v1.35.20 官方最新版-西西软件下载...
- 提升NexusPHP解析种子文件性能(优化benc.php)
- 《带人要同频,管人要共情》读书笔记
- 学编程需要什么基础?
- HTML5-企业宣传6款免费源码尽在h5edu.cn
- 适合学生党的蓝牙耳机选哪个?学生党最爱的几款蓝牙耳机
- 2018-8-29-win2d-渐变颜色
- 基于Java毕业设计志愿者信息管理系统源码+系统+mysql+lw文档+部署软件
- vediojs m3u8 视频清晰度切换
热门文章