一、JavaScript
什么是JavaScript
- JavaScript是基于对象和事件驱动并具有相对安全性并广泛用于客户端网页开发的脚本语言,同时也是一种广泛用于客户端Web开发的脚本语言。
- JavaScript的核心部分相当精简,只包括两个部分:基本的语法结构(比如操作符、控制结构、语句)和 标准库(就是一系列具有各种功能的对象比如Array、Date、Math等)。
JavaScript是一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言。
直译式:直接编译并执行,代码不进行预编译。
脚本:凡是不能独立执行需要依赖其他程序的,通常都叫做脚本。
JavaScript 的特点
- 代码可以使用任何文本编辑工具编写
- 无需编译,由JavaScript引擎解释编写
- 弱类型语言
- 基于对象和原型
Javascript 代码执行
script 元素的作用是用于执行JavaScript代码
一个页面允许有多个script元素 且script元素可以出现在页面的 任意位置
如果页面中有多个script元素 默认的执行循序是从上至下
JavaScript所有的符号都是英文符号
分号表示语句的结束
JS引用及运行
引入方式
内部引入:在html文件中直接写在script标签内部
<script type="text/javascript"> //type属性可以省略
alert('hello world');
</script>
标签内引入:直接写在标签内
<button onclick="alert("hello world);">按钮</button>
外部引入:在html文件中通过script标签引入外部js文件
<script src="test.js"> </script>
思考:?外部引用js标签内部不可以添加内容
当 script元素用于引入外部文件时
当前script元素中的内容会被忽略
相对路径 相对于当前目录(文件夹)查找文件
绝对路径 从盘符(C:/D:/E:/)开始查找文件
盘符概念来自Windows操作系统
在服务器(采用Linux操作系统)中没有盘符的概念
Linux也叫做类Unix操作系统
类Unix操作系统包含(Linux Unix OSx)
在类Unix操作系统中 绝对系统 从 根目录(/)开始
(.) 表示 当前目录
(..) 表示 上级目录
在访问网页时 从协议开始的是 绝对路径
http://
JavaScript调试
JavaScript 是一个弱类型的 解释型语言
它由浏览器内核中的JavaScript引擎 解释执行
当引擎无法解析代码时 就会 停止当前代码块的解析并抛出一个 错误
JavaScript错误 不影响后续 代码的执行(指抛出错误后)
JavaScript出错 并不会影响 html和css的解析
JavaScript 的错误信息 和调试功能主要依赖于 浏览器开发者工具
错误信息会显示在开发工具的 控制台(console)
控制台开启有快捷键(Option+Command+J)(ctrl+shift+J)
JavaScript语法规范
语句 --- 不会被JS引擎执行的内容
注释 --- 不会被JS引擎执行的内容
语句
语句 是由 关键字 运算符 表达式 组成的
JavaScript 的语句 大小写敏感(严格区分大小写)
语句使用 分号(;)结束
语句结尾没有分号是可以的 但是没有分号表示由JS引擎自动判断语句的结束位置
在一些特定的场景中 没有分号会导致 引擎断句失效 导致错误
注释
单行注释 以双斜杠来表示(//)
多行注释 表示注释内容可换行(/*开始 */结束)
文档注释 指的是文件说明(js文件)/**开始 */结束
标识符的命名规范
- 可以使用字母、数字、下划线(_)、美元符($)
- 标识符不能以数字开头
var a1 //√
var 1a //×
var $a //√
var _ //√
var a% //× 除_和$外 所有符号均不可用于命名
-
标识符 不能是关键字 和 保留字
-
关键字
-
break case catch continue default delete do else finally for function if in instanceof new return switch this throw try typeof var void while with
-
-
保留字
-
abstract boolean byte char class const debugger double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile let yield
-
-
-
标识符 命名要有明确含义(语义化)
-
标识符的命名 通常采用 骆驼命名法(驼峰式命名)
- 小驼峰式命名(变量/函数) 首字母小写 之后的每一个单词首字母大写
- 大驼峰式命名(类/构造函数) 每一个单词的首字母大写
命名的基本原则(非必须):语义化,见名知意
1.驼峰命名法,userAgeNumber
2.帕斯卡命名法,UserAgeNumber
3.下划线命名法,user_age_number
4.匈牙利命名法,nUserAge,num_UserAge
JS的编译和执行(了解)
JS的编译和执行分为两个阶段
编译阶段
对于常见编译型语言(例如:Java)来说,编译步骤分为:词法分析->语法分析->语义检查->代码优化和字节生成。 对于解释型语言(例如JavaScript)来说,通过词法分析和语法分析得到语法树后,就可以开始解释执行了。
- 词法分析是将字符流(char stream)转换为记号流(token stream),就像英文句子一个个单词独立翻译,举例: 代码:
var result = testNum1 - testNum2;
//词法分析后 :
NAME "result"
EQUALS
NAME "testNum1"
MINUS
NAME "testNum2"
SEMICOLON
- 语法分析得到语法树,举例: 条件语句 if(typeof a == "undefined" ){ a = 0; } else { a = a; } alert(a); 当JavaScript解释器在构造语法树的时候,如果发现无法构造,就会报语法错误,并结束整个代码块的解析。
- “预编译”(并非完全的顺序执行) “function函数”是==一等公民==!编译阶段,会把定义式的函数优先执行,也会把所有var变量创建,默认值为undefined,以提高程序的执行效率! 总结:当JavaScript引擎解析脚本时,它会在预编译期对所有声明的变量和函数进行处理!并且是先预声明变量,再预定义函数!
JavaScript引擎 在执行代码之前 会有一个 编译阶段
编译阶段
-
词法分析
-
语法分析
-
预编译(将部分代码优先执行)
JS引擎会查找到所有 function 函数声明
JS引擎会查找到所有 var 变量声明
函数声明会优先执行
变量也会优先创建 创建好的变量默认被赋值为undefined
声明提前 的意义是提高代码的执行效率
代码执行阶段 代码按照从上至下顺序执行
console.log(num);
var num = 10;
console.log(num); //10
fn();//OK
function fn() {
console.log('ok');
}
console.log(fn2);//fn2
var fn2 = function () {
console.log('fn2');
}
console.log(fn); // 函数 函数和变量声明都提前了 函数的优先级最高 所以访问到的是函数
var fn = 10; // 执行阶段执行了赋值操作 原本被提前的fn函数 被覆盖了 变成10
console.log(fn); // 10
function fn() { } // 执行阶段 直接跳过 应为函数的创建在预编译阶段已经完成
console.log(fn); // 10
fn(); // 报错
JavaScript执行过程
- 在解释过程中,JavaScript引擎是严格按着作用域机制(scope)来执行的。JavaScript语法采用的是词法作用域(lexcical scope),也就是说JavaScript的变量和函数作用域是在定义时决定的,而不是执行时决定的,由于词法作用域取决于源代码结构,所以 JavaScript解释器只需要通过静态分析就能确定每个变量、函数的作用域,这种作用域也称为静态作用域(static scope)。补充:但需要注意,with和eval的语义无法仅通过静态技术实现,实际上,只能说JS的作用域机制非常接近lexical scope。 JavaScript中的变量作用域在函数体内有效,有块作用域;
- JavaScript引擎在执行每个函数实例时,都会创建一个执行环境(execution context)。执行环境中包含一个调用对象(call object), 调用对象是一个scriptObject结构(“运行期上下文”),用来保存内部变量表varDecls、内嵌函数表funDecls、父级引用列表upvalue等语法分析 结构(注意:varDecls和funDecls等信息是在语法分析阶段就已经得到,并保存在语法树中。函数实例执行时,会将这些信息从语法树复制到 scriptObject上)。scriptObject是与函数相关的一套静态系统,与函数实例的生命周期保持一致,函数执行完毕,该对象销毁。
- JavaScript引擎通过作用域链(scope chain)把多个嵌套的作用域串连在一起,并借助这个链条帮助JavaScript解释器检索变量的值。这个作用域链相当于一个索引表,并通过编号来存 储它们的嵌套关系。当JavaScript解释器检索变量的值,会按着这个索引编号进行快速查找,直到找到全局对象(global object)为止,如果没有找到值,则传递一个特殊的undefined值。
作用域(范围/区域)
ECMAScript 采用的式静态作用域
静态作用域指的式在函数和变量定义时就决定了作用域
ECMAScript(传统)==ES2015之前== 作用域 分为两类
- 全局作用域 全局定义的变量或函数 在任意位置都可以被访问
- 函数作用域 在函数中定义的变量或函数 仅在当前函数中可以被访问
变量 在创建时 就定义了它的作用域
var num = 3; //全局作用域 这个变量在任意位置都可以访问
function fn(){
var num = 5; // num 是函数作用域 仅在 fn 函数中可以使用
console.log(num); // 5 访问的式 fn 中的 num
}
fn();
console.log(num) // 3 访问的式全局变量
function fn2(){
console.log(num) // 3 当前函数作用域 没有声明num 所以当前访问的式全局变量 num
}
---------------------------------------------
var a = 2;
function fn3(){
var a = 3;
function fn4(){
var a=5;
console.log(a);
}
fn4(); // 5
console.log(a);
}
fn3();//3
console.log(a);// 2
-------------------------------------------------
var a=5;
function fn5(){
console.log(a);//a 声明提前 结果为 undefined
var a = 6;
console.log(a);
}
fn5();// undefined 6
//---------------------------------------
var x = 3;
function fn6() {
console.log(x); // undefiend
if (false) {
var x = 6;
}
console.log(x); // undefined
}
fn6();//undefined undefined
// --------------------------------------------
var c = 7;
function fn7() {
console.log(c); // undefined
for (var c = 0; c < 10; c++) {
console.log(c)//1-9
}
console.log(c); // 10
}
fn7();
// --------------------------------------------
var b = 3;
function fn8() {
console.log(b); // undefined
b = 5;
var b = 4;
console.log(b); // 4
}
fn8();
console.log(b); // 3
// --------------------------------------------
var a = 6;
var b = 7;
function fn9() {
var a = b = 3;
}
fn9();
console.log(a); // 6
console.log(b); // 3
// -------------------------------------------
function fn10() {
// 当前只声明了变量a
// 没有声明变量b
// 为未声明的变量直接赋值 该变量默认泄漏为全局变量
// 变量的使用 一定要 先声明 后使用
var a = b = 5;
}
fn10();
console.log(b);// 5
垃圾回收
现在各大浏览器通常用采用的垃圾回收有两种方法:标记清除、引用计数。
标记清除
这是javascript中最常用的垃圾回收方式。当变量进入执行环境是,就标记这个变量为“进入环境”。
从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到他们。
当变量离开环境时,则将其标记为“离开环境”。
垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。
然后,它会去掉环境中的变量以及被环境中的变量引用的标记。
而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后。
垃圾收集器完成内存清除工作,销毁那些带标记的值,并回收他们所占用的内存空间。
引用计数
另一种不太常见的垃圾回收策略是引用计数。引用计数的含义是跟踪记录每个值被引用的次数。
当声明了一个变量并将一个引用类型赋值给该变量时,则这个值的引用次数就是1。
相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数就减1。
当这个引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其所占的内存
API
API(Application Programming Interface ,应用程序接口)
API就是别人定义好的方法(功能)
XSS 跨站脚本攻击
跨站脚本攻击 通常使用恶意的JavaScript代码进行权限获取等操作 作为前端 需要规避此类风险 最常见的情况 就是使用 innerHTML 照成的漏洞 因为innerHTML可以识别元素 所以只需要让用户提交的内容没有元素即可
干预方案 1. 替换 替换掉关键符号 2. 转义
----> <h1>
submit.onclick = function () {
// output.innerHTML = text.value;
// output.innerHTML = text.value.replace(/<[^<>]+>/g, ''); // 直接删除标签(替换)
// 转义
let temp = text.value.replace(/</g, '<');
temp = temp.replace(/>/g, '>');
output.innerHTML = temp;
}
网页渲染
动态网站 指的是 HTML+CSS+JS+后端语言(php,jsp,asp ...) 组成的页面 当用户在访问动态页面时(php,jsp,asp ...) web服务器会找到对应的文件 和 后端语言的 编译工具(php,java虚拟机,.net) 编译工具将这些后端语言的代码 编译成 HTML 然后发送给浏览器 浏览器只认识 HTML 它不认识其他的后端语言 所以需要编译
后端渲染
后端渲染 指的是 后端获得数据 然后将数据解析到HTML中 然后发送给浏览器(浏览器收到的是HTML)
$message = 'hello world';
$color = 'yellow';
前端渲染
前端渲染 指的是 后端提供数据(JSON) 前端通过异步请求获得数据 然后将数据解析到页面(DOM操作)
<h1 style="color:<?php echo $color; ?>">你好世界</h1>
<h2> <?php echo $message; ?> </h2>
<?php
$data = array(
array(
'product'=>'iphone13',
'price'=>9988,
'color'=>'blue'
),
array(
'product'=>'iphoneX',
'price'=>6999,
'color'=>'black'
),
array(
'product'=>'xiaomi12',
'price'=>4999,
'color'=>'blue'
),
array(
'product'=>'huaweiP40',
'price'=>7766,
'color'=>'black'
),
);
?>
<ul>
<?php
for($i = 0;$i<count($data);$i++){
echo '<li>';
echo '商品名:'.$data[$i]['product'].' ';
echo '价格:'.$data[$i]['price'].' ';
echo '颜色:'.$data[$i]['color'].' ';
echo '</li>';
}
?>
</ul>
数据库
什么是数据库?
存储数据的仓库 物理存储介质 U盘 网盘 硬盘 光盘 磁带 计算机软件 记事本 word excel ...
专业版数据库 是用于存储数据的 服务软件 mysql access oracle sqlserver mongodb db2 redis ...
存储数据 需要考虑哪些因素 数据的安全性 服务的稳定性
数据库软件
数据库中存储的数据 是经过格式化(结构化)的数据
你好, 我是小花, 来自山西。今年18岁,就读于 西南科技大学 计算机专业。
在数据库中存储的关键字(key) 叫做 字段 它是一张表格的头信息(表头)
mysql数据库 关系型数据库
关系型数据的特点 以表的形式呈现数据 多张表之间通过字段产生联系
用户信息表
id 姓名 籍贯 年龄 学校 专业 10001 小花 山西 18 西南科技大学 计算机 10002 张三 北京 25 西南政法大学 法律
订单表
订单编号 用户id 创建时间 1832045612314 10002 192318540165423145
关系型数据库 有统一的操作语言 SQL
SQL语言 不区分大小写
nosql(非关系型数据库)
非关系型数据库 通常以文档形式存储数据(mongodb)
每一条数据 都是一个独立的文档 多个文档组成一个集合 多个集合组成一个数据库 每条数据都是独立存在的
{
_id:1620232123,
用户名:'小明',
年龄:20,
性别:'男',
专业:'法律',
订单:[132486156465465,132486156465412]
}
同源策略
同源策略 同源策略是浏览器提供一组安全策略 用户保护数据安全 保证数据的请求者是来自同一来源
ajax 严格遵循同源策略 一旦出现不同源的请求 则无法获得数据
同源(相同的源头/相同的来源)
- 相同的地址(ip/域名)
- 相同的协议(https:// https://)
- 相同的端口号(80 443)
同源需要同时满足以上三个条件
工作场景中 需要访问跨源数据(跨域请求)
跨域请求的解决方案
- CORS(XHR2) 后端方案 后端开放数据请求权限
- JSONP 前端方案 需要后端配合
- 反向代理 使用服务器 转发请求
const xhr = new XMLHttpRequest();
xhr.open('get', 'http://localhost/2202/day24/interface/hasuser.php?username=zhangsan');
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);//因为同源策略 所以访问失败
}
}
二、JavaScript基本输出语句
alert()
弹出一个警告框⚠️
alert("我是你爹")
document.write()
在文档(html文档中的body)中输出
这种输出方式 可以识别标签
document.write("<h1>我是你爹<h1>")
console.log()
控制台日志
console.log("我是你爹")
三、变量和常量及定义
用于存储信息的容量
JS的变量是松散类型的,可以用来保存任何类型的数据。
变量需要一个名称 变量的命名可以使用一些数字 字母 和符号
使用关键字 var 进行变量的创建(声明)
创建变量时为变量进行 取名操作
变量 存储信息的容器 存储的值可变(可修改)
常量 存储信息的容器 存储的值固定(不可修改)
var
使用var 声明变量 可以在声明时对变量进行赋值
也可以先声明 后赋值
如果声明了一个变量没有未其进行赋值
这个变量的默认值 undefined (未定义)
var car;
console.log(car); //undefined
使用一条语句声明多个变量
声明多个变量时 使用英文逗号隔开
var a, b, c, d; // 声明了4个变量
// a b c d 的值都是undefined
错误类型:
Uncaught ReferenceError: hello is not defined test.html:38
未捕获 引用错误 : 报文 报错位置
Uncaught SyntaxError: Unexpected token var test.html:40
未捕获 语法错误 : 报文 报错位置
四、数据类型与结构
ECMAScript 的数据类型
大致可以划分为两大类
- 值类型 (基本数据类型/原始数据类型)
- 引用类型 (对象引用)
传统(ES6)的 JavaScript 一共有5种 值类型(基本数据类型)(string、number、boolean、undefined、null)
基本数据类型
最新的ECMAScript 一共有7种基本数据类型
Undefined
这个数据类型 只有一个值
这个值就是 undefined
它是未赋值变量的默认值 这个值一般不会主动使用 因为没有意义
var num = undefined
console.log(num)
Null
Null类型 只有一个值
这个值就是 null
null 的英文含义是空
null 表示一个变量 未来可能会指向某个对象 但是目前没有任何指向
它的本质是 空对象指针(指向了一个空对象)
var n = null
console.log(n)
Number
Number类型显示是数字
数字的意义是用于计数和运算
在强类型语言中存储数字是有不同的数字类型的( Java 整数使用int 小数使用float)
在JavaScript中 所有的数字(无论整数还是小数) 都是Number
var num = 5
console.log(num - 3)
NaN
特殊值
NaN(Not a Number)不是一个数字(非数字)
NaN是Number类型的值
他表示一个需要返回数值的操作 无法获得数值的情况('a'-1) ('b'-3)
console.log(3 * 5 ) //15
console.log(3 * 'a') //NaN
NaN有两个特点:(Not a Number)
- 任何涉及NAN的操作都会返回NaN
- NaN与任何值都不相等,包括它本身
isNaN() 判断值是否为NaN,返回布尔值
parseInt() 解析一个字符串,并返回一个整数
parseFloat() 解析一个字符串,并返回一个浮点数
Number.toFixed(n) 方法可把 Number 四舍五入保留n位小数,返回字符串
Infinity
英文含义 无穷
他也是一个特殊的 Number类型的值
当0作为除数时 结果就是 Infinity
console.log( 33/2 ) //16.5
console.log( 33/0 ) //infinity
Boolean
布尔类型
这个类型有两个值 分别是 true 和false
true 含义 真
false 含义 假
在程序中 如果结果只有两种情况 就可以使用 布尔类型
在使用 可以用数字代替布尔类型
true可以用1代替
false可以用0代替
在使用布尔值进行运算时 它会自动转换成数字
true 转换成数字 1
flase 转换成数字 0
console.log(true) //true
console.log(false) //false
console.log(true + 3) // 4
console.log(false + 2) // 2
String
字符串类型
除其他数据类型之外 任意放在引号中的数据 都是字符串类型
==单引号== 和 ==双引号== 在JavaScript都表示字符串
在==java==中 单引号表示 字符 char 'a' 'b'
双引号表示 字符串 string "abc" "ok"
alert('你好 我是你爹')
特殊字符
有一些字符需要转义进行使用
字符串的转义字母是 ``
在Windows操作系统中 \n 表示换行符
在类Unix操作系统中 \r\n 表示换行符
console.log('\')
console.log('\n') //换行
console.log('\t') //制表符
bigInt
大整型
BigInt() 不是构造函数,因此不能使用 new 操作符。
是ECMAScript中 新增的基本数据类型
ES2021新增的数据类型
除了通过BigInt构造函数,我们还可以通过在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n。
var num1 = 123432152351235215
console.log(num1) //number
var num2 = 123124124315435344n
console.log(num2) //bigInt
Symbol
Symbol 是 ES2015 新增的 基本数据类型
Symbol 没有构造函数 不能使用new创建对象
使用 Symbol() 函数 来创建 Symbol类型的数据
Symbol 表示的是独一无二的值
Symbol 解决的是 对象属性名 命名冲突的问题
const obj = {
username: 'xiaoming'
};
// 假设我们使用了一个他人提供的对象 obj
// 想要在该对象上新增一个用户名 并赋值为 'lisi'
// 本意想要添加一个属性username 但是这个属性已经存在 导致属性名的命名有冲突 最后的结果是修改了原属性的值
// obj.username = 'lisi';
let userName1 = Symbol('username');
let userName2 = Symbol('username');
// 将Symbol作为对象的属性名时 只能使用[]的语法 ( .点操作符默认访问的是字符串类型的属性名 )
obj[userName1] = 'lisi';
obj[userName2] = 'wangwu';
console.log(obj);
//username: "xiaoming"
//Symbol(username): "lisi"
//Symbol(username): "wangwu"
console.log(obj[userName2]);//wangwu
console.log(typeof userName1);//Symbol
console.log(userName1 === userName2);//false
引用数据类型
引用类型概念
使用 ==new== 关键字创建的数据 都是引用数据
关键字 ==new== 负责在(堆)内存中开辟一块存储空间
创建一个新对象保存进去
返回这个内存空间的 引用地址 (在栈内存中存入堆的地址引用)
赋值符 只操作栈中数据
所有的基本数据类型都保存在栈中 只有引用类型保存在堆中
var obj = {
x: 1,
y: 2
}
var obj2 = obj; // 赋值符 赋值是栈中数据
// 引用类型 在栈中保存的就是地址
// 所有的基本类型的数据 直接被保存在栈中
obj2.x = 5;
console.log(obj.x); // 5
//-------------------------------
// 相等运算符( == ) 不相等运算符( != ) 全等运算符( === ) 不全等运算符( !== )
// 这四个运算符 在比较 引用类型时 比较的是 引用地址
// 在比较引用类型相等性时 只有相同的地址比较的结果才为true
var arr1 = [1, 2, 3, 4, 5]; // new Array(1,2,3,4,5)
var arr2 = [1, 2, 3, 4, 5]; // new Array(1,2,3,4,5)
console.log(arr1 == arr2); // false
// -------------------------------------
var o1 = { x: 1 };
var o2 = { x: 1 };
console.log(o1 == o2); //false
var o3 = o2;
console.log(o3 == o2); //true
// --------------------------------------
var arr = [1, 2, 3, 4];
arr.length = 0; //删除所有数组
console.log(arr)//[]
arr = []; // new Array(0)
console.log(arr);
Object
对象的本质是一组无序的键值对( 键Key 值Value )构成
对象通常用于表述一个整体
使用一个变量名 保存多个相关数据的 数据类型
var userName = '爹'
var sex = '女'
var age = 18
var user = new Object() //创建一个对象
user.name = '爹'
user.sex = '女'
user.age = 18
引用类型传参
参数传递就是在赋值
实参将赋值给形参
var arr = [1, 2, 3, 4, 5];
function changeFirst(a) {
a[0] = 0;
}
// 此处实参是 arr变量 它的值(栈中值) 是引用地址
// 按值传递 指的是变量的值传递给形参
changeFirst(arr);
console.log(arr);// [0, 2, 3, 4, 5]
// --------------------------------------------
var obj = {
x: 1, y: 2
}
function fn(o) {
o.z = 3;
}
fn(obj);
console.log(obj);//{x: 1, y: 2, z: 3}
函数的参数传递 参数如果是基本数据类型 则直接传值 参数如果是引用数据类型 则传递地址
Math
Math 是 EMCAScript 的内置对象 它是引用类型
console.log(Math);
EMCAScript 没有为Math提供构造函数 依次无法创建实例
var m = new Math(); //报错
Math 主要封装了一些 数学 常数 和 函数 访问Math的成员直接使用 Math.属性 或 Math.方法()
常数-> 常量 值是固定不改变的
在编程语言中(有一个常量命名规范) 所有字母大写
console.log(Math.E);
console.log(Math.PI);
常用方法
console.log(Math.abs(-3)); // 绝对值
console.log(Math.ceil(-3.14)); // 向上取整
console.log(Math.log(2)); // 自然对数
console.log(Math.floor(3.99)); // 向下取整
console.log(Math.max(25, 66)); // 返回较大的数
console.log(Math.min(25, 66)); // 返回较小的数
console.log(Math.pow(2, 31)); // 返回x的y次幂 可以用幂运算符代替这个函数 **
console.log(Math.round(3.6));// 四舍五入
console.log(Math.sqrt(9)); // 根号
三角函数
Math.sin() = 对边/斜边
Math.cos() = 领边/斜边
Math.tan() = 对边/领边
勾股定理
var a = 3;
var b = 4;
var c = Math.sqrt(a ** 2 + b ** 2);
console.log(c);
random
Math.random() 0(含)和 1(不含)之间的随机数
// 编写一个函数 返回一个指定范围内的随机数
function random(min, max) {
return Math.round(Math.random() * (max - min) + min);
return parseInt(Math.random() * (max - min + 1) + min);
}
编写一个函数 生成一个随机字符串 该字符串 可以指定长度 并且由随机的 大小写字母和数字组成
function getCode(len) {
len = len || 6;
var code = '';
for (var i = 0; i < len; i++) {
var type = random(1, 3); // 随机一种类型 1-3
switch (type) {
case 1:
code += String.fromCharCode(random(48, 57));
break;
case 2:
code += String.fromCharCode(random(65, 90));
break;
case 3:
code += String.fromCharCode(random(97, 122));
break;
}
}
return code;
}
console.log(getCode(4));
基本包装类型
1、基本类型:Undefined,Null,Boolean,Number,String
var str = 'hello'; //string 基本类型
var s2 = str.charAt(0); //为什么它能召唤出一个 charAt() 的方法?
//在执行到这一句的时候 后台会自动完成以下动作 :
(
var _str = new String('hello'); // 1 找到对应的包装对象类型,然后通过包装对象创建出一个和基本类型值相同的对象
var s2 = _str.chaAt(0); // 2 然后这个对象就可以调用包装对象下的方法,并且返回结给s2.
_str = null; // 3 之后这个临时创建的对象就被销毁了, _str =null;
)
alert(s2);//h
alert(str);//hello
基本包装类型:Boolean,Number,String
2、ECMAScript中 提供了三种基本包装类型
基本包装类型指的是将 基本类型包装成对象
ECMAScript中 所有的数据类型 都可以被装换成 Number Boolean String
Number Boolean String 是基本包装类型
var num = 198;
console.log(typeof num )// 'number'
console.log(num.toFixed(2))// num.toFixed() 对象.方法()
num变量 是基本数据类型 number 基本类型 不是对象 没有属性和方法 当我们需要对数值进行某些操作 需要使用一些功能(方法) JS引擎 就将 num 变量 临时包装成了一个对象 包装成对象以后 就可以使用方法了
var num2 = new Number(13);
console.log(num2 + 15) // 28
console.log(typeof num2) // Object
console.log(num2) // Number {13}
//---------------------------------
var str = new String('abc');
console.log(typeof str);
console.log(str + '123');
console.log(str);//abc123
var str2 = 'abcdefg'; // a boy can do everything for girl(只是个梗)
console.log(str2[3]); // 临时包装成了对象
console.log(str2.length); // 临时包装成了对象
for (var i = 0; i < str2.length; i++) {
console.log(str2[i]);
}
// ---------------------------------
var bool = new Boolean(true);
console.log(bool);//Boolean{true}
数据类型检测
typeof()
typeof 检测数据类型是不靠谱的 typeof 仅限于基本数据类型检测
console.log(typeof null);
console.log(typeof [1, 2, 3]);
console.log(typeof { x: 1 });
instanceof
ECMAScript 提供了另外一个不靠谱的关键字==instanceof==
var o = {}; // new Object()
var arr = []; // new Array()
var num = new Number(123);
console.log(o instanceof Object); // 看o 是不是由Object创建的 true
console.log(arr instanceof Array); // 看arr 是不是由Array创建的 true
console.log(num instanceof Number);// 看num 是不是由Number创建的 true
console.log(o instanceof Array); //false
console.log(num instanceof Array); //false
// 任何引用类型 instanceof Object 结果都是true
console.log(arr instanceof Object); //true
console.log(num instanceof Object); //true
console.log('123' instanceof Object); //false
console.log(new String('123') instanceof Object); //true
任何==引用类型== instanceof Object 结果都是true
constructor
==constructor== 构造函数 在EMACScript中 除了 null 和 undefined 之外 所有的数据类型 都可以访问到 constructor 所有的函数 都是有名字的 都有一个属性name
var o = {}; //对象
var arr = []; //数组
var num = 3; //数字
var bool = true; //布尔
var str = 'abc'; //字符串
var n = null; //空
var test; // undefined
console.log(o.constructor.name); // Object
console.log(arr.constructor.name); // Array
console.log(num.constructor.name); // Number
console.log(bool.constructor.name); // Boolean
console.log(str.constructor.name); // String
console.log(n === null); // 判断null时一定要用 全等 //true
console.log(test === undefined);//true
自定义函数
var o = {};
var arr = [];
var num = 3;
var bool = true;
var str = 'abc';
var n = null;
var test;
function getClass(target) {
return Object.prototype.toString.call(target).slice(8, -1);
//Object.prototype.toString.call(target) === [Object 类型]
}
console.log(getClass(o)); //Object
console.log(getClass(arr)); // Array
console.log(getClass(num)); // Number
console.log(getClass(bool)); // Boolean
console.log(getClass(str)) // String
console.log(getClass(n)); // Null
console.log(getClass(test)); // Undefined
// -----------------------------------------------------
// ES6(ES2015)
// 函数 Array.isArray()
// 判断一个值是否是数组
// 返回一个布尔值
console.log(Array.isArray(o)); // false
console.log(Array.isArray(arr)); // true
String 字符串类型
它是基本类型 字符串 的 对象包装类型
所有出现在引号中的数据 都是字符串
ECMAScript 为字符串提供了一系列用于操作的函数 帮助开发者 控制和修改字符串 这些方法都被保存在 String.prototype 中 String.prototype 是字符串的原型 原型中所有的 方法 都可以在基本字符中被访问 当基本字符串 调用这些方法时 它们会临时被包装成对象
length()
String.length 在每一个字符串的实例中 都可以访问到 length 属性 length 属性是一个number类型的值 表示字符串中的字符个数
var str = '122,334'; console.log(str.length);
字符串也是一个有序结构 可以使用索引 [index] 来访问字符串中的每一个字符 索引从0开始 最大索引 是字符串长度-1 console.log(str[3]);
charAt()
String.prototype.charAt() 语法: str.charAt(index); 参数: index(number) 索引 返回值: string 索引对应的字符 描述: charAt用于在字符串中获得指定索引的 字符 效果和 str[index] 相同
var str = '1234567';
console.log(str.charAt(2));
console.log(str[2]);
charCodeAt()
String.prototype.charCodeAt() 语法: str.charCodeAt(index); 参数: index(number) 索引 返回值: number 索引对应的字符的Unicode编码 描述: 获得字符的Unicode编码 范围 0-65535
数字 48-57 大写字母 65-90 小写字母 97-122
var str = 'abc0';
console.log(str.charCodeAt(3));
var str2 = '今晚小树林见';
var arr = [];
for (var i = 0; i < str2.length; i++) {
arr.push(str2.charCodeAt(i));
}
console.log(arr);
fromCharCode()
String.fromCharCode() 语法: String.fromCharCode(unicode); 参数: unicode 编码 返回值: string Unicode对应的字符
var res = arr.map(function (val) {
return String.fromCharCode(val);
});
console.log(res.join(''));
concat()
String.prototype.concat() 描述: 合并字符串(连接字符串) 语法: str.concat(value,[valueN]); 参数: value(string) 需要连接的字符串 返回值: 新字符串
var str1 = 'abc';
var str2 = '123';
var str3 = 'ok';
var str4 = str1.concat(str2, str3);
console.log(str4);
indexOf()
String.prototype.indexOf() 描述: 在字符串中查找指定的字符串 找到后返回第一个匹配的字符串的第一个字符的索引 没有找到返回-1 语法: str.indexOf(searchString[,fromIndex=0]); 参数: searchString(string) 需要查找的内容 fromIndex(number) 开始索引 默认值0 返回值: 索引 或 -1
var str = 'JavaScript';
console.log(str.indexOf('cri'));
lastIndexOf()
String.prototype.lastIndexOf() 描述: 在字符串中 从后向前 查找指定的字符串 找到后返回第一个匹配的字符串的第一个字符的索引 没有找到返回-1 语法: str.lastIndexOf(searchString[,fromIndex=0]); 参数: searchString(string) 需要查找的内容 fromIndex(number) 开始索引 默认值0 返回值: 索引 或 -1
var str = 'JavaScript';
console.log(str.lastIndexOf('rc'));// -1
slice()
String.prototype.slice() 语法: str.slice(start[,end]); 参数: start(number) 开始索引 end(number) 结束索引 返回值: string 新字符串 描述: slice 在字符串中 用于截取 从start开始 到end结束的字符串片段 截取结果包含 start所在索引 不包含end所在索引 如果没有end 截取到字符串的结尾 注意点: slice参数允许为负数 负数表示从后向前计算 -1表示最后一个 -2表示倒数第二个 以此类推
var str = '123456789';
console.log(str.slice(3));
console.log(str.slice());
console.log(str.slice(2, 6));
console.log(str.slice(3, -2));
console.log(str.slice(1, -1));
console.log(str.slice(12) === ''); // slice如果没有截取到内容 则返回空字符串 []
var o = {};
var str2 = o.toString();
console.log(str2.slice(8, -1));
spilt()
String.prototype.split(); 语法: str.split([sep]); 参数: sep(string) 分离器 用于切割字符串 描述: split在字符串中使用指定的分离器对字符串进行切割 将切割后的每一段内容 存入新数组 返回值: 新数组 split 是 join 的逆向操作
var str = '1,2,3,4,5';
var arr = str.split(',');
console.log(arr);//[1,2,3,4,5]
var str2 = 'a-b-c-d';
var arr2 = str2.split('-');
console.log(arr2);//[a,b,c,d]
var email = 'root@rootbk.cn';
var result = email.split('@');ff
console.log(result);//[root,rootbk.cn]
var path = 'E:/SynologyDrive/Drive/2202/stage2/week2/day9/code';
var paths = path.split('/');
console.log(paths);//[E:,SynologyDrive,Drive,2202,stage2,week2,day9,code]
var str3 = 'abcdefg';
var arr3 = str3.split(''); // 字符串转数组
console.log(arr3);//[a,b,c,d,e,f,g]
substr()
String.prototype.substr() 语法: str.substr(start,[length]); 参数: start(number) 开始索引 length(number) 长度 描述: substr 在字符串中截取 片段 从start开始 指定一个长度 返回值: 新字符串
var str = '123456789';
console.log(str.substr(2, 2)); // 34
console.log(str.substr(2)); // 3456789
substring()
String.prototype.substring() 语法: str.substring(start[,end]); 参数: start(number) 开始索引 end(number) 结束索引 描述: substring 在字符串中截取 片段 从start开始到end结束 返回值: 新字符串
当subtring的参数小于0时 或不是数字时 会被当做是0 当subtring的参数 start 大于 end 时 参数会交换位置
var str = '123456789';
console.log(str.substring(2, 6)); // 3456
console.log(str.slice(2, 6)); // 3456
console.log(str.substring(2, -1)); // 12
console.log(str.slice(2, -1)); // 345678
console.log(str.substring(5, -3)); // 12345
toLowerCase()
String.prototype.toLowerCase() 描述: 将字符串转换成小写字母
var str = 'ABC';
console.log(str.toLowerCase());//abc
toUpperCase()
String.prototype.toUpperCase() 描述: 将字符串转换成大写字母
var str2 = 'a123456abc';
console.log(str2.toUpperCase()); // A123456ABC
trim()
String.prototype.trim(); 语法: str.trim() 返回值: 新字符串 描述: trim 用于去除字符串前后的空格
var str = ' abc ';
console.log(str);// abc
console.log(str.trim()); //abc
原理
String.prototype.trim2 = function () {
return this.replace(/^\s+|\s+$/g,''); //把开头的空格或结尾的空格 替换为空
}
let str = ' aa a aa ';
console.log(str.trim2()); //aa a aa
repeat()
String.prototype.repeat() 语法: str.repeat(count); 参数: count(number) 重复次数 返回值: 新字符串
var str = 'abc';
console.log(str.repeat(5));
replace()
String.prototype.replace() 语法: str.replace(substr,replacement);
replace查找符合条件的字符串,替换成新字符串
参数: substr 符合的字符串
replacement 替换的字符串
stringObject.replace(regexp/substr,replacement)
var str = 'abc';
console.log(str.replace('a','b')); // bbc
String.prototype.replace() 语法: str.replace(regexp,string); 参数: regexp 用于匹配文本的正则 string 需要替换的新文本 描述: 在字符串中通过正则匹配内容 使用新的字符串替换被匹配到的内容 返回值: 新字符串 不修改原字符串
let str = 'h32e1ll654o w65orl654d';
// 删除字符串中的数字
let str2 = str.replace(/\d+/g,'');//把数字替换成空
console.log(str2);//hello world
let str3 = 'r3ewqgf 2gds a42GS36HF 38fd9s4326HG 8329';
// 去除字符串中的字母 剩余内容组成数组
let str4 = str3.replace(/[a-z]/ig, '');//'3 2 4236 3894326 8329'
console.log(str4.split(' '));//[3,2,4236,3894326,8329]
replace 应用
() 表示分组 分组可以看作是一个整体 每一对() 表示一个分组 这个分组会拥有一个编号 分组编号是从1开始的 (11)(22)(33) ((11)(22))(33)
分组的编号是按照左括号计算的
在replace中 需要替换字符串 可以使用分组编号表示 2 表示第二个分组匹配的字符串 ... 以此类推
let str = 'hahaha123';
// 交换字符和数字的位置
let str2 = str.replace(/([a-z]+)(\d+)/g, '$2$1');//交换位置
console.log(str2);//123hahaha
// 直接获得分组匹配内容*(非标准 不推荐)
console.log(RegExp.$1);//hahaha
console.log(RegExp.$2);//123
编写一个函数 计算字符串的长度(字节数) 中文汉字是 双字节 字符 字母和数字是 单字节 字符
[\x00-\xff] 单字节字符 [^\x00-\xff] 双字节字符
String.prototype.len = function () {
return this.replace(/[^\x00-\xff]/g, '11').length; //把双字节换成两个单字节
}
let str = '你好12啊3123';
console.log(str.len());//12
match()
String.prototype.match() 语法: str.match(regexp) 描述: match在字符串中通过正则的规则匹配内容 将匹配到的结果 放入一个新数组 返回值: 数组
let str = 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque inventore debitis ipsam voluptate dolorem enim natus quis praesentium unde? A provident non quis veniam rem consequuntur possimus maiores laudantium similique?';
// \b 匹配单词边界
let arr = str.match(/[a-z]+\b/ig);
console.log(arr);//以单词的数组
let str2 = 'h23el5lo 6534wo3r6435ld';
// 找到字符串中所有数字
let arr2 = str2.match(/\d+/g);
console.log(arr2);//[23,5,6534,3,6435]
汉字字节 == [\u4e00-\u9fa5] ==
let str3 = 'he你好llo w世or界ld';
// 找到所有汉字
// [\u4e00-\u9fa5]
let arr3 = str3.match(/[\u4e00-\u9fa5]+/g);
console.log(arr3);['你好','世','界']
search()
String.prototype.search() 语法: str.search(regexp); 描述: search在字符串中 通过正则匹配查找字符串 返回==第一个==与正则所匹配的字符串的第一个字符索引 返回值: 索引 或 -1 indexOf 正则版
let str = 'hel23lo wo645rld';
let index = str.search(/\d+/);
console.log(index); // 3
Date日期类型
Date 日期对象 引用数据类型 它是ECMAScript中的内置对象 可以使用 new 创建 Date 的实例
//日期对象创建
var d = new Date();
console.log(d); // 当前系统时间 和当前电脑的时间设置有关
console.log(typeof d);// object
var d2 = new Date(2008, 4, 12, 13, 21, 50); // 指定一个时间节点 创建时间对象 年月日 时分秒
console.log(d2);//Mon May 12 2008 13:21:50 //月份会比平常多1
var d3 = new Date('2008,5,12 13:21:50');
console.log(d3);//Mon May 12 2008 13:21:50
Date.now() //返回自 1970/01/01 到现在的毫秒数
Date()
日期对象的相关方法 都保存了在了 日期对象的原型中 Date.prototype
var d = new Date();
获取日期
| 方法名 | 描述 |
|---|---|
| getDate() | 返回Date对象“日期”部分数值(1~31) |
| getDay() | 返回Date对象“星期”部分数值(0~6) |
| getFullYear() | 返回Date对象“年份”部分实际数值 |
| getHours() | 返回Date对象“小时”部分数值(0~23) |
| getMilliseconds() | 返回Date对象“毫秒”部分数值(0~999) |
| getMinutes() | 返回Date对象“分钟”部分数值(0~59) |
| getMonth() | 返回Date对象“月份”部分数值(0~11) |
| getSeconds() | 返回Date对象“秒”部分数值(0~59) |
| getTime() | 返回Date对象与UTC时间1970年1月1日午间之间相差的毫秒数 |
| getTimezoneOffset() | 返回本地时间与格林威治标准时间(GMT)的分钟差 |
console.log(d.getFullYear()); // 获得年份
console.log(d.getMonth() + 1); // 获得月份 取值范围0 - 11
console.log(d.getDate()); // 获得日期 取值范围 1 - 31
console.log(d.getDay()); // 获得星期 取值范围 0-6 0表示星期天
console.log(d.getHours()); // 获得小时 取值范围 0 - 23
console.log(d.getMinutes()); // 获得分钟 取值范围 0 - 59
console.log(d.getSeconds()); // 获得秒钟 取值范围 0 - 59
console.log(d.getTimezoneOffset() / 60); // 当前时间 距离格林威治时间的 分钟差 //比北京晚8个小时
getTime 获得时间对象 距离 1970年1月1日 0年0分0秒的 毫秒差 这个数字 在计算机世界中 意义重大 时间戳 它在程序中是唯一不可重复的值
console.log(d.getTime()); // 从日期对象中获得时间戳
//快速获得 当前时间戳
console.log(Date.now()); // 1647831982885
//应用场景
//订单号设计(不重复)
2022032111080210312642885
//数据存储(在数据库中存储时间信息)
1647831982885
var d2 = new Date(1647831982885); // 将时间戳作为参数传入日期对象的构造函数还原日期对象
console.log(d2);//Mon Mar 21 2022 11:06:22
设置日期
一般set方法只会用到 setDate()
var d2 = new Date();// 2022/2/21
d2.setDate(d2.getDate() + 5); // 当前日期加5天
console.log(d2);
//日期对象的容错机制
d2.setDate(d2.getDate() + 15); // 21+15 == 36 超过了31 自动月份进1
console.log(d2);
var d3 = new Date();
console.log(d3);
// 日期对象允许直接运算 当日期对象参与运算时 会自动转换成时间戳进行运算
console.log((d2 - d3) / 1000 / 60 / 60 / 24);
| 方法名 | 描述 |
|---|---|
| setDate() | 设置Date对象“日期”部分数值(1~31) |
| setFullYear() | 设置Date对象“年份”部分实际数值 |
| setHours() | 设置Date对象“小时”部分数值(0~23) |
| setMilliseconds() | 设置Date对象“毫秒”部分数值(0~999) |
| setMinutes() | 设置Date对象“分钟”部分数值(0~59) |
| setMonth() | 设置Date对象“月份”部分数值(0~11) |
| setSeconds() | 设置Date对象“秒”部分数值(0~59) |
| setTime() | 以毫秒值设置Date对象 |
日期格式转换
| 方法名 | 描述 |
|---|---|
| toString() | 返回Date对象的字符串形式 |
| toDateString() | 返回Date对象“日期”部分(年月日)的字符串形式 |
| toTImeString() | 返回Date对象“时间”部分(时分秒)的字符串形式 |
| toLocaleString() | 基于本地时间格式,返回Date对象的字符串形式 |
| toLocaleDateString() | 基于本地时间格式,返回Date对象“日期”部分(年月日)的字符串形式 |
| toLocaleTImeString() | 基于本地时间格式返回Date对象“时间”部分(时分秒)的字符串形式 |
| toGMTString() | 基于GMT时间格式,返回Date对象的字符串形式 |
| toUTCString() | 基于UTC时间格式,返回Date对象的字符串形式 |
var d = new Date();
console.log(d);//现在时间
console.log(typeof d);//Object
//常见日期格式
console.log(d.toString());//现在时间的字符串
console.log(typeof d.toString());// String
console.log(d.toTimeString());// 14:24:43
console.log(d.toDateString());// Mon Apr 04 2022
console.log(d.toLocaleString()); // Locale 本地 // 2022/4/4 14:24:43
console.log(d.toLocaleTimeString()); // Locale 本地 // 14:24:43
console.log(d.toLocaleDateString()); // Locale 本地 // 2022/4/4
五、运算符与操作符
算数运算符
-
加法 +
-
减法 -
-
乘法 *
-
除法 /
-
取余 % (读音读mó)
- 表达式 a % b
- 含义:a 除以 b 获得未除尽的余数
var num = 7 % 3;
console.log(num) //1
- 幂运算 **
一元运算符
它指的是 只有一个值参与预算的运算符
++ 一元自增运算符 将运算符+1
-- 一元自减运算符 将运算符 -1
当一元自增、一元自减 成为独立语句时运算数 +1 或 -1
当一元自增、一元自减 不是独立语句时 需要考虑符号位置
- 当一元运算符出现在运算数前方时 将运算符+1/-1 然后使用运算数
- 当一元运算符出现在运算数后方时 使用运算数 然后将运算符+1/-1
a++;
++a;
a--;
--a;
一元 +
一元 -
一元 + 运算符 和 一元 - 运算符 可以将任意数据类型转换成number类型
其中一元+运算符的转换结果 不改变符号
一元 - 运算符的转换结果 改变符号
console.log(-'12') //-12
console.log(+null) //0
console.log(+undefined)// NaN
console.log(+'13.1a') //NaN
var o = new Object()
console.log(+o)//NaN
需要记住所有类型转number的结果 (ECMAScript中的所有数据类型都能转换成number类型)
关系运算符
判断两个数值之间的大小关系
关系运算符的结果是一个 布尔值
返回布尔值的表达式 叫做 布尔表达式
17 > 15 //true
17 >= 15 //true
17 <= 15 //false
17 < 15 //false
特殊情况
在比较字符串的大小关系时
EMCAScript会将它转换成 数值(number)进行比较
根据字符串的 Unicode 编码进行转换
- 是一种计算机存储基础字符的编码格式
- 它是由数字组成的
- 它的取值范围是(0-65535)
- 数字0 - 9 : (48-57)
- 大写字母A - Z: (65-90)
- 小写字母a - z : (97-122)
比较运算符
相等运算符(==) 和 不相等运算符(!=) 在比较不同数据类型时 会优先进行数据类型转换
转换原则:
- 在比较之前 如果有布尔值 则将布尔值转换成数字 true转1 false转0
- 在比较之前 如果有一个值是数字 另外一个值是字符串 则将字符串转换成数字
- NaN和任何值比较相等 结果都是false
相等比较运算符(==)
类似于数学中的等号
作用是比较两个值是否相等
比较结果相等 返回 true
比较结果不相等 返回 alse
相等比较运算符的表达式 也是 布尔表达式
15 == '15a' // false 15a=NaN
13 == '13' // true
true == 1 // true
0 == null // false // null不会进行类型转换
false == +null // true // +null==0 false==0
null == undefined //true
NaN == NaN // false
'NaN' == NaN // false 'NaN' 转换成NaN
'NaN' == 'NaN' //true
null == 'null' //false
undefined == 'undefined' //false
13.00 == 13 //true
'3.140' == 3.14 //true
' ' == false //true //因为空格转字符串的时候为0 false转字符串的时候为0 所以相等
不相等比较运算符(!=)
作用是比较两个值 不相等
比较结果相等 返回 false
比较结果不相等 返回 trues
13 != 14 // true
13 != 13 // false
undefined != NaN // true
全等操作符
全等操作符 和 不全等操作符 仅比较值是否相等或不想等
在比较前不会对数据类型进行转换
三个等号更严谨
全等操作符(===)
1 === '1' //false
不全等操作符(!==)
1 !== '1' //true
逻辑非操作符(!)
逻辑非操作符(!)可以用在EMCAScript任意数据类型之前
可以快速的将所有数据类型转换成布尔类型
作用:
- 将逻辑非操作符之后的数据转换成布尔类型
- 将转换后的布尔值求反
EMCAScript 中所有数据类型 都可以转换成 布尔类型
EMCAScript 中所有数据类型 都可以转换成 数字
EMCAScript 中所有数据类型 都可以转换成 字符串
任意非0的有效数转布尔类型 都是true
!123 //false
!0 //true
!3.14 //false
!-3.14 //false
null undeifned NaN 转布尔值结果都是 false
!NaN // true
!null // true
!undefined // true
使用在布尔值前面 直接求反
!false //true
!true //false
任意非空字符串转布尔类型 结果为true
空字符串转布尔类型为 false
!'abc' // false
!' ' // false
!'' //true
任意对象转布尔类型结果都是 true
var o = new Object();
console.log(!o) //false
逻辑与和逻辑或
短路运算(短路逻辑)
它是计算机对逻辑运算符(逻辑与和逻辑或)的一种求值策略(最小化求值)
当逻辑表达式的一个值能决定结果时 不在对另一个进行求值
当 逻辑或操作符 第一个操作值的结果为 true 则返回 第一个值 否则返回第二个值
当 逻辑与操作符 值结果都为 true 则返回 第二个值 否则返回第一个值
逻辑与(&&)
读作 and
运算符的左右 各有一个表达式
当左右表达式结果都为true时 则返回true
当左右表达式任意一个结果为false时 则返回false
3 > 2 && 5 > 4 //true
3 > 2 && 5 < 4 //false
逻辑或(||)
读作 or
运算符的左右 各有一个表达式
当左右表达式结果有true时 则返回true
当左右表达式都为false时 则返回false
3 < 2 || 5 < 4 //false
3 > 2 || 5 < 4 //ture
赋值运算符
本意 是赋值符和运算的简写
简写后 运算符的优先级就降低了
赋值符(=)
含义:将符号右边的值 赋予给 左边的变量
将符号右边的值赋予给左边的变量 符号结合性为右结合
var a = b = 3 //右结合 将3赋值给b 然后将b赋值给a
//变量声明 只声明了一个变量a
//变量一定要先声明 后使用
赋值的本意 是将 原有的值进行替换
var num=15
console.log(num); // 15
//第一种
var a = 1
var b = 2
var c
c = a
a = b
b = c
//第二种
var a = 1
var b = 2
a = a + b //3
b = a - b //1
a = a - b //2
+=
var num;
num+=5 //num = num + 5
-=
num-=5 //num = num - 5
字符连接符(+)
在 ECMAScript 中 + 有两个含义
- 算数运算符 加法运算
- 字符连接符
当 + 左右两边 有任意一边是字符串类型时 符号为 字符连接符
当 + 被看作是字符连接符时 不是字符串的一边会被转换成字符串类型 然后连接在一起
字符串连接符 可以用于快速改变数据类型(将任意类型的值转换成字符串类型)
true false NaN null undefined 转字符串类型都是原样转换
NaN和任意值进行任意的运算 结果都是NaN
console.log(12 + '31') // 1231
console.log('a' + null) // anull
console.log(undefined + '123') // undefined123
console.log(NaN + '31') // NaN31
console.log('1' + true) // 1true
console.log(15 + null) //15
console.log(NaN + 10) // NaN
console.log(NaN + 'NaN') // NaNNaN
var o = new Object();
//任意对象转换成字符串 都是'[Object Object]'
console.log(o + '123')// '[Object Object]123'
+null //快速转 number
!!null //快速转 boolean
'' + null //快速转String
条件运算符(三目运算符/三元运算符)
基本语法:
表达式1 ? 表达式2 :表达式3;
表达式1 是一个布尔值表达式
当表达式1的结果为 true 时 条件运算符的结果为 表达式2
false时 条件运算符的结果为 表达式3
条件运算符 很多情况下会配合赋值语句使用
var age = 15;
var message = age >= 18? '成年人' : '未成年人';
当表达式1 不为布尔表达式时
JS引擎会将其转换成布尔值进行判断
console.log('hello'? 'yes':'no')
(...)拓展运算符
... 扩展运算符(展开运算符) 这个符号来自ES6
//要求: 找到数组中的最大数和最小数
var arr = [65, 2, 325, 653, 4, 435];
console.log(Math.max(...arr));
console.log(Math.min(...arr));
console.log(...arr);
console.log(65, 2, 325, 653, 4, 435);
六、类型转换
隐式类型转换
ECMAScript 是一个 弱类型语言
在定义变量时没有约束数据类型
变量的数据类型 是由赋值操作来决定的
在代码的执行过程中 为了保证运行结果的正确 减少出错的情况 会有自动的类型转换发生
具体来说是在运算时 发生的数据类型转换 --> 隐式转换
console.log(3 + '2') // '32'
console.log(5 - '3') // 2
console.log('13' * 2 ) // 26
console.log(null + 7) // 7
console.log(undefined + 45) //NaN
//undefined 转换成number 结果是NaN NaN和任何数进行任何运算 结果都是NaN
console.log(+'55') // 55
console.log(12 + +'7') // 19
//一元加的优先级 高于 所有二元运算符
console.log(+true); // 1
console.log(++null) //出错
console.log(++1) //出错
//一元自增 和 一元自减 会对变量进行赋值
//无法直接给值使用一元自增/一元自减
var o = new Object();
console.log(+o) //NaN
//任意对象转换成数值型 都为NaN
6.2 强制类型转换
用户主动使用 函数 进行数据类型转换
Number()
将一个字符串解析成number类型 如果字符串不可解析 则返回NaN
Number 函数的转换结果与 一元+ 相同
可以使用一元 + 代替这个函数
console.log(Number('123')) // 123
console.log(Number('12.3')) // 12.3
console.log(Number('12.3a'))// NaN
Number()函数的转换规则如下:
-
如果是 Boolean 值,true 和 false 将分别被转换为 1 和 0。
-
如果是数字值,只是简单的传入和返回。
-
如果是 null 值,返回 0。
-
如果是 undefined,返回 NaN。
-
如果是字符串,遵循下列规则:
- 如果字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即"1" 会变成 1,"123"会变成 123,而"011"会变成 11(注意:前导的零被忽略了);
- 如果字符串中包含有效的浮点格式,如"1.1",则将其转换为对应的浮点数值(同样,也会忽略前导零);
- 如果字符串中包含有效的十六进制格式,例如"0xf",则将其转换为相同大小的十进制整 数值;
- 如果字符串是空的(不包含任何字符),则将其转换为 0;
- 如果字符串中包含除上述格式之外的字符,则将其转换为 NaN;
-
如果是对象,则调用对象的 valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是 NaN,则调用对象的 toString()方法,然后再次依照前面的规则转换返回的字符串值。
parseFloat()
将一个字符串解析成number类型 结果为一个浮点数 若字符不可解析 则返回NaN
console.log(parseFloat('3.14')) // 3.14
console.log(parseFloat('3.14a15')) // 3.14
console.log(parseFloat('3.1a45')) // 3.1
console.log(parseFloat('3.a1234')) // 3
console.log(parseFloat('31a.14')) // 31
console.log(parseFloat('a3.14')) // NaN
parseInt()
将一个字符串解析成number类型 结果为一个整数 若字符不可解析 则返回NaN
要被解析的值。如果参数不是一个字符串,则将其转换为字符串(使用ToString抽象操作)。字符串开头的空白符将会被忽略。
console.log(parseInt('3.14')) // 3
console.log(parseInt('31qw.w14')) // 31
console.log(parseInt('3.14a')) // 3
console.log(parseInt('a3.14')) // NaN
console.log(parseFloat('3.99999999999999')) // 3
console.log(parseFloat('3.9999999999999999999999999999999')) // 4
toString()
语法:value.toString()
作用:将指定的值转换成 字符串类型
ECMAScript 所有的数据类型 都可以转换成字符串
ECMAScript 中所有的数据类型都有toString函数(null 和 undefined 除外)
var num = 15;
console.log(num.toString()); // '15'
var bool = true;
console.log(bool.toString()); // 'true'
var o = new Object();
console.log(o.toString()) //[object Object]
var n = null;
console.log(n.toString()); //出错
var a;
console.log(a.toString()); //出错
number类型中的toString()
var num = 15;
console.log(num.toString()); // '15'
console.log(num.toString(2));// 将数值转换成2进制
console.log(num.toString(8));// 将数值转换成8进制
console.log(num.toString(16));// 将数值转换成16进制
Boolean()
将一个值转换成布尔类型
可以用(!!)来代替
console.log(Boolean(31)) //true
console.log(Boolean(!!31)) //true