系列文章目录
第二章:在html中使用javaScript
第三章:基本概念
第四章:变量作用域和内存问题
目录
前言
这本书是我刚入行的时候我师傅推荐给我的,当时只想获得实现的满足感,而一直没有深入学习。随着页面实现了更多后,发现学好javascript非常的有必要,这也是这个系列出现的缘由~
我将分章节学习并记录(第一章简介我就不记录了,有兴趣自己去看看),如果内容太多也会分为上下两小节。
学习过程中也会拓展一下相应内容,思考一些问题,感兴趣就继续往下看看吧~
这一章主要记录一些基本语法、数据类型、操作符、语句、函数等,这些都是我们会常用的滴~
一、语法
1.标识符
标识符:变量、函数、属性的名字
- 标识符第一个字符必须是字母或_或$,不能是数字或其他特殊字符,变量推荐驼峰命名
- 标识符区分大小写的,所以name 和Name并不相等
- 不能把关键字、保留字、true、false、null作为标识符
- 在代码开头或函数开头写 “use strict”可开启严格模式
2.关键字和保留字
关键字:控制语句中的一些开始或结束的字,如:break 、continue、if 、else、do 、while、catch 、case等
保留字:不是关键字但未来可能成为关键字的字,如:export 、static 、throw、debugger、doouble等
二、数据类型
我们都知道基本数据类型有五种:null、undefined、string、number、boolean
引用数据类型:object
1.null
表示一个空的指针对象,所以type of(null)等于object。
一般情况下,我们要定义定义变量为对象,但还没有定义的时候,可用定义为null
2.undefined
undefined表示定义个一个变量,但未赋值。
undefined派生自null,所以undefined ==null 等于true
3.boolean
有两个值:true、false,区分大小写
虽然0能转化为false,但false不一定等于0;1能转化为true,但true不一定等于1;
3.1转型函数
提供一个转型函数Boolean()。转化规则如下:
- 当为空字符串‘ ’,0、null、undefined、NaN的时候,转为false;
- 其他情况下转为true;
4.string
表示字符串
4.1字面量
我们这里了解一下字面量,string类型包含了一些字面量(转义序列),例如:\n(换行)、 \t(制表)、 \r(回车) 、\b(空格)、 \f(进纸)等
4.2转型函数
提供了两个转型函数:toString()、String()
这两个函数区别在于:
toString()是每个值都有的一个方法,能返回字符串表现(可指定进制)
String()首先会查看是否有toString(),有就使用这个方法返回;如果没有就返回字符,如遇到null 和 undefined 则返回 “null” 和 “undefined”
5.Number
数值型,支持进制、默认十进制。
NaN(非数值)属于一个特殊的数值,任何数除以NaN都等于NaN。NaN ==NaN 等于false,所以提供了isNaN()来检测是否为NaN,只要是非数值就返回true。
对于极大的数值,可以用infinity或-infinity表示,也可用e(后面指数可指定正负)表示,如:3.1e10 = 3.1 * 10的10次方
5.1转型函数
提供三个转型函数:Number()、parseInt()、parseFloat()
同:转为数值,都可识别进制
三者区别在于:
- Number()可转化所有类型
- parseInt()转化整形
- parseFloat()转化浮点型
Number()转化规则:
- 数值:如果是进制则转为对于十进制;其他转为对于数值,首位为0忽略;
- true转为1,false转为0
- null、“ ” 转为0,undefined和除上面的其他类型都为NaN
- 如果是对象则调用valueOf(),没有就调用toString()
parseInt()和parseFloat():
这两个转型函数的出现其实是因为Number()的不足处理字符串时比较复杂且不合理
这两个函数有相似的地方:都是从第一个数字开始识别(忽略空格和0),如果第一个不是数字则返回NaN,至不是数字的位置
parseInt()可指定进制,默认第二位是10;
pareFloat()只能解析十进制。
6.object
object是数据和功能的集合,我们通常会通过new Object()创建一个实例。对象中包含属性或方法。我们来看一下object中都有的属性:
- constructor:构造函数,指向创建这个对象的函数
- hasOwnProperty():判断属性是否存在于当前对象里面
- isPrototypeOf():检查传入的对象是否是传入对象的原型
- propertyIsEnumber():检查属性是否能使用for in 来枚举
- toLocaleString():返回该地区的字符串
- toString():返回字符串
- valueOf():返回对象的字符串、数值或布尔值表示。一般情况下与toString()返回结果相同
三、操作符
1.一元操作符
一元操作符包括四种,这个和C语言中的差不多
//先计算再自增(减)
i++;
i--;
//先自增(减)再计算
--i;
++i;
-i;//变相反数
+i;
2.位操作符
位操作数就涉及到二进制问题啦,我们先来了解一下原码、反码、补码的关系
如果是正数,原码 = 反码 = 补码
如果是负数,反码 = 原码的绝对值的反码;补码 = 反码 + 1
位操作符主要有四种:按位与、按位或、按位非、按位异或、左移、有符号右移、无符号右移
2.1 按位与(&)
简单来说就是只有两个都为1的时候才等于1,其他情况都为0
例:0101 & 1001 = 0001
2.1 按位或(|)
有一个及以上为1就等于1,其他情况都为0
例:0101 | 1001 = 1101
2.1 按位非(&)
取反码,如:~10100 = 01011
2.1 按位异或(^)
只有一个都为1才等于1,两个为1或两个为0时都为0
例:0101 ^ 1001 = 1100
2.1 左移(<<)
这里我们需要知道进制是32位的,第一位是符号位(0表示正,1表示负),剩余31位是放数值的。通常喜欢使用二进制来表示,前面没写的位数都是用0来填充的,例如:1010(十进制为10)的表示其实如下:
1010 = 00000000000000000000000000001010
再讲回我们的左移,左移后空位用0来填充。以2(二进制为10)为例子:
2<< 5
结果为:1000000(十进制等于64)
2.1 有符号右移(>>)
有了左移的例子,右移也很好理解了。
就是将其向右移动,空位用0来填充,例如:
64>>5
结果就是0000010(十进制等于2)
2.1 无符号右移(>>>)
无符号右移和有符号右移最大的区别就是右移后的空位用符号位填充,对正数来说结果和有符号右移的相同,对负数来说就不相同拉。
例如:
64 >>> 5 //结果为2
-64 >>> 5 //结果就不一样拉
首先,负数的二进制表示是反码+1,反码又等绝对值(原码),所以-64的二进制表示为:
11111111111111111111111111000000
此时我们再无符号右移5位,空位用符号位填充(符号位为1),结果为:
11111111111111111111111111111110
转化为十进制结果为:134217726
3.布尔操作符
布尔操作符是用来测试两个值关系的能力。像我们经常使用 if(a&&b) else ,这样的语句用来判断值得关系。
他与位操作符相似,也有三种操作符:与、或、非
3.1与( && )
两个值都为true时候才返回true,否则返回false
举个例子:a && b
我们先检测a,如果a为false,直接返回false,不需要往下走了;当a为true,我们再去检验b ,如果b为true则这个结果为true,否则返回flase。
针对不是数值规则如下:
- 当遇见null、undefined、NaN则返回原数
- 当第一个数值是对象,则返回第二个值;如果两个都是对象则返回第二个对象;
3.2或( || )
有一个值为true就返回true
或和与一样,如果第一个值能决定返回值,就不需要鉴别第二个啦。如果第一个值为false,则返回第二个值。
针对不是数值规则如下:
- 当遇见null、undefined、NaN则返回原数
- 当第一个数值是对象,则返回第一个;如果两个都是对象则返回第二个对象;
3.3非( ! )
表示取相反数,例如:! true = false。如果你想让一个值转为真正得布尔值,则用 !! 转化。
转化规则如下:
- 当遇见0、“ ”、null、undefined、NaN则返回true
- 当遇见对象(可以理解为true)时,返回false
- 当遇见非空字符串或非0数值都返回true
4.乘性操作符
乘性操作符包括:乘法(*)和除法(/),这就和我们数学中的一样。还有一个求模(%),就是求余数
4.1 乘法(*)和除法(/)
当遇见不是数值的值,我们会先用Number()转为数值再运算。
这里要注意的特殊规则:
- 当遇见NaN的时候,不管是乘法还是除法都等于NaN
- 当遇见 infinity 或 -infinity时,
- 乘法:
- infinity * 0 = NaN
- infinity * infinity = infinity
- 除法:
- infinity / infinity = NaN
- 0 / 0 =NaN
- 非零有限数 / 0 = infinity
- 乘法:
4.2求模(%)
就是求余数。他也有几个特殊例子:
- infinity % 有限大 = NaN
- 有限大 % 0 = NaN
- 有限大 %无穷大 = 有限大
- 0 % 任何数 = 0
5.加性操作符
加性操作符包括加法和减法,
5.1加法(+)
正常情况下,如何是数值型,则和数字中的加法相同,特殊情况如下:
- 有一个为NaN,结果就为NaN
- infinity + infinity = infinity
- -infinity + -infinity = -infinity
- infinity+ -infinity = NaN
- 0 + 0 = 0
- -0 + -0 =-0
- 0 +-0 = 0
如果相加中有字符串,则将两个转为字符串连接起来,如:3 + “你好” = “3你好”
如果有操作数是对象、数值、布尔值,则调用toString()方法取得相应字符串在计算。如果是undefined、null 则转化为“undefined”、“null”
5.2减法
正常情况下,如何是数值型,则和数字中的减法相同,特殊情况如下:
- 有一个为NaN,结果就为NaN
- infinity - infinity = NaN
- -infinity - -infinity =NaN
- infinity+ -infinity = NaN
- 0 - 0 = 0
- -0 - -0 =0
- 0 +-0 = -0
如果有操作数是字符串布、尔值、undefined、null ,则调用Number()方法转为数值在计算。如果是NaN,则结果为NaN
如果有操作数是对象则调用valueof()方法,如果没有则调用tostring()方法在计算
6.关系操作符
关系操作符包括> 、<、>= 、<=,基本和数学一样。特殊情况如下:
- 如果操作数是字符,则比较两个字符的编码值
- 如果是对象,使用valueof()或tostring()方法转换后计算
- 如果一个为数值,则将另一个也转化为数值
7.相等操作符
包括==、===、!=,这里值得注意的是,相等和不相等当类型不同时会转换类型比较,全等和不全等是只比较,不转换。
相等与不相等的情况下,
- 当有一个值为数值时候,将另外的值转为数值;
- 当有一个值为对象的时候,调用valueof()得到基本值在比较
- 当有一个值为boolean的时候,另一个转为布尔再比较
- 这里值得注意的是,NaN不等于NaN,所以才有isNaN()的方法
全等和不全等,只有在类型和数值都相等的情况才会返回true
8.条件操作符
格式如:条件?满足:不满足
当满足条件的时候执行第一个操作,不满足执行第二个操作
例:x>y ? "满足" : "不满足"
9.赋值操作符
可以用=来赋值,也可以在前面添加操作符组合成复合赋值,如:
a+=b 等价于a=a+b
a-=b 等价于a=a-b
10.逗号操作符
通常用来隔开定义的多个变量,如:let a=0,b=2,c=3
还可以用来赋值,不过我们很少用,如:let a =(1,2,3,4,5) ,结果为最后一个值,所以结果为5
四、语句
1.if
这个算经常用的了,和他配套的有else 、else if,满足条件则执行,不满足就执行else if ,都不满足则执行else,如:
if(a>b){
console.log("a大于b")
}else if(a==b){
console.log("a等于b")
}else{
console.log("a小于b")
}
2.do while
标准后测试语句(先执行在判断是否满足条件),如:
var i =0
do{
i+=2
console.log(i)
}while(i< 10)
输出:
2 4 6 8 10
3.while
前测试语句(满足了条件才会执行),如:
var i=0
while(i<10){
i+=2
console.log(i)
}
输出:
2 4 6 8 10
4.for
常用的循环语句。如:
for (var i=0;i<10;i++){
console.log(i)
}
输出:0-10的数字
5.for in
用来枚举对象的属性,如:
let obj = {
name:'lily',
age:"18",
sex:'女'
}
for (var i in obj){
console.log(i)
}
输出:
name
age
sex
6.label
在语句中添加标签,通常和break ,continue结合使用
7.break 和continue
break表示跳出整个循环,如:
for(var i = 0;i<10 ;i++){
if(i%2 == 0){
break
}
console.log(i)
}
没有输出,因为i=0时就跳出循环了,不会执行break后的语句
continue表示跳出本次循环,如:
for(var i = 0;i<10 ;i++){
if(i%2 == 0){
continue
}
console.log(i)
}
输出:1 3 5 7 9
双层嵌套情况下可结合label使用,我们来分情况看一下
不加label的时候的break,如下:
for(var i = 0;i<3 ;i++){
for(var j = 0;j<3 ;j++) {
if (i==j) {
break
}
console.log(i,j)
}
}
输出:
1 0
2 0
2 1
加了label后,break会跳出整个循环,如下:
stag:
for(var i = 0;i<3 ;i++){
for(var j = 0;j<3 ;j++) {
if (i==j) {
break stag
}
console.log(i,j)
}
}
没有输出,因为当i=0的时候,j初始值也为0 ,所以跳出了双重循环
当只有continue的时候,如下:
for(var i = 0;i<3 ;i++){
for(var j = 0;j<3 ;j++) {
if (i==j) {
continue
}
console.log(i,j)
}
}
输出:
0 1
0 2
1 0
1 2
2 0
2 1
加了continue后,会跳出内层循环,如下:
stag:
for(var i = 0;i<3 ;i++){
for(var j = 0;j<3 ;j++) {
if (i==j) {
continue stag
}
console.log(i,j)
}
}
输出:
1 0
2 0
2 1
8.with
用处是将一个作用域设置到特定对象中,目的是减少多次重复写同一个对象,如下:
var a = obj.name
var b =obj.age
var c = obj.sex
换成with可以这样写:
with(obj){
var a = name
var b =age
var c = sex
}
//上面代码认为a,b,c是一个局部变量,如果在局部中没有找到定义的变量,则去obj里面去找,并赋值
注:
- 严格模式下不允许使用with,会报错
- 大量使用with会导致性能下降,所以大型开发中不建议使用with语句
9.switch
和if一样是条件判断,switch case主要是为了解决多个if elseif else造成的代码不雅的情况,通常和case搭配使用,如下:
switch(i){
case 1:
console.log("i等于1")
break;//表示跳出switch,不加这个,这个case执行完后还要执行剩下的所有case
case 2:
console.log("i等于2")
break;
defalut://表示除上所有条件后的值走的路,l类似else
console.log("i等于其他值")
}
也可以合并条件,例如:
switch(i){
case 1:
case 2:
console.log("i等于1或2")
break;
defalut:
console.log("i等于其他值")
}
五、函数
函数是较为重要的角色,我们通常这样定义函数,如下:
//定义
function add(a,b){
retrun a+b //可以写retrun设置返回值,也可以不写
}
//使用
add(2,3)
函数中一个argument对象,它包含了所有参数,我们可以通过argument调用参数,如下:
//定义
function add(a,b){
let result = arguments[0] +arguments[1]
retrun result//这里的返回值和a+b是相同的
}
//使用
add(2,3)
注:值得注意的是,虽然他们相同,但a,b,arguments是独立的内存空间,他们的值是对应的,但不是同一个内存空间,且不可对arguments进行赋值,会报错。
这里再说一下重载,其他语言中都有重载这个概念。当定义了相同命名的函数,只要两个函数拥有不同签名,则表示两个不同函数,但是,在js当中,没有重载这个概念,第二个函数只会覆盖掉第一个函数。
总结
以上就是今天要讲的内容,本文讲诉了基本概念,包括基本数据类型,操作符,语句,函数等内容。