1 javascript简介
Javascript是一种运行在浏览器中的解释型编程语言。
一个完整的JavaScript实现应该由ECMAScript,DOM,BOM组成
为了让JavaScript成为全球标准,ECMA(European Computer Manufacturers Association)组织定制了JavaScript语言的标准,被称为ECMAScript标准。
所以简单说来就是,ECMAScript是一种语言标准,而JavaScript是网景公司对ECMAScript标准的一种实现。
2 数据类型
javacript的数据类型可以大致分为两种,一种是原始类型,一种是Object对象。原始类型有五种:
Number
,String
,Boolean
,null
以及undefined
,而Object对象则有很多种了,比如说Function
,Array
,Date
,RegExp
,JSON
等等。
想要知道数据的类型,可以调用以下几种方法:
-
typeof
:调用typeof(something)
能区分原始类型以及Object类型中的Function
,其中由于JS的历史问题,测试null
类型的时候会返回object
,typeof
是一个操作符而不是一个函数,所以后跟的括号可以省略,使用空格隔开。 -
instanceof
:与python的isinstance()
的作用差不多,都是判断对象的类型,返回布尔值。JS的instanceof
是依据原型链,也就是说这里的son instanceof father
并不能测试原始类型,只能测试出Object对象。
注:Array的判断只能使用Array.isArray(xxx)
,NaN也只能使用isNaN(xxx)
来辨认。 -
Object.prototype.toString.apply(someting)
:这个返回的是字符串的形式如[Object Date]
,这个能区分原始类型以及Object对象。
##2.1 数字(Number)
JavaScript不同于python分为int
和float
,数字类型就只有一种number
。number
可以表示整数,浮点数,科学计数法以及两个比较特别的值NaN
和Infinity
(JavaScript严格区分大小写)。 -
NaN
:不同于python的None
,NaN
的意思是Not a Number,当无法计算结果时用NaN
表示,注意这与undefined
是两码事。(放在python里头就是一个error) -
Infinity
的意思是数值无限大
2.2 字串符(string)
2.2.1 反引号
字符串的表达完全与python一样,转义符\n
,\t
,\x##
表达十六进制ASCII字符,\u####
表示一个Unicode字符。
唯一比较特殊的就是这个 ` 反引号了,这个反引号的作用有:
- 表示多转行字串符,不需要使用
\n
转行符,只需要将想表达的样式包含在反引号内就可以了,就像这样
`ab
cd
`
- 可以定制模板化,格式化字串符,就像python字串符中常常用到如
"str %s"%(x)
格式化字串符一样,而这里的反引号就代替了引号的作用了,而$
号代替了百分号的作用,就像这样
var a = "seiei"
console.log(`Hello,${a}!`)
2.2.1 操作字串符
JavaScript的字串符也是可以操作的,像python一样,JavaScript的字串符是不可变量,操作字符串本身不会影响原字符串,只会生成另一个字符串。
"use strict";
var a="Seiei";//可以像python使用索引
a.length;//等同于python的len(str),不过注意这个像是类的属性值
a.toUpperCase();//等同于python的upper(),调用类的方法?
a.toLowerCase();//等同于python的lower(),调用类的方法?
a.indexOf("e");
a.indexOf("e",2);//第二个参数是指从哪个索引开始,包含该参数
a.lastIndexOf("e");//从后往前数
//类似于python的index(),不过当查询不存在的字符时,不会报错,而是会返回值'-1'
a.slice(0,4);
a.substr(0,4);
a.substring(0,4);
/*输出从索引0开始到3的字节符
*注意substring()会把所有负值参数转化为0;
*slice()会将负值与字串符长度相加;
*substr()会将第一个参数的负值与字串符长度相加,第二个参数的负值改为0
*/
/* 使用trim方法可以删除字符串头尾的空格 */
var a=" abc ";
var b=a.trim();
alert(b);//abc
2.3 布尔值(Boolean)
JavaScript的布尔值也是true
和false
(python的是大写首字母)。
其中布尔值运行符号:
&&
:与运算(python的and
)||
:或运算(python的or
)!
:非运算(python的not
)
另外,&&
与||
还可以使用在运算过程,赋值的行为上,比如说
a = b&&c
,如果b为真,则a=c,若b为假,则a=ba = b||c
,如果b为真,则a=b,若b为假,则a=ctrue && !(false) && (false,a=0),alert(a)
,请留意逗号的作用
JavaScript不能使用
a<=x<=b
这样的形式,只能写成a<=x && x<=b
比较运算符:
大于小于号都与python的基本一致,唯一不同的是相等运算号。
JavaScript的相等运算号有两个
==
:会自动转化数据类型再比较,有时候会得到非常诡异的结果===
:不会自动转化数据类型,如果数据类型不同,直接返回false
不要使用
==
比较,始终坚持使用===
比较,还有的就是**NaN
值不等同于任何值,包括自己本身**,唯一能判断NaN的方法是通过isNaN()
函数,如:var a=NaN; isNaN(a);//true
当然还有浮点数的比较了,这是计算机的问题,之前的600x笔记已经写得很清楚
2.4 数组(array)
JavaScript的数组array(也就是python的list)。
以下直接讲数组的操作:
"use strict"
var a=[0,1,2];//还可以使用a=new Array(0,1,2),不过只推荐前者
a.length;
//可以查询长度(注意没括号),另外当你对a.length定义一个数值的时候,是会导致Array的长度的,比如说设置a.length=2,这时数组a的值就是[0,1],假如设置大于3的时候,超出的数值都为undefined。
a[0]=5;
//可以使用索引修改数组的数值,同样的假如设置的索引超出了数组长度,数组长度也是会变长,而除了设置的值外,没有定义的数值都为undefined,因此访问和修改的时候,都得注意数组的长度。
a.indexOf();//查询索引
a.slice(0,3);
//对应字串符的substring,使用它还可以复制数组了,注意数组是可变变量,不能直接通过赋值复制的
a.push(4);//从尾部添加数值,如同python的append()
a.pop();//从尾部删除数值,如同python的pop()
a.unshift(-1);//从头部添加数值
a.shift();//从头部删除数值
a.sort();//对数组进行排序,接受两个参数,第一个为数组,第二个为比较函数(比较函数要第一值位于第二值之后应返回1,否则返回-1)
a.reverse();//把顺序掉过来摆放
//splice(拼接),修改数组的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素
a.splice(0,1,4);//从索引0开始删除1个元素,并在索引0地方处加上元素4
a.splice(0,0,6,5);//从索引0开始不删除元素,并在索引0地方处依次加上元素6,5
var b=[4,5,6]
a.concat(b);
//用于数组相加,而且加法顺序是a+b,注这里直接用加号运算,会生成一个类似字串符的东西,如:`0,1,24,5,6`
a.join("-");//如同python的str.join(sequence),只是参数位置不同
2.5 对象(object)
JavaScript的对象是一组由键-值组成的无序集合(就类似python的dict),其实键的值就是个属性值,所以可以调用属性的形式取得键值。
var a={
name:"seiei",
score:100,
"hight-school":"school"
};
//JavaScript的对象key值都是字串符,也就可以没加引号表明了,但使用横杠号时就必须加上引号表明了。
//键-值之间的链接像python一样使用分号,键与键之间用逗号隔开,最后一个键-值不要使用逗号,不然会报错!!!
a.name;//seiei
a["name"];//seiei
a.sex;//当访问一个不存在的值会返回undefined
a.name="abc";//赋值
delete a.name;
//删除,删除一个不存在的数值也不会报错。而python的dict删除还是用pop(),如a.pop("name")
"name" in a;
//true,判断对象是否存在属性name,跟python一致
a.hasOwnProperty("name");
//之前都说了键值是类的属性,为了防止继承类的属性干扰,可以使用hasOwnProperty()来判断
2.5.1 Map和Set
严格意义上JavaScript的对象(object)并不是对应python中的dict,因为它的键只能为字符串,为了解决这个问题,最新的ES6规范引入了新的数据类型Map。
//初始化Map需要一个二维数组,或者直接初始化一个空的Map
var a=new Map([["name","seiei"],["score",100]]);//二维数组创建Map
var a=new Map();//初始化一个空的Map
a.has("name");//有没有这个键
a.get("name");//读取键值
a.set("sex","man");//创建新的键-值
m.delete("sex");//删除键-值
而set就等同与python中的set了,至于操作与Map大同小异:
var s1 = new Set();
var s2 = new Set([1, 2, 3]);
s2.add(4);//添加数值
2.6 变量
申明变量的方法有几种:
var
:使用var
申明的变量不是全局变量,它的范围被限制在该变量被申明的函数体内,同名变量在不同的函数体内互不冲突。let
:用于申明块部变量,如for循环语句const
:用于申明常量,申明过后的常量不能修改(进行修改虽然不会报错,都不会赋值)
变量在JavaScript中就是用一个变量名表示,变量名是大小写英文、数字、$
和_
的组合,且不能用数字开头。
JavaScript变量一般都使用var
声明。
同一个变量可以反复赋值,不同数据类型也可以,但是要注意只能用var
申明一次。
变量本身类型不固定 的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。
##2.7 null和undefined
null
表示一个“空”的值,等同于python的None
,它和0
以及空字符串''
不同,0是一个数值,’'表示长度为0
的字符串,而null
表示“空”。
undefined
表示值未定义,区分两者的意义不大。大多数情况下,我们都应该用null
。undefined
仅仅在判断函数参数是否传递的情况下有用。
##2.8 数据类型的转换
使用
typeof()
函数可以求出当前对象的数据类型。
2.8.1 string转number
JavaScript比较奇怪,string与number之间居然可以进行加减乘除的操作,得出的结果是除了加号,其它符号的运算都会转换成正常的number运算,而加号的时候就是字节符的相加,如:
"123"*1;//等于123,number类型
"123"+10;//等于"12310",字串符类型
当然除了这方法还有比较正常的使用函数转换:
parseInt()
函数:接受两个参数,第一个是要转换的字串符,第二个是数字基数(就是进制数,输出结果会由该进制数转换成十进制数)。另外当string以“0”开头的话解析出的结果也不同,详情Number()
函数:只接受一个参数,常用这个,转换规则如下:- 如果是布尔值,
true
返回1
,false
返回0
,所以isNaN(true)-->false
- 如果是
null
,返回0
- 如果是
undefined
,返回NaN
- 如果是字串符,头个字符为零时零会被忽略(除十六进制);字串符为空返回
0
,如果包含其他以上格式外的字符,返回NaN
,所以isNaN("blue")-->true
2.8.2 toString()方法
几乎所有的实例对象都可以使用toString()
方法,注意是方法而不是函数,其作用就是转换字串符,语法是:object.toString()
null
与undefined
没有这个方法
3 条件判断
JavaScript使用if () { ... } else { ... }
来进行条件判断。
与python不同,python以语句的缩进作为语句块,而JavaScript以花括号作为语句块。
4 循环
4.1 for循环
JavaScript使用for (a;b;c) { d }
来进行for循环。
- a部分:初始条件
- b部分:判断条件
- c部分:实现逐步逼近判断条件的做法
- d部分:循环操作
- 以上各部分都可以不填写,可以使用break语句
注意:在for里头初始定义变量都要使用
var
4.1.2 for … in 循环
for循环的一个变体是for (a in b) {c}
循环,它可以把一个对象的所有属性依次循环出来:
注意,for … in对Array的循环得到的是String而不是Number。而且得到的数值还是索引
4.1.3 for … of 循环 与iterable
内置的forEach
方法
为了统一集合类型,ES6标准引入了新的
iterable
类型,Array、Map和Set都属于iterable
类型。
for … in循环由于历史遗留问题,它遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。即假如当我们手动给Array对象添加了额外的属性后,使用for…in还是会把新添加的属性输出。
而for … of循环则完全修复了这些问题,它只循环集合本身的元素。
然而,更好的方式是直接使用iterable
内置的forEach
方法,它接收一个函数,每次迭代就自动回调该函数(python生成器?):
var a=[0,1,2,3];
a.forEach(function (element,index,array) {
// element: 指向当前元素的值
// index: 指向当前索引
// array: 指向Array对象本身
// 以上参数名字可以变换,只是位置已经是定死了的,比方说这第一个参数就是元素值,第二个参数就是索引,第三个参数就是iterable类型本身,只是名字不同而已
console.log(element)//可以只挑一个参数输出
});
//注意forEach包含函数的括号
4.2 while 循环
JavaScript使用while (a) { b,c }
来进行while循环。
- a:判断条件
- b:循环操作
- c:实现逐步逼近判断条件的做法
- 以上各部分都可以不填写,可以使用break语句
4.2.1 do …while 循环
JavaScript使用 do {b,c} while(a)
来进行while循环。与while循环差不多只是唯一区别在于,不是在每次循环开始的时候判断条件,而是在每次循环完成的时候判断条件,也就是说,do …while 循环体会至少执行1次。
4.3 label语句
使用label语句可以在代码中添加标签,以便将来调用。以下是label语句的语法:
label:statment
其常用来联合循环的break
和continue
语句使用,这种使用多发生在循环嵌套的情况下:
var num=0;
outer:for (var i=0;i<10;i++) {
for (var j=0;j<10;j++) {
if (j==5) {
break outer;//返回最外的循环
}
}
}