Day 51 JS基础语法
一、数组对象Array
数组对象的作用是:使用单独的变量名来存储一系列的值。类似于python中的列表。
var arr = [1, 22, 34, 23, 42, 34, 234, 2, 42, 34, 234, 234, 234, 23]
console.log(arr); //输出数组arr
1、取值
数组只能正取,不能反取,超出索引不报错。
var arr=[1, 2,3,4,"asda","sdasd"]
arr[9] //undefined
arr[-1] //undefined
常用方法
方法 | 说明 |
---|---|
Array.length | 数组的大小(元素个数) |
Array.push(element) | 尾部追加元素 |
Array.pop() | 获取尾部的元素 |
Array.unshift(element) | 头部插入元素 |
Array.shift() | 头部移除元素 |
Array.slice(start, end) | 切片 |
Array.reverse() | 反转 |
Array.join(seq) | 将数组连接成字符串 |
Array.concat(val,....) | 链接数组 |
Array.sort() | 排序 |
Array.forEach() | 将数组的每个元素传递给回调函数 |
Array.splice() | 删除元素,并向数组添加新元素 |
Array.map() | 返回一个数组元素调用函数处理后的值的新数组 |
2、头部插入元素-unshift
var arr=[1, 2,3,4,"asda","sdasd"]
arr.unshift(99) // 头部添加元素
arr
-----------------------
[99, 1, 2, 3, 4, "asda", "sdasd"]
3、切片-slice
arr.slice(0, 4) //从0索引开始到4号索引结束,顾头不顾尾
-----------------
[99, 1, 2, 3]
4、将数组连接成字符串-join
arr.join()
------------------------
"99,1,2,3,4,asda,sdasd"
5、数组连接-concat
相当于python字典的extend
var arr2=["a", "b", "c", "d"]
arr.concat(arr2)
----------------------------------
[99, 1, 2, 3, 4, "asda", "sdasd", "a", "b", "c", "d"]
6、排序-sort
如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。
var arr=[123,9,23,444,56]
arr.sort()
-----------------------------
[123, 23, 444, 56, 9] //这个结果并不是我们想要的
如果想按照其他标准进行排序,就需要提供比较函数,该函数应该具有两个参数 a 和 b,接收传入的a和b,执行函数体代码,然后返回一个值用于说明a和b的大小 利用JS中-
自动转换成数字类型的特点
function sort_y(a, b){
return a-b}
arr.sort(sort_y)
---------------------------
[9, 23, 56, 123, 444] //这是我们想要的结果
7、将数组的每个元素传递给回调函数-forEach()
语法:forEach(function(currentValue, index, arr), thisValue)
参数 | 描述 |
---|---|
currentValue | 必须:当前元素 |
index | 可选:当前元素的索引值 |
arr | 可选:当前元素所属的数组对象 |
thisValue | 可选:传递给函数的值一般用"this"值 如果这个参数为空,“undefined”会传递给“this”值 |
var res = arr.forEach(function(v, i , arr){
console.log(v,i,arr);
console.log(this[0]);
return 123},["first", "secend"])
=-------------------------------------------
9 0 (5) [9, 23, 56, 123, 444]
first
23 1 (5) [9, 23, 56, 123, 444]
first
56 2 (5) [9, 23, 56, 123, 444]
first
123 3 (5) [9, 23, 56, 123, 444]
first
444 4 (5) [9, 23, 56, 123, 444]
first
var res2 = arr.forEach(function (v) {
console.log(v);}
-----------------------------------------------
9
23
56
123
444
8、返回组元素调用函数处理后的值的新数组-map
map()返回一个新数组,原数组不会改变
var arr=["毛成", "卢本伟", "PDD","旭旭宝宝"]
var res=arr.map(function(v,i,arr){
v=v+"_DSB"; // 在每个元素后加上_DSB
console.log(v, i)})
------------------------------------------------
毛成_DSB 0
卢本伟_DSB 1
PDD_DSB 2
旭旭宝宝_DSB 3
注意:在使用forEach()
时候,如果数组在迭代的值被修改,则其他元素会被跳过
var arr=[11,22,33,44,55]
arr.forEach(function(v){
console.log(v);
if (v === 33){
arr.shift() // 下一次循环应该循环出第索引为3的元素,但此时一旦删除第一个元素,那么值55的索引变成了3 也就是说下一个索引应该是3,但是44不再是3所以他被跳过
}
})
-----------------------------------------------
11
22
33
55
二、Date日期对象
创建日期对象只有构造函数一种方式,使用new关键字
1、不指定参数
var d1=new Date
d1
console.log(d1.toLocaleString()) //tolocalestring方法后要加括号() 转换成东八区
-----------------------------
Tue Sep 22 2020 16:09:12 GMT+0800 (China Standard Time) {}
22/09/2020, 16:09:12
2、参数为日期字符串
var d2 = new Date("1949-10-01 10:01:00")
d2
console.log(d2.toLocoleString())
---------------------------
Sat Oct 01 1949 10:01:00 GMT+0800 (China Standard Time)
01/10/1949, 10:01:00
var d3 = new Date("01/27/18 11:12:13"); // 月/日/年 时分秒
console.log(d3.toLocaleString());
------------------------------------
27/01/2018, 11:12:13
3、参数为毫秒数
var d4 = new Date(2923429342)
console.log(d4.toLocaleString())
------------------------------------
04/02/1970, 04:03:49
4、参数为:年,月,日,时,分,秒,毫秒
var d5 = new Date(2018,1,27,11,11,11,11,700)
console.log(d5.toLocaleString())
--------------------------------------
27/02/2018, 11:11:11
5、常用方法
方法 | 含义 |
---|---|
getDate() | 根据本地时间返回指定日期对象的月份中的第几天(1-31)。 |
getMonth() | 根据本地时间返回指定日期对象的月份(0-11) |
getFullYear() | 根据本地时间返回指定日期对象的年份(四位数年份时返回四位数字) |
getDay() | 根据本地时间返回指定日期对象的星期中的第几天(0-6) |
getHours() | 根据本地时间返回指定日期对象的小时(0-23) |
getMinutes() | 根据本地时间返回指定日期对象的分钟(0-59) |
getSeconds() | 根据本地时间返回指定日期对象的秒数(0-59) |
getMilliseconds() | 根据本地时间返回指定日期对象的获取毫秒 |
getTime() | 返回累计毫秒数(从1970/1/1午夜) |
三、Math对象
方法 | 含义 |
---|---|
Math.floor() | 向下取整,如5.1取整为5 |
Math.ceil() | 向上取整,如5.1取整为6 |
Math.max(a,b) | 求a和b中的最大值 |
Math.min(a,b) | 求a和b中的最小值 |
Math.random() | 随机数,默认0-1之间的随机数,若想求min~max之间的数,公式为:min+Math.random()*(max-min) |
那么我们如何获取一定区域间的随机值呢?其实也比较简单
获取4-9之间的随机值
res=4 + Math.random()*(9-4)
------------------------------
4.216542948169268
6.904331570280943
7.185153744869904
...........
四、JSON对象
1、JSON格式的字符串转成对象
var dic1='{"name":"马超", "age":19, "gender":"male"}'
typeof dic1
res = JSON.parse(dic1)
typeof res
-------------------------------
"string"
{name: "马超", age: 19, gender: "male"}
"object"
2、对象转成JSON字符串
var res2=JSON.stringify(res)
res2
------------------------------
"{"name":"马超","age":19,"gender":"male"}"
五、RegExp对象
1、创建正则对象的方式
参数一:正则表达式
参数二:匹配模式,常用g(全局匹配;找到所有匹配,而不是在第一个匹配后停止)和i(忽略大小写)
注意:正则放到引号内,{ }内的逗号后面不要加空格
var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9]{5,11}$") //以字母开头 数字或字母结尾出现5-11次
var reg2 = new RegExp("^我.*爸$")
reg1.text("a223423423")
reg2.test("我是你爸爸爸的爸爸")
------------------------
true
true
2、创建正则对象的方式2
var reg2 = /^[a-zA-Z][a-zA-Z0-9_]{5,11}$/; // 不要加引号
reg2.test("egon_123")
-------------------------
true
3、String对象与正则结合的四个方法
var s1="hello world";
s1.match(/l/g) // 符合正则的内容["l", "l", "l"]
s1.search(/h/g) // 符合正则的内容的索引0
s1.split(/ /) // ["hello", "world"]
s1.replace(/l/g,'L') // "heLLo worLd"
4、匹配模式g与i
var s2="name:Egon age:18"
s2.replace(/e/,"赢") // "nam赢:Egon age:18"
s2.replace(/e/g,"赢") // "nam赢:Egon ag赢:18"
s2.replace(/e/gi,"赢") //"nam赢:赢gon ag赢:18"
5、注意
- 如果regExpObject带有全局标志g,test()函数不是从字符串的开头开始查找,而是从属性regExpObject.lastIndex所指定的索引处开始查找。
- 该属性值默认为0,所以第一次仍然是从字符串的开头查找
- 当找到一个匹配时,test()函数会将regExpObject.lastIndex的值改为字符串中本次匹配内容的最后一个字符的下一个索引位置。
- 当再次执行test()函数时,将会从该索引位置处开始查找,从而找到下一个匹配。
- 因此,当我们使用test()函数执行了一次匹配之后,如果想要重新使用test()函数从头开始查找,则需要手动将regExpObject.lastIndex的值重置为 0。
- 如果test()函数再也找不到可以匹配的文本时,该函数会自动把regExpObject.lastIndex属性重置为 0。
var reg=/秋天/g //正则表达式
reg.lastIndex //0 此时指针在首位
reg.test("秋天,这北国的秋天。") // true 匹配成功
reg.lastIndex // 2 此时指针移动到了2这个位置
reg.test("秋天,这北国的秋天。") // true 匹配成功
reg.lastIndex // 9 此时指针移动到了9这个位置
reg.test("秋天,这北国的秋天。") // false 匹配失败 因为后面9后面已经没有“秋天”了
reg.lastIndex // 0 指针重新回到首位
6、注意2
当我们不加参数调用RegExpObj.test()方法时, 相当于执行RegExpObj.test(“undefined”), 并且/undefined/.test()默认返回true。
var reg4 = /^undefined$/;
reg4.test(); // 返回true
reg4.test(undefined); // 返回true
reg4.test("undefined"); // 返回true
六、运算符
算数运算符
+
-
*
/
%
++
--
比较运算符
> >=
< <=
!=
==
===
!==
注意
1 == “1” // true 非严谨模式
1 === "1" // false 严谨模式
逻辑运算
&&
||
!
且 或 非
赋值运算
=
+=
-=
*=
/=
七、流程控制
if-else if-else
var x = 12
if (x < 12) {
console.log("我是你爸爸!")
} else if (x > 12) {
console.log("我不是你爸爸")
} else {
console.log("儿子")
}
------------------------------
儿子
switch
switch (x) {
case x > 12:
console.log("你太大了")
break;
case x < 12:
console.log("你太小了")
break;
default:
console.log("儿子!")
for
var arr = [1, 22, 34, 23, 42, 34, 234, 2, 42, 34, 234, 234, 234, 23]
console.log(arr)
for (var i = 0; i < arr.length; i++) {
console.log(arr[i])
}
------------------------------------
[1, 22, 34, 23, 42, 34, 234, 2, 42, 34, 234, 234, 234, 23]
1
22
34
23
42
34
234
2
42
34
234
23
for (let i=1;i<4;i++){
console.log(i);}
-------------------------
1
2
3
三元(条件)运算
语法结构为:条件 ? 操作1 : 操作2。 如果条件为真,执行操作1,否则执行操作2。
var x=1;
var y=2;
var z=x>y?x:y // (条件) ? 表达式1 : 表达式2
八、函数
1、函数定义与调用
1.1、无参函数
function fun1(){
console.log("冰与火之歌")}
fun1()
------------------------------
冰与火之歌
1.2、有参函数
function fun2(a, b){
console.log(a**b)
}
fun2(2,10)
------------------------------
1024
1.3、带返回值的函数
function fun3(a, b){
return a**b
}
res = fun3(2,5)
fun3(2,5) // 调用函数
----------------------------
32
1.4、匿名函数
var sum = function(a, b){
return a + b;
}
sum(1, 2);
------------------
3
1.5、立即执行函数
(function(a,b){
return a*b**a})(2, 4)
-------------------------
32
2、函数中arguments参数
arguments代表是函数中的参数是一个数组Array
(function(a, b){
console.log(a**b);
console.log(arguments[0])})(2,10)
--------------------------------
1024
2
注意:函数只能返回一个值,如果要返回多个值,只能将其放在数组或对象中返回。
3、函数的全局变量和局部变量
局部变量
在JavaScrip中函数内部声明变量(使用var)是布局变量,所以只能在函数内部访问它(该变量的作用域是函数内部)。只要函数运行完毕,局部变量就会被删除
全局变量
在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。
变量生存周期
JavaScript变量的生命期从它们被声明的时间开始。
局部变量会在函数运行以后删除
全局变量会在页面关闭后被删除
4、作用域
首先在函数内部查找变量,找不到则到外层函数查找,逐步找到最外层。另外函数的作用域关系是在定义阶段就固定死的,与调用位置无关
栗子1
var name="马超"
function fun1(){
console.log(name)
}
fun1()
---------------------------
马超
栗子2
var name="马超"
function fun2(){
var name="锦马超";
console.log(name)
}
fun2()
--------------------------
锦马超
栗子3
var city = "BeiJing";
function f() {
var city = "ShangHai";
function inner(){
var city = "ShenZhen";
console.log(city);
}
inner();
}
---------------------
ShenZhen
5、JavaScript中的变量提升和函数提升
1、在js中只有两种作用域
- 全局作用域
- 函数作用域
在ES6之前,js是没有块级作用域。
首先来解释一下什么是没有块级作用域?
var i=1
if(true){
var a = "锦马超"; //变量a是声明在if的{}里,但是在js里面,因为没有块级作用域,所以此时的变量a的作用域是全局作用域
}
console.log(a)
2、什么是变量提升?
在我们的js中,代码的执行时分两步走的,1、解析 2、一步一步执行
那么变量提升就是变量声明会被提升到作用域的最顶上去,也就是该变量不管是在作用域的哪个地方声明的,都会提升到作作用域的最顶上去。
//变量提升
console.log(a);
var a = "龙胆";
console.log(a); //龙胆
其实这种写法等价于
var a;
console.log(a);
a = "龙胆"
console.log(a);
举个栗子
var a=10
function fun(){
console.log(a); //undefined
var a=20;
console.log(a); //20
}
fun() //20
console.log(a) // 10
把上面的例子稍作改动:结果就会大不一样,
var a=10
function fun(){
console.log(a); // 10 全局变量
a=20 //没有var 给全局变量重新赋值为20
console.log(a) // 20
}
fun() //10 20
console.log(a) // 20
在一个栗子
var a=1
if(true){
console.log(a); //10
var a =20;
console.log(a) //20
}
cosole.log(a) //20
由于在js中没有块级作用域,所以此处是在全局作用域重复声明的两次,那么第二次声明会被忽略,仅用于赋值
3、什么是函数提升
fn(); //此处也可以正常调用 啦啦啦
console.log(fn);
function fn(){
console.log("啦啦啦")
}
fn(); //此处可正常调用 啦啦啦
注意:函数声明式,会将函数的声明和定义一起提升到作用域的最顶上去。
如果是这种写法:函数表达式声明的函数
输出结果
ƒ fn(){
console.log('生命不息 奋斗不止');
}
ƒ fn(){
console.log('生命不息 奋斗不止');
}
最后一个例子
输出结果
ƒ fn(){
console.log('生命不息 奋斗不止');
}
hello
最后总结
#1:所有的声明都会提升到作用域的最顶上去。
#2:同一个变量只会声明一次,其他的会被忽略掉。
#3:函数声明的优先级高于变量申明的优先级,并且函数声明和函数定义的部分一起被提升。