JavaScript基础知识
2020-04-13 12:44:22 21 举报
AI智能生成
JavaScript基础知识
作者其他创作
大纲/内容
JavaScript基础知识
操作符
一元操作符
正负操作符
变量数值自增、自减(即 + 1、 -1)
var age = 29;age ++ ;alert(age); // 30
用在变量之前或者之后会有区别
如果用在前面,则变量会先 +1 再参与计算
如果用在后面,则变量会计算再 +1
布尔操作符(!)
布尔值取反
但是对于任何其他类型的数值,会有显式的转换
空字符串,返回true
非空字符串,返回false
NaN,返回true
二元操作符
位操作符
需要先了解
数值在计算机中的存储方式
二进制负数补码
按位非(~)
var num1 = 25 ;// 00000000000000000000000000011001var num2 = ~num1;//11111111111111111111111111100110
按位与(&)
var result 25 & 3; // 10000 0000 0000 0000 0000 0000 0001 11010000 0000 0000 0000 0000 0000 0000 0011AND0000 0000 0000 0000 0000 0000 0000 0001 //1
同1为1
按位或(|)
var result 25 | 3; // 10000 0000 0000 0000 0000 0000 0001 11010000 0000 0000 0000 0000 0000 0000 0011OR0000 0000 0000 0000 0000 0000 0001 1111 //27
有1为1
按异或(^)
var result 25 ^ 3; // 10000 0000 0000 0000 0000 0000 0001 11010000 0000 0000 0000 0000 0000 0000 0011XOR0000 0000 0000 0000 0000 0000 0001 1110 //26
1、0 不同为1
有符号左移(<<)
var oldValue = 2var newValue = oldValue << 5 //6410 << 5 = 100000
左移几位相当于 * 2^n ,在进制层面理解更透彻
保留符号位
有符号右移(>>)
同左移操作,友移几位相当于 / 2^n
无符号左移(<<<)
与有符号左移类似,但是不再考虑符号位
无符号右移(>>>)
与有符号右移类似,但是不考虑符号位
逻辑与(&&)
var result = true && false // false
逻辑与操作可以应用于任何类型的操作数,而不仅仅是布尔值
如果有一个操作数不是布尔值,那么返回的不一定是布尔值
如果第一个为对象,则返回第二个操作数
逻辑短路
如果第一个值为false,则不执行后面的计算
逻辑或(||)
var result = true && false; // true
如果第一个操作数是对象,则返回第一个操作数
如果第一个操作数为false,则返回第二个操作数
乘性操作符
乘法
var result = 34 * 56
除法
var result = 66/11
求模
var result = 26 % 5 // 1
加性操作符
加法
var result = 1 + 2
减法
var result = 1 - 2
关系操作符
> 、 < 、 <= 、>=
用于比较两个数值的大小 5 > 6 // false
非数值比较时不做赘述,不推荐
相等、不相等( == 、 !=)
5 == 5 // true
如果比较相等性之前先将其转换为数值,false为0,true为1
如果一个操作数是字符串,一个操作数是数值,那么会先键字符串转数字再比较
全等、不全等 (=== 、!==)
5 === 5 //true\"5\" === 5 //falsenull == undefined // false
全等于不仅要数值一致,数据类型也要一致才能返回true
条件操作符
var = boolean_expression ? true_value : false_value
var result = 5 > 3 ? 1 : 2 // 返回1
赋值操作符( = )
将右侧的数值赋值给左侧变量
乘/赋值 ( *= )
var num = 1 ;num *= 5 // 5相当于num = num * 5 其他操作类似
除/赋值(/=)
模/等于(%=)
加/赋值(+=)
减/赋值(-=)
左移/赋值(<<=)
右移/赋值(<<=)
逗号操作符
使用逗号操作符可以在一条语句中执行多个操作
流控制语句
if 语句
do-while语句
do { //执行的代码} while (循环条件)
while语句
与do-while语句不同的是,do-while先执行一次再判断,而while是先判断再执行
while(循环条件){ //执行代码}
for语句
for (语句 1; 语句 2; 语句 3){ //被执行的代码块}语句 1 (代码块)开始前执行语句 2 定义运行循环(代码块)的条件语句 3 在循环(代码块)已被执行之后执行
for(;;) 等同于while(true) 无限循环
for-in 语句
是一种精确的迭代语句,可以用来枚举对象的属性
for(perpertyName in expression) { //执行的代码块}
通过for-in 循环输出的属性名的顺序是不可预测的
label语句
不推荐
break 和 continue 语句
break立刻退出当前循环
continue跳过此次循环,继续下次循环
with语句
将代码的作用于设置到一个特定的对象中
with(expression) { //语句块}
var qs = location.search.substring(1);var hostname = location.hostname;与with(location){ var qs = search.substring(1); var hostname = hostname;}等价
switch语句
switch(n){ case 1: //执行代码块 1 break; //break必须要有,否则他会执行到下面的代码 case 2://执行代码块 2 break;case 3:case 4 : //合并两种情况break; default://与 case 1 和 case 2 不同时执行的代码}
js的switch可以在语句中使用任何数据类型
函数
函数可以封装任意多条语句,可以在任何地方,任何时候被调用
函数声明
函数可以有返回值,也可以没有返回值
return 语句之后停止并立刻退出,return语句后的代码永远不会执行
参数
arguments
arguments与数组类似,可以通过对应的下标来获取相应的参数
arguments.length查看代码传入参数的个数
修改arguments中的值,会同步修改形参的值,但是修改形参的值,arguments中的值不会被修改
callee属性
指向拥有这个arguments对象的函数
使用arguments.callee()就能调用函数本身
函数不能重载
this
与其他语言的this特征基本类似
this引用的是函数执行的环境对象,即在什么执行环境下,该this就指向哪个执行环境的对象
面向对象
ECMAScript中没有类的概念,因此与其他语言有所不同
对象是无序属性的集合,其属性可以包含基本值、对象或者函数
属性(property)
属性指的是与 JavaScript 对象相关的值
var cat = { color:'yellow' //color 就是 cat 的一个属性 }alert(cat.color); //在这里获取属性使用 . 符号
新增属性
var cat = { color:'yellow' }cat .weight = 600 //新增属性
JavaScript 对象是无序属性的集合
属性在创建时都带有一些内部特征值,通过这些特征值来定义他们的行为(比如:控制一个属性是否能被读写等)
属性分类
属性被分为两种类型,一种为数据属性,另一种为访问器属性,两种属性的内部特征不相同
数据属性
数据属性有4个描述其行为的特征
示例var pserson = { name:\"zhuo\"}
[[Configurable]]
表示是否能通过delete属性删除 以及 能否被配置特征值
[[Enumerable]]
表示能否通过for-in循环返回属性,默认为true
[[Writable]]
表示能否修改属性值,默认为true
[[Value]]
包含这个属性的数据值,读和写都从这个位置读写,这个特征的默认值为undefined
修改属性默认特征
使用Object.defineProperty()方法
如果执行了不符合特征值的操作,非严格模式下会自动忽略,而严格模式下则会报错
一旦将configurable配置为false,就不能再次修改为true了,而且修改除writable之外的特征,都会导致错误
访问器属性
[[Get]]
在读取属性时调用的函数,默认值为undefined
[[Set]]
示例
内部特征主要控制属性是否可配置、可删除、可枚举、可读写
定义多个属性
Object.defineProperties()
获取属性特征
Object.getOwnPropertyDescriptor()
内存
堆与栈
内存的回收(垃圾收集)
JavaScript具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存
常用垃圾收集方式
标记清除
当变量进入某个作用域时,就将他标记为进入环境,离开时则将其标记为离开环境
将系统中每个变量都存储起来,每过一个时间间隔去清除这些无用的内存
引用计数
引用计数存在相互引用的问题
参考资料和书籍
JavaScript高级程序设计
在线运行地址
https://www.sojson.com/runjs.html
语法
标识符
第一个字符必须是字符、下划线或者$符号,其他字符可以是字母、下划线、数字或者$符号
使用驼峰大小写格式
标识符语义明确,不要随便命名,方便阅读代码
区分大小写
注释
//单行注释
/** 多行注释**/
严格模式
使用 \"use strict\" 来告诉编译器下面代码使用严格模式
语句
每个语句结束以分号结尾
虽然可以省略分号,但是建议加分号,增加代码可读性、压缩、提高性能等
语句块
使用{}包裹
建议单行代码也使用语句块包裹,方便阅读
关键字和保留字
摘自:https://www.runoob.com/js/js-reserved.html
https://www.runoob.com/js/js-reserved.html
变量
声明变量
变量是弱类型的,一个变量可以存储任何类型的值
变量必须被声明后才能使用,否则会报错
var message;
声明
var message = \"hi\";
声明并赋值
可以在修改变量值的同时修改值的类型
let 与 var区别
变量提升
所有变量的声明语句都会被提升到代码头部,这就是变量提升。
暂时性死区
只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
var
函数作用域,不管声明在哪个代码块中,整个函数中都能随意使用
存在变量提升,所有Var声明的变量会提升到作用域开头声明
捕获变量奇怪
一个通常的解决方法是使用立即执行的函数表达式(IIFE)来捕获每次迭代时i的值:
可重复定义
使用var声明时,它不在乎你声明多少次;你只会得到1个。
let
块级作用域,作用域仅在当前代码块中
不存在变量提升,let语句声明的变量仅在当前语句块中
有暂时性死区
function f(input: boolean) { let a = 100; if (input) { // Still okay to reference 'a' let b = a + 1; return b; } // Error: 'b' doesn't exist here return b;}
无法重复定义
const声明变量
它们与let声明相似,但是就像它的名字所表达的,它们被赋值后不能再改变。
换句话说,它们拥有与 let相同的作用域规则,但是不能对它们重新赋值。
使用最小特权原则,所有变量除了你计划去修改的都应该使用const
解构赋值
对象解构
不仅声明时可以,声明变量后也可以解构赋值
嵌套的对象也可以解构
属性重命名
数组解构
除了花括号变成中括号,其他与对象解构一致
交换值
对象解构与数组解构可以嵌套使用
使用解构赋值表达式时,如果指定的局部变量名称在对象中不存在,那么这个局部变量会被赋值为undefined
解构同样可以放置于函数参数内
值的类型
基本类型
基本类型指的是简单的数据段,比如Number、Boolean、String类型
String类型属于基本类型
变量地址中存储的就是当前的数据段
摘自:https://www.cnblogs.com/embrace-ly/p/10659970.html
引用类型
引用类型指那些可能由多个值构成的对象
属性和方法
引用对象由属性和方法两部分组成,其中存储数据的称为属性,而提供操作的函数称为方法,方法也是属性的一种
变量地址中存储的是对象的引用地址,即指针
JavaScript不允许直接操作对象的内存空间,在操作对象时,实际上是在操作对象的引用
复制变量值
如果从一个变量向另一个变量复制基本类型的值,会新分配一个地址存储该值,两个变量存储地址相互独立,相互没有影响,修改其中一个变量的值不会影响另一个的值
如果从一个变量向另一个变量复制引用类型的值,也会新分配一个地址存储该值,但是这个值是一个指针,指向实际的存储在堆中的对象,两个变量会同时引用一个对象,改变其中一个变量,会影响另一个变量
函数形参
函数知识参考 函数
函数会把函数外部的值复制给函数内部的形参
基本类型的变量从函数外部传到函数内部改变值后外部不受影响,但是引用类型在函数内部改变对象内的属性值,外部变量也会受影响,因为外部变量和内部变量引用的是同一个堆中的对象
作用域链
当代码执行时,会创建变量对象的一个作用域链,作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问
作用域链的末端始终是当前执行的代码所在环境的变量对象
标识符解析是沿着作用域链一级一级地搜索标识符的过程,搜索过程从作用域链的末端开始,然后逐级回溯,直到找到标识符为止
直观表现为 当执行函数时,外部变量与局部变量命名相同是,总是先从函数内部找寻局部变量
var n = 4; //全局变量 function func(){ let n = 6 //局部变量 console.log(n) // 6 }
延长作用域链
使用with,try...catch等会延长作用域链
无块级作用域
例子:if(true){ var color = \"blue\"}alert(color) //blue
在C等语言中,这样做肯定报错,但在javaScript中并不会,javascript作用域以函数级为单位,只要在同一个函数中(即在一个函数环境中),那么该变量都可以用
定义变量时如果不加 var ,而是直接使用,那么他会加入到全局变量中
执行环境
全局执行环境
函数执行环境
进入某个函数后的环境
数据类型
Undefined类型
如果变量声明但未初始化,那么这个值为undefined,他的类型也为undefinded
Null类型
表示一个空对象指针
如果一个变量想用于存储引用变量,那么使用null赋值,如果是基本变量,那么undefined比较好
undefined == null // true
undefined 派生自null值
Boolean类型
只有两个字面值 : true|false
Number类型
Number类型可以用来表示整数和浮点
进制
十进制表示
55
八进制表示
067
以0开头,数字从0-7
十六进制表示
0x1f
以0x开头,数字从0 - f
二进制表示
0b1110
以0b开头,数字从0-1
特殊值
Infinity
超出 1.7976931348623157E+103088 的数值即为Infinity,小于 -1.7976931348623157E+103088 的数值为无穷小。
NaN
任何数值与NaN计算都会返回NaN值
NaN == NaN //false NaN与NaN本身也不相等
isNaN()函数能判断这个值是不是NaN
最大最小表示数
Number.MAX_VALUE
1.7976931348623157E+103088
Number.MIN_VALUE
-1.7976931348623157E+103088
超出这个范围数值会自动转为 Infinity 或者 -Infinity,这个值不能参与下一次运算了
其他
科学计数法
1.1123e7
表示 1.1123 * 10 ^7
默认情况下,ECMAScript会将小数点后面带6个0以上的浮点数转换为e表示法
浮点数计算会存在舍入误差问题,其他语言也有相同的毛病,切记此点
例子:0.1 + 0.2 = 0.30000000004
String类型
用于表示零或者多个16位Unicode字符组成的字符序列
var firstName=\"Zhuo\"
使用单引号、双引号都行,但是必须配对
字符串中存在单双引号则需要使用转义符\\'、\\\"表示
通过 .length获得字符串长度
字符串拼接, 使用 + 拼接即可
模板字符串let name = 'zzz';let say= `My name is ${name}`;
& 即可以使用变量,也可以使用计算值 比如: ${age + 2 )
Object类型
Object其实就是一组数据和功能的集合
创建方式
var o = new Object()o.name = \"Zhuo\";o.age = 25
var o = { name:\"Zhuo\
推荐
访问对象的方式
使用 . 操作符
o.age // 25
使用方括号
o[\"age\"] // 25
删除对象属性
delete o.name
每个Object都有下列属性和方法
Constructor
构造函数,保存着用于创建当前对象的函数
hasOwnProperty(propertyName)
用于检查给定的属性在当前对象实例中是否存在
isPrototypeOf(object)
检查传入的对象是不是另一个的对象的原型
原型详见(未完成)
propertyIsEnumerable(propertyName)
用于检查给定的属性是否能够使用for-in语句
for-in详见 流控制语句-for-in语句
toLocaleString()
返回对象的字符串表示,该字符串与执行环境的地区对应
toString():返回对象的字符串表示
valueOf()
返回对象的字符串、数值或者布尔值表示,通常与toString()相同
内置类型
Array类型
ECMAScript中的数组与其他语言中的数组区别很大
数组每一项都可以存储任何类型的数据
new 创建
var colors = new Array();var colors = new Array(); //创建并指定长度var color = new Array(\"red\
字面量表示法创建
var colors = [\"red\
空留的位置都会被填充为undefined
.length
获取当前数组长度
如果数组长度不够,再往里加数据会自动扩容
实用函数
join()函数
用于将数组每一项以特定分隔符隔开合并为一个字符串
Array能像栈或者堆一样工作,提供多个实用功能
push()函数
推送任意数量个数组项到数组末尾
pop()函数
取得并移除最后一项
shift()函数
取得并移除第一项
unshif()函数
在数组开头推入任意项
排序
reverse()函数
倒序排序
sort()函数
升序排序
排序之后都会返回新的数组,与原来数组不相等
concat()函数
向后拼接一项或者多项,实参可以是数组
slice()函数
切片(截取)数组
示例var colors = [\"red\
splice()函数
splice() 方法向/从数组中添加/删除项目
index
从哪一项开始
howmany
删除多少项
item1...itemX
插入的项
位置方法
indexOf()函数
查找某一项在数组的什么第一个位置,从头查找,找不到返回-1
lastIndexOf()函数
迭代方法
every()函数
如果数组中每一项都满足条件,才返回true
some()函数
如果数组中有一项满足条件,就返回true
filter()函数
过滤出满足条件的项
forEach()函数
遍历所有项
map()函数
将每一项进行转化后返回
缩小方法
reduce()函数
遍历所有值,然后构建出一个值返回,从头到尾遍历
reduceRight()函数
遍历所有值,然后构建出一个值返回,从尾到头遍历
Date类型
时区在这里不做讨论
使用自UTC 1970年1月1日0时开始经过的毫秒数来保存日期
var now = new Date();
自动获得当前的日期和时间
解析函数
Date.parse()
如果字符串不能表示日期,则会返回NaN
UTC月是从0开始的,也就是一月为0,二月为1
其中年、月是必需的,其他都可以缺省
其他实用工具函数
Date.now()
获取当前时间毫秒数
RegExp类型
正则表达式详解(未完成)
var expression = /pattern / flags ;
var expression = new RegExp(\"[bc]at\
pattern
正则表达式
flags
每个正则表达式可以一或者多个flags
正则表达式的匹配模式支持下列3个标志
g
全局模式,即模式被应用于所有字符串,而非在发现第一个匹配项时立即停止
i
表示不区分大小写,即在确定匹配项时忽略模式与字符串的大小写
m
表示多行模式,记载到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项
test()函数
如果只想知道目标字符串是否匹配该模式,使用test()即可
var text = \"000-00-0000\";var pattern = /\\d{3}-\\d{2}-\\d{4}/;alert(pattern.test(text)); //true
exec()函数
匹配正则函数,匹配结果使用Array()实例返回
无匹配项时返回null
index表示匹配项在字符串中的位置 0
input表示应用正则表达式的原始字符串
var text = \"mom and dad and baby\";var pattern = /mom( and dad( and baby)?)?/gi;var matches = pattern.exec(text);alert(matches.index); //表示匹配项在字符串中的位置 0 alert(matches.input); //表示应用正则表达式的原始字符串 mom and dad and babyalert(matches.length);//返回结果的数组长度alert(matches[0]); //mom and dad and babyalert(matches[1]); //and dad and babyalert(matches[2]); //and baby
此数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(如果有的话),以此类推。
它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。
Function类型
在ECMAScript中,函数实际上是对象,每个函数都是Function类型的实例。与其他对象一样具有属性和方法
因此函数名实际上也是指向函数对象的指针
函数也可以当参数传入或者当做返回值传出
length
表示希望接收参数的个数,即形参定义数量
prototype
参考(未完成)
apply(作用域,参数数组)方法
调用函数,并指定作用域和参数
主要的作用是扩充函数的作用域
与apply作用相同,传参方式不同
基本包装类型
基本包装类型包括
单体内置对象
这些对象在程序执行之前就自动实例化好了
Global对象
基本上在代码中可以直接使用方法都是Global的方法,比如:isNaN、parseInt()等等,但是不需要显示地去写出Global. 来调用
Math对象
常用操作的方法繁多,在这里不再赘述
各个类型之间比较和互转
其他类型转Boolean
使用转型函数Boolean()转化
其他类型转Number
使用转型函数Number转换
false转0,true转1
String 类型
有具体含义各种进制的数值的字符串都会转为数字,否则转为NaN
null值
0
undefined
使用parse函数
专门用于字符串转数字
parseInt()
可自动解析各种进制整数,也可通过第二个参数指定进制数
可解析的格式
1234Blue
1234
\"\"
0xA
10
22.5
22
parseFloat()
只解析十进制数
如果一个数没有小数点,那么他会解析返回整数
1234Blue
22.23.5
22.23
0908.5
908.5
其他类型转String
toString()方法
几乎每个值都有toString()方法
Stirng()函数
在不确定转换值是不是null或者Undefined的时候建议用这个函数
转换规则
如果值有toString()函数,那么直接调用该函数
nll 则 返回 \"null\"
undefined 则返回 \"undefined\"
Boolean值返回 \"true\" 或者 \"false\"
Object 如果未重写toString(),则返回返回 [Object object]
typeof 操作符
typeof 操作符可以获取该变量的数据类型
instanceof
检测某个对象的值是不是另一个对象的实例
函数柯里化
在一个函数中,首先填充几个参数,然后再返回一个新的函数的技术,称为函数的柯里化。通常可用于在不侵入函数的前提下,为函数 预置通用参数,供多次重复调用。
const add = function add(x) {return function (y) { return x + y }}
只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
只有拥有闭包的语言才能函数柯里化
立即执行的函数表达式
当需要声明一个函数并立即执行函数时,可以使用该表达式
(function () { /* code */ } ()); //推荐或者(function () { /* code */ })(); // 比较常见
代码结构分析
(function () { /* code */ } ());前面function内的代码块即为需要立即执行的代码
(function () { /* code */ } ());后面的括号表示调用前面这个函数,当然,这个括号内是可以传入参数的
(function () { /* code */ } ());因为js编译器在解析时,看到function声明,以为后续是一个函数声明,到最后发现一对无用括号,则会报错,如果给最外层增加一个括号,就能让编译器知道,这是一个表达式,就不会报错了
立即执行函数我个人将他称为 匿名内部函数表达式
个人认为这个就是JavaScript设计的毛病,导致产生的奇怪语法
ES6
箭头函数
ES6标准新增了一种新的函数:Arrow Function(箭头函数)。
代码示例
箭头函数看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。
Promise
Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。
promise 状态
pending:初始状态,既不是成功,也不是失败状态
fulfilled:操作成功
rejected:操作失败
示例代码
async await(未深入学习)
使用
当调用一个 async 函数时,会返回一个 Promise 对象
当这个 async 函数返回一个值时,Promise 的 resolve 方法会负责传递这个值;
当 async 函数抛出异常时,Promise 的 reject 方法也会传递这个异常值。
async 函数中可能会有 await 表达式,await表达式会使 async 函数暂停执行,直到表达式中的 Promise 解析完成后继续执行 async中await 后面的代码并返回解决结果
注意, await 关键字仅仅在 async function中有效
async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
0 条评论
回复 删除
下一页