JS基础知识(三)

数组

数组简介

数组也是一个对象,和普通的对象功能类似,也是用来存储一些值的,不同的是普通对象是使用字符串作为属性值的,而数组是使用数字来作为索引操作元素的

创建数组对象

获取数组的长度:
对于连续的数组,使用length属性来获取数组的长度(元素的个数)
对于非连续的数组,使用length属性会获取到数组的最大索引加1

修改数组的长度:
如果修改的length大于原长度,则多出部分会空出来
如果修改的length小于原长度,则多出的元素会被删除

//创建数组对象
var arr = new Array();
//使用typeof检查一个数组时,会返回object
//console.log(typeof arr)   object
//向数组中添加元素
arr[0] = 10;
arr[1] = 11;
arr[2] = 12;
//读取数组中的元素
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[2]);
//获取数组的长度
console.log(arr.length);
//修改数组的长度
arr.length = 10;
//向数组的最后一个位置添加元素
arr[arr.length] = 15;

数组字面量

使用字面量来创建数组

//使用字面量来创建数组
var arr = [];
//使用字面量来创建数组时,可以在创建时就指定数组中的元素
var arr = [1,2,3,4,5];
//使用构造函数来创建数组时,也可以同时添加元素,将要添加的元素作为构造函数的参数进行传递
var arr = new Array(1,2,3,4,5);
//字面量
var arr1 = [10]; //创建一个数字,数组中只有一个元素
var arr2 = new Array(10);//创建长度为10的数组
console.log(arr1);// 10
console.log(arr2);//,,,,,,,,,  长度为10
//数组中的元素可以是任意的数据类型,也可以是对象,也可以是函数,也可以放数组
var arr3 = ["hello",1,true,null,undefined,{
    
    name:'猪八戒'},function(){
    
    alert(2)},[1,2,3]]
var obj = {
    
    name:'孙悟空'};
arr3.[arr.length] = obj;

创建一个数字,数组中只有一个元素var arr1 = [10];
创建长度为10的数组var arr2 = new Array(10);

数组的四个方法

  1. push():
    向数组的末尾中添加一个或者多个元素,并返回数组的新的长度
    可以将要添加的元素作为方法的参数传递,这样这些元素将会自动添加到数组的长度
    该方法会将数组新的长度作为返回值返回。
var arr = ['孙悟空','猪八戒','沙和尚']
var result = arr.push('唐僧','蜘蛛精','白骨精');
console.log(arr)//孙悟空,猪八戒,沙和尚,唐僧,蜘蛛精,白骨精
console.log(result);//6
  1. pop():
    该方法可以删除数组中的最后一个元素,调用一次删除一次
    该方法会将被删除的元素作为返回值返回
var arr = ['孙悟空','猪八戒','沙和尚']
var result = arr.push('唐僧','蜘蛛精','白骨精');
result = arr.pop();
console.log(arr)//孙悟空,猪八戒,沙和尚,唐僧,蜘蛛精
console.log(result);//白骨精
  1. unshift():
    向数组开头添加一个或多个元素,并返回新的数组长度;
    像前面插入元素以后,其他元素的索引回依次调整
var arr = ['孙悟空','猪八戒','沙和尚']
var result = arr.push('唐僧','蜘蛛精','白骨精');
result = arr.unshift('牛魔王');
console.log(arr)//牛魔王,孙悟空,猪八戒,沙和尚,唐僧,蜘蛛精
console.log(result);//7
  1. shift()
    可以删除数组的第一个元素并将被删除的元素作为返回值返回

数组的遍历(forEach)

遍历数据就是将数组中的所有的元素都取出来

 for(var i=0;i<arr.length;i++){
    
    
   cosole.log(arr[i])
 }

也可以调用forEach()方法去遍历(这个方法只支持IE8以上的浏览器)

forEach()方法需要一个函数作为参数,一般不传普通函数进去,因为传普通函数,就还是相等于在全局作用域中定义了一个函数,因此一般传进去的是匿名函数

var arr = ['孙悟空','猪八戒','沙和尚']
arr.forEach(function(){
    
    
	console.log('hello')
})

此时,直接打印出了3次hello

  • 像这种函数,由我们创建但是不由我们调用的,我们称为回调函数。可以简单理解,这种函数由浏览器去调用,我们只是给浏览器传过去
  • 数组中有几个元素,函数就执行几次。每次执行时,浏览器就会将遍历到的元素以实参的形式传递进来。
var arr = ['孙悟空','猪八戒','沙和尚']
arr.forEach(function(a,b,c){
    
    
	console.log('a='+a)
	console.log('b='+b)
	console.log('c='+c)

})

输出:
a = ‘孙悟空’;
a = ‘猪八戒’;
a = ‘沙和尚’ ;
b = 0;
b = 1;
b =2;
c=孙悟空,猪八戒,沙和尚;
c=孙悟空,猪八戒,沙和尚
c=孙悟空,猪八戒,沙和尚

  • 浏览器会在回调函数中传递三个参数:
  • 第一个参数,就是当前正在遍历的参数(value)
  • 第二个参数,就是当前正在遍历的元素的索引 (index)
  • 第三个参数,就是正在遍历的数组(obj)

splice和slice

slice:

  • slice()方法可以从已有的数组中返回选定的元素
  • 语法:arrayObject.slice(start,end)
  • 参数:start:必需,规定从何处开始选取,截取开始的位置索引,包含开始索引。end:截取结束的位置的索引,不包含结束索引。可以省略不写,此时会截取从开始索引往后的所有元素。end也可以传递一个负值,如果传递一个负值,则从后往前计算。
  • 该方法不会改变原数组,而是将截取到的元素封装到一个新数字中返回

splice:

  • 可以用于删除,插入,替换数组中的指定元素
  • 使用splice()会影响到原数组,会将指定元素从原数组中删除,并将被删除的元素作为返回值返回
  • 参数:第一个:表示开始位置的索引;第二个:表示删除的数量;第三个及以后:可以传递一些新的元素,这些元素将会自动插入到开始位置索引前边。

数组的剩余方法

concat:

  • concat()可以连接两个或者多个数组,并将新的数字返回
  • 该方法不会对原数组产生影响
  • 不仅可以传数组,也可以传元素var result = arr.concat(arr1,arr2,"牛魔王","铁扇公主");

join:

  • 该方法可以将数组转换为一个字符串
  • 不会对原数组产生影响,而是将转换后的字符串作为结果返回
  • 在join()中可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符arr = ["孙悟空","猪八戒","沙和尚"]; result = arr.join('hello');输出'孙悟空hello猪八戒hello沙和尚'
  • 如果不指定连接符,则默认使用逗号作为连接符。如果不想要连接符,则使用一个空串。arr.join('')

reverse:

  • 该方法用来反转数组
  • 会直接修改原数组

sort:

  • 可以用来对数组中的元素进行排序
  • 也会影响原数组
  • 默认会按照Unicode编码进行排序,即使对应纯数字的数字,使用sort()排序时,也会按照Unicode编码来排序,因此,对于对数字进行排序时,可能会得到错误的信息。
  • 我们可以自己指定排序的规则,可以在sort()添加一个回调函数,来指定排序规则。回调函数中需要定义两个形参,浏览器将会分别使用数组中的元素作为实参去调用回调函数;使用哪个元素调用不确定,但是肯定的是在数组中a一定在b前面
  • 如果返回一个大于0的值,则元素会交换位置;如果返回一个小于0的值,则元素位置不变;如果返回一个等于0的值,则元素相等,位置不变
arr = [5,4,2,1,3,6,8,7]
arr.sort(function(a,b){
    
    
//前面的大
	if(a > b){
    
    
		return 1;
	}else if(a < b){
    
    
		return -1;
	}else{
    
    
		return 0;
	}
})

等同于

arr = [5,4,2,1,3,6,8,7]
arr.sort(function(a,b){
    
    
	//升序排列
	return a - b;
})

结论:升序:a-b;降序:b-a

函数(补充)

call()和apply()

  • 这两个方法都是函数对象的方法,需要通过函数对象来调用
  • 当函数调用call()和apply()都会调用函数执行
function fun(){
    
    
	alert("我是fun函数!");
}
fun.aaply();
fun.call();
  • 在调用call和apply()可以将一个对象指定为第一个参数。此时这个对象将会成为函数执行的this
  • call()方法可以将实参在对象之后依次传递fun.call(obj,2,3);而apply()方法需要将实参封装到一个数组中统一传递fun.apply(obj,[2,3])

this总结:

  • 以函数形式调用时,this是window;
  • 以方法的形式调用时,this是调用方法的对象
  • 以构造函数的形式调用时,this是新创建的对象
  • 使用call和apply调用时,this指定的那个对象

arguments

在调用函数时,浏览器每次都会传递两个隐含的参数

  1. 函数的上下文对象this
  2. 封装实参的对象arguments

arguments:

  • arguments是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度
  • 在调用函数时,我们所传递的实参都会封装到arguments中
  • arguments.length可以用来获取实参的长度
  • 即使不定义形参也可以通过arguments来使用实参。arguments[0]表示第一个实参
  • arguments有一个callee属性,这个属性对象一个函数对象,就是当前正在指向的函数的对象。
function fun(){
    
    
	console.log(arguments);
	console.log(arguments instanceof Array);//false
	console.log(Array.isArray(arguments));//false
	console.log(arguments[1]);//2	
	console.log(arguments.callee);//打印出fun函数
}
fun(1,2);

内嵌对象:Date对象

  • 在JS中使用Data对象来表示时间
  • 如果直接使用构造函数创建一个对象,则会封装当前代码的时间。下面例子中:就是let d = new Date()执行的时间
let d = new Date();
console.log(d);//打印出当前时间
  • 创建一个指定的时间对象:需要在构造函数中传递一个表示时间的字符串作为参数let d2 = new Data('12/03/2016 11:10:30')
  • 日期格式:月份/日/年时:分:秒

方法:

  • getDate():获取当前日期对象是几日(1-31),一个月中的某一天
  • getDay():从Date对象返回一周中的某一天(0-6),0表示周日
  • getMonth():获取当前时间对象的月份(0-11)从0开始,0表示一月,如果想要正常转化,需要加一
  • getFullYear():获取当前事件对象的四位数字的年份
  • getTime():获取当前对象的时间戳。时间戳是指格林威治标准时间1970年1月1日0时0分0秒到当前时间所花的毫秒数(1秒等于1000毫秒)。计算机为了统一时间单位,因此计算机底层在保存时间时使用的都是时间戳。
  • 获取当前的时间戳:time = Date.now()

应用:
利用时间戳来测试代码的执行的性能

//获取当前的时间戳
let start = Date.now();
for(let i=0;i<100;i++){
    
    
	console.log(i);
}
let end = Date.now();
console.log("执行了"+(end - start)+'毫秒');

Math

  • math和其他对象不同,他不是一个构造函数,属于一个工具类不用创建对象,他里面封装了数学运算相关的属性和方法
  • Math.PI表示圆周率
  • Math.abs()可以用来计算一个数的绝对值console.log(Math.abs(-1)) //1
  • Math.ceil()可以对一个数进行向上取整,小数位只要有值就自动进一console.log(Math.ceil(1.001)) //2
  • Math.floor()可以对一个数进行向下取整,小数位会被舍掉console.log(Math.floor(1.99)) //1
  • Math.round()可以对一个数进行四舍五入取整console.log(Math.round(1.4)) //1
  • Math.random()可以用来生成一个0-1之间的随机数,不会出现0和1;如果想生成一个0-10的随机数console.log(Math.random()*10),如果想要生成一个整数console.log(Math.round(Math.random()*10))
  • 生成一个x-y之间的随机数Math.round(Math.random()*(y-x)+x)
  • Math.max()可以获取多个数中的最大值。Math.max(10,34,56,44);
  • Math.min()可以获取多个数中的最小值。Math.min(10,34,56,44);
  • Math.pow(x,y)返回x的y次幂。Math.pow(12,3);
  • Math.sqrt(x)对x进行开方运算

包装类

在JS中为我们提供了三个包装类,通过这三个包装类可以将基本数据类型的数据转化为对象
String():可以将基本数类型字符串转换为String对象
number():可以将基本数据类型的数字转化为Number对象
Boolean():可以将基本数据类型转化为Boolean对象

创建一个Number类型的对象

let num = new Number(3);
console.log(num)//3
console.log(typeof num)//object对象类型

既然是对象,就可以向其添加属性

num.hello = 'weewrqr';
console.log(num.hello);//weewrqr

当使用包装类创建两个对象,这两个对象并不相等

let num1 = new Number(3);
let num2 = new Number(3);
console.log(num1 == num2);//false

原因:两个对象相比较,比较的是内存地址
注意:在实际应用中不会使用基本数据类型的对象,如果使用基本数据类型的对象,在做一些比较时可能会带来不可预期的结果

let b = new Boolean(false);
if(b){
    
    
	alert('我运行了')
}

结果:依然会弹出’我运行了’弹出框。因为b是一个对象,定义了就有值

包装类的使用情况:

一般来说方法和属性只能添加给对象,不能添加给基本数据类型,但是以下情况却不会报错

let s = 123;
s = s.toString();
console.log(s);//123
console.log(typeof s);//string

上述例子中,基本数据类型不仅调用了toString()方法,并且成功将number类型转化为string类型,这是因为当我们对一些基本数据类型的值去调用属性和方法时,浏览器会临时使用包装类将其转化为对象,然后再调用对象的属性和方法,调用完以后在将其转化为基本数据类型

let s = 123;
s = s.toString();
s.hello = '你好';
console.log(s.hello);//undefined

上述例子中打印出来undefined;浏览器临时使用包装类转化的对象是临时对象,在给s添加hello属性时,他将s临时转为一个对象,将属性添加到对象中去,属性添加完以后,对象就被销毁了。当打印s.hello时,会去读基本数据类型s中的hello属性,而基本类型不能保存属性,所以需要临时把s转换为字符串对象,然后去读hello属性,而转化前的s又没有该属性,因此为undefined。所以:每次调用,每次转化,转化完就销毁

字符串的方法

(主要是指String对象里的方法)
在底层字符串是以字符数组的形式保存的,比如:'hello’在底层的保存形式为[‘h’,‘e’,‘l’,‘l’,‘o’];因此:let str = 'hello'; console.log(str.length)//5;console.log(str[1];//e)

charAt()

  • 可以返回字符串中指定位置的字符
  • 根据索引获取指定的字符
let str = 'hello atguigu'
let result = str.charAt(6);
console.log(result);//A

charCodeAt()

  • 获取指定位置字符的字符编码(Unicode编码)
let str = 'hello atguigu'
let result = str.charCodeAt(6);
console.log(result);//97

fromCharCodeAt()

  • 可以根据字符编码去获取字符;
  • 使用的是字符对象去调用该方法
let result = String.fromCharCode(97);
console.log(result);//a

concat()

  • 可以用来连接两个或多个字符串
  • 作用和+一样
  • 对原字符串没有影响,输出str,依旧是hello atguigu
let str = 'hello atguigu'
let result = str.concat('你好','再见')
console.log(result);//hello atguigu你好再见

indexof()

  • 该方法可以检索一个字符串中是否含有指定内容
  • 如果字符串中含有该内容,则会返回其第一次出现的索引。
  • 如果没有找到指定的内容,则返回-1
  • 可以指定一个第二个参数,该参数指定开始查找的位置
let str = 'hello atguigu';
let result1 = str.indexOf('a');
console.log(result1);//6
let result2 = str.indexOf('a',1)//6

lastIndexOf()

  • 该方法的用法和indexOf一样,不同的是indexOf()是从前往后找,而lastIndexOf()是从后往前找
  • 也可以指定开始查找的位置
let str = 'hello atguigu';
let result1 = str.lastIndexOf('o');
console.log(result1);//4
let result2 = str.indexOf('a',4)//o

slice()

  • 可以从指定字符串中截取指定的内容
  • 不会影响到源字符串,而是将截取到的内容返回
  • 参数:第一个:开始位置的索引(包括开始位置);第二个:结束位置的索引(不包括结束位置)
  • 如果省略第二个参数,则会截取到后面所有的
  • 也可以传递一个负数作为参数,负数的话将会从后面计算,-1表示结束到倒数第一个,不包括倒数第一个,因此没有k
let str = 'abcdefghijk';
let result = str.slice(1,4)
console.log(result);//bcd
let result1 = str.slice(1)
console.log(result1);//bcdefghijk
let result2 = str.slice(1,-1);
console.log(result2);//bcdefghij

substring()

  • 可以用来截取一个字符串,和slice类似
  • 参数:第一个:开始截取位置的索引(包括开始位置)第二个:结束位置的索引(不包括结束位置)
  • 与splice不同的是这个方法不接受负值作为参数,如果传递了一个负值,则默认使用0
  • 会自动调整参数的位置,如果第二个参数小于第一个,则自动交换位置
  • str.substring(3,-1)==str.substring(3,0)==str.substring(0,3);所以是abc
let str = 'abcdefghijk';
let result1 = str.substring(0,2);
console.log(result1)//ab
let result2 = str.substring(3,-1);//abc
console.log(result2)

substr()

  • 用来截取字符串
  • 参数:第一个:截取开始位置的索引;第二个:截取的长度
let str = 'abcdefghijk';
let result1 = str.substr(3,2);
console.log(result1)//de

split()

  • 可以将一个字符串拆分为一个数组
  • 参数:需要一个字符串作为参数,将会根据该字符串去拆分数组
  • 如果传递一个空串作为参数,将会根据该字符串去拆分数组
let str = 'abc,def,ghi,jk';
let result = str.split(',');
console.log(result[0]);
let str1 = 'abcdefghijk';
let result1 = str1.split('');
console.log(result1);// ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']

toUpperCase()

  • 可以将一个字符串转化为大写并返回
  • 不会影响到原变量

toLowerCase()

  • 可以将一个字符串转化为小写并返回
  • 不会影响到原变量

正则表达式

正则表达式用于定义一些字符串的规则:

  • 计算机可以根据正则表达式,来检查一个字符串是否符合规则,获取将字符串中符合规则的内容提取出来

创建正则表达式的对象:

  • 语法:var 变量 = new RegExp(‘正则表达式’,‘匹配模式’);
  • 使用typeof检查正则对象,会返回object
  • 在构造函数中可以传递一个匹配模式作为第二个参数。可以是:i 忽略大小写 g 全局匹配模式

正则表达式的方法:

  • test();
  • 使用这个方法可以检查一个字符串是否符合正则表达式的规则
  • let reg = new RegExp(‘a’)用于检查一个字符串中是否含有小写的a
let reg = new RegExp('a','i');
let str = 'a';
let result = reg.test(str);
console.log(result);//true

使用字面量来创建正则表达式

  • 语法:let 变量 = /正则表达式/匹配模式
let reg = /a/i;
let str = 'a';
let result = reg.test(str);
console.log(result);//true

创建一个正则表达式,检查一个字符串中是否有a或b:使用|表示或者的意思

let reg = /a|b/;
console.log(reg.test('bcd'))//true

创建一个正则表达式,检查一个字符串中是否有字母:[]里的内容也是或的关系,[ab]==a|b。[a-z]任意小写字母;[A-Z]任意大写字母;[A-z]任意字母

let reg = /[a-z]/;
console.log(reg.test('bcd'))//true

创建一个正则表达式,检查一个字符串中是否含有abc或adc或aec

let reg = /a[bde]c/;
console.log(reg.test('aec'))//true

[^ ] 除了;[^ab] 除了ab;[^0-9] 除了数字

字符串和正则表达式

split()

  • 可以将一个字符串拆分为一个数组
  • 方法可以传递一个正则表达式作为参数,这样方法将会根据正则表达式去拆字符串
  • 这个方法及时不指定全局匹配,也会全部拆分

需求:根据任意字母来建字符串拆分

let str = '1a2b3c4d5e6f7g8h9i';
let result = str.split(/[A-z]/)
console.log(result);//['1', '2', '3', '4', '5', '6', '7', '8', '9', '']

search()

  • 搜索字符串中是否含有指定内容
  • 如果搜索到指定内容,则会返回第一次出现的索引,如果没有搜索到返回-1;
  • 可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串
  • 只会查找第一个,即使设置了全局匹配也没用

需求:搜索字符串中是否含有abc

let str = 'hello abc hello abc';
let result1 = str.search('abc');
console.log(result1)//6
let result2 = str.search('abcd');
console.log(result2)//-1

需求:搜索字符串中是否含有abc 或 aec 或afc

let str = 'hello abc hello aec afc';
let result1 = str.search(/a[bef]c/);
console.log(result1)//6

match()

  • 可以根据正则表达式,从一个字符串中将符合条件的内容提取出来
  • 默认情况下我们的match只会找到第一个符合要求的内容,找到以后就停止检索了,我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容。
  • 可以为一个正则表达式设置多个表达式,且顺序无所谓/[A-z]/ig == /[A-z]/gi
  • match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果

需求:找到字符串中所有的字母

let str = '1a2b3c4d5e6f7g8h9i';
let result = str.match(/[A-z]/g);
let result2 = str.match(/[A-z]/ig);//即全局匹配又忽略大小写
console.log(result);//['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']

replace()

  • 可以将字符串中指定内容替换为新的内容
  • 参数:1被替换的内容,可以接受一个正则表达式作为参数 2新的内容
  • 默认只会替换第一个
let str = '1a2a3a4a5e6f7A8B9C';
let result1 = str.replace('a','@_@');
console.log(result1);//1@_@2a3a4a5e6f7A8B9C
let result2 = str.replace(/[a-z]/gi,'@_@');
console.log(result2);//1@_@2@_@3@_@4@_@5@_@6@_@7@_@8@_@9@_@
let result3 = str.replace(/[a-z]/gi,'');
console.log(result3);//123456789

正则表达式语法

量词:

  • 通过量词可以设置一个内容出现的次数
  • {n}正好出现n次
  • 量词只对它前面的一个内容起作用/(ab{3})/:找abbb的,如果想找连续的ababab,则/(ab){3}/
  • /ab{1,3}c/意思为找abc,abbc,abbbc。b出现一次到三次
  • /ab{3,}c/意思为b可以出现三次及以上
  • {m,n}出现m-n次
  • {m,}出现m次以上
  • +至少一个,相当于{1,}
  • *0个或多个,相当于{0,}
  • ?0个或一个,相当于{0,1}
  • ^ 表示开头
  • $ 表示结尾
  • . 表示任意字符
  • 在正则表达式中使用\作为转义字符,.表示.;\表示\

需求:创建一个正则表达式来检查一个字符串中是否含有aaa(/aaa/ == /a{3}/)

let reg = /aaa/;
console.log(reg.test('aaabs'))//true
let reg1 = /a{3}/;
console.log(reg1.test('aaabs'))//true

需求:检查一个字符串是否以a开头

let reg = /^a/ //匹配开头的a
let reg1 = /a$/ //匹配结尾的a
let reg2 = /^a$/ //只能有一个a
let reg3 = /^|a$/ //以a开头或者以a结尾
console.log(reg.test('abc'))//true
console.log(reg1.test('abc'))//false
console.log(reg2.test('abc'))//false

需求:创建一个正则表达式,用来检查一个字符串是否是一个合法手机号。手机号规则:11位;第一位以1开头;第二位3-9任意数字;三位以后任意数字9个

let phoneStr = '13454563656';
let phoneReg = /^1[3-9][0-9]{9}$/
console.log(phoneReg.test(phoneStr));//true

需求:检查字符串中是否含有.

let reg =/./;
let reg1 = /\./;
console.log(reg.test('s'))//true
console.log(reg1.test('s'))//false

需求:检查字符串中是否含有\

let reg1 = /\\/;
console.log(reg1.test('s\\'))//true

猜你喜欢

转载自blog.csdn.net/weixin_48242257/article/details/121147092