【JS】JavaScript高级程序设计-第五章 引用类型

五 引用类型

5.1 Object类型

创造Object实例
两种方式: ①new ②对象字面量

var person = new Object();
var person2 = { name: 'zhangsan'}

对象的属性
原型相关方法见后续章节,此处不展开

var person = {};
// 添加/修改属性
person.name ='Zhangsan'
// 动态的属性名 可使用[] 
var n = 'sex';
person[n] = '18';
console.log(person); // {name: 'Zhangsan', sex: '18'}
// 删除属性
delete person.name;
delete person[n];
console.log(person); // {}

5.2 Array类型

创建、读、设置

// 使用构造函数
var arr = new Array();
// 知道数组数量
var arr2 = new Array(3);
// 知道数组具体值
var arr3 = new Array('red', 'blue', 'green');

// 使用字面量:
var colors = [];
var colors2 = ['red', 'blue', 'green'];
console.log(colors2[0]); // red
colors[1] = 'black'; // 修改第二项
colors[3] = 'pink'; //新增第四项

**数组长度 length **
length属性 不是只读的,可以设置该属性,使数组移除末项或添加新项

var colors = ['red', 'blue', 'green'];
console.log(colors.length); //3
colors.length = 4;
console.log(colors[3]); // undefined
colors.length = 2;
console.log(colors); //['red', 'blue']
// 利用length 在末尾新增
colors[colors.length] = 'pink'
console.log(colors); // ['red', 'blue', 'pink']

5.2.1 检测数组、转换方法

** 检测数组**
①instanceof 前面有提到引用类型可以使用instanceof来判断
②Array.isArray()

console.log(['red'] instanceof Array); //true
console.log(Array.isArray(['red']); // true

转换方法
如前所述,所有对象都具有toLocaleString() 、toString() 、valueOf()方法。
toLocaleString()、toString():返回数组中每个值的字符串形式,以逗号分隔
valueOf(): 返回的还是数组

var colors = ['red', 'blue'];
console.log(colors.toLocaleString()); // red,blue
console.log(colors.valueOf()); // ['red', 'blue']
console.log(colors.toString()); // red, blue

5.2.2 栈方法

栈是一种LIFO(后进先出)的数据结构。数组提供push()和pop()方法来实现类似栈的行为。
push(): 向数组的末尾添加一个或更多元素,并返回插入后数组的长度
pop(): 从数组末尾移除最后一项,减少数组的length值,并返回移除的项

var arr = []
var count = arr.push('red', 'green'); // 推入两项
console.log(count); //2
const item = arr.pop();
console.log(item); // green

5.2.3 队列方法

队列是一种FIFO(先进先出)的数据结构。数组提供shift()方法,可以移除数组中第一个项并返回该项,同时数组长度-1。
结合shift和push可以像队列一样使用数组。

var color = [];
color.push('red','green');
var item = colors.shift(); // 取得第一项
console.log(item); // 'red'
console.log(colors.length); // 1

另外提供unshift()方法,能在数组前端添加任意个项并返回新数组的长度。同时使用unshift()和pop()可以从相反方向来模拟队列。

var colors = [];
colors.unshift('red', 'green');
colors.unshift('pink');
console.log(colors); // ['pink', 'red', 'green']
var item = colors.pop();
console.log(item); // 'green'
console.log(colors.length); // 2

5.2.1 其他常用方法

排序
sort(): 用于对数组的元素进行排序,并返回数组。
reverse(): 反转数组项的顺序, 该方法会改变原来的数组,而不会创建新的数组。

var values = [1,2,3,4,5];
values.reverse();
console.log(values); //  [5, 4, 3, 2, 1]

sort() ① 未传参数: ,按照 unicode码顺序排序,默认升序

var values = [1,5,10,15];
values.sort();
console.log(values); // [1, 10, 15, 5]

②传参数: 接收一个比较函数,返回比较的结果。
比较函数返回值:
负值,如果所传递的第一个参数比第二个参数小。
零,如果两个参数相等。
正值,如果第一个参数比第二个参数大。

function compare(value1,value2) {
	if (value1 <value2) return -1;
	else if (value1 > value2) return 1;
	else  return 0;
}
//对于数值类型或者其valueOf方法会返回数值类型的对象类型,可以简写为:
// 升序 (降序: value2 - value1)
function compare2(value1, value2) {
  return value1 - value2
}

concat()
合并两个或多个数组, 不改变当前数组,返回一个新数组

var arr1 = ['str1', 'str2'];
var arr2 = arr1.concat('str3', ['str4', 'str5']);
console.log(arr1); // ['str1', 'str2']
console.log(arr2); // ['str1', 'str2', 'str3', 'str4', 'str5']

splice
数组中非常强大的方法。主要用法有三种
删除:可以删除任意数量的项。splice(index, num) index:删除的第一项的位置; num:要删除的项数
插入:可以向指定位置插入任意数量的项。splice(startIndex, 0, insertData1, insertData2)。 startIndex 起始位置;num:删除0项,insertData1插入的数据
替换:可以向指定位置插入任意数量的项,同时删除任意数量的项。splice(startIndex, num, insertData1, insertData2)
返回值:返回一个数组,包含从原始数组删除的项

var colors = ['red','green','blue'];
var removed = colors.splice(0, 1); // 删除第一项
console.log(removed); // ['red]
removed = colors.splice(1, 0, 'yellow', 'pink'); // 从位置1插入
console.log(removed); // [] 
removed = colors.splice(1,1, 'red', 'black'); // 从位置1删除1个,在插入两个
console.log(removed); // ['yellow']
console.log(colors); // ['green', 'red', 'black', 'pink', 'blue']

slice()
返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
若begin为负数则表示从原数组中的倒数第几个元素开始提取
该end为负数, 则表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1) 表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)

var colors = ['green', 'red', 'black', 'pink', 'blue'];
console.log(colors.slice(2)); // ['black', 'pink', 'blue']
console.log(colors.slice(2,3)); //['black']
console.log(colors.slice(-2); ['pink', 'blue']
console.log(colors.slice());// ['green', 'red', 'black', 'pink', 'blue']

includes()
判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false

var colors = ['green', 'red', 'black', 'pink', 'blue'];
console.log(colors.includes('red')); // true

join()
将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。 (默认以,分隔)

var colors = ['green', 'red', 'black', 'pink', 'blue'];
console.log(colors.join()); // green,red,black,pink,blue
console.log(colors.join('-')); // green-red-black-pink-blue

位置方法
indexOf(): 返回在数组中可以找到给定元素的第一个索引,不存在返回-1;
lastIndexOf(): 从数组末尾开始向前找
两个方法均接受两个参数: 要查找的项和查找起点位置的索引(可选)

var numbers = [1,2,3,4,5,4,3,2,1];
console.log(numbers.indexOf(4); //3
console.log(numbers.lastIndexOf(4); // 5
console.log(numbers.indexOf(4,4); //5;
console.log(numbers.lastIndexOf(4,4); // 3

find()
返回数组中满足提供的测试函数的第一个元素的值,没找到则返回 undefined

var numbers = [1,2,3,4,5,4,3,2,1];
const findRes = numbers.find(item => item === 3);
console.log(findRes); //3

迭代方法
every(): 对数组中的每一项运行给定函数,如果函数对每一项都返回true,则返回true
filter():对数组中的每一项运行给定函数,返回该函数返回true的项组成的新数组
forEach(): 遍历数组,类似for循环, 但使用break return等中断语句无效, 无返回值。
map():对数组中的每一项运行给定函数,返回该函数调用的结果组成的新数组
some():对数组中的每一项运行给定函数,任一项返回true则返回true

var numbers = [1,2,3,4,5,4,3,2,1];

var everyRes = numbers.every((item,index,array) => {
	return item> 2;
})
console.log(everyRes); //false

var someRes = numbers.some(item => item > 2);
console.log(someRes); // true

var filterRes = numbers.filter(item => item> 2);
console.log(filterRes); // [3, 4, 5, 4, 3]

var mapRes = numbers.filter(item => item* 2);
console.log(mapRes); // [2, 4, 6, 8, 10, 8, 6, 4, 2]

numbers.forEach(item => {
  console.log(item)
})

reduce()
reduce() 接受两个参数,一个回调函数,一个初始值,如果不赋初始值他会默认从第一个元素开始。
reduce的回调函数接受四个参数:Accumulator(acc)累加器,Curent Value(cur)当前值,Current Index(idx) 当前索引,Sourc Array(src)元素组。
reduceRight() 与reduce()类似,从数组的最后一项开始,向前遍历至第一项。
场景:求和

var arr = [1, 2, 3, 4, 5];
var res = arr.reduce((prev, next) => prev + next)
console.log(res); // 15
var res2= arr.reduce((prev,next) => prev+next, 1); // 赋了初始值1
console.log(res); // 16

二维数组转为1维数组

var arr = [1, 2, [3, 4], 5];
var res2= arr.reduce((prev,next) => prev.concat(next), []);
console.log(res2); // [1, 2, 3, 4, 5]

5.3 Date类型

Date类型保存的日期能够精确到1970年1月1日之前或之后的285616年。
构造日期对象: var now = new Date()
toLocaleString(): 按照与浏览器设置的地区相适应的格式返回日期和时间
toString(): 返回带时区信息的日期和时间
valueOf():返回日期的毫秒数,因此可以使用小于或大于来比较日期值

var now = new Date();
console.log(now.toLocaleString()); // 2024/1/11 17:17:59
console.log(now.toString()); // Thu Jan 11 2024 17:17:59 GMT+0800 (中国标准时间)
console.log(now.valueOf()); // 1704964679923

5.3.1 日期格式化方法

toDateString():显示星期几、月、日、年
toTimeString():显示时、分、秒、时区
toLocaleDateString():以特定的地区的格式显示星期几、月、日、年
toLocaleTimeString():以特定的地区的格式显示时、分、秒
toUTCString():以特定于实现的格式完成的UTC日期

var date = new Date();
console.log(date.toDateString()); // Fri Jan 12 2024
console.log(date.toTimeString()); // 10:08:08 GMT+0800 (中国标准时间)
console.log(date.toLocaleDateString()); //2024/1/12
console.log(date.toLocaleTimeString()); // 10:08:08
console.log(date.toUTCString()); // Fri, 12 Jan 2024 02:08:08 GMT

5.3.2 日期/时间组件方法

相关的方法很多,这里主要列举一些常用的
getTime():返回日期的毫秒数,与valueof方法返回的值相同
getFullYear():获取4位数的年份
setFullYear(year):设置日期的年份,必须传入4位数
getMonth():返回日期中的月份0-11. 0表示1月
setMonth(month):设置月份,一月为 0,二月为 1,依此类推。
getDate():获取当前日期月份中的天数(1-31)
setDate(date):设置日期月份中的天数,若传入的值超过该月中应有的天数则增加月份
getDay():返回星期几,0表示星期日,6表示星期六
getHours:返回日期中的小时数0-23
getMinutes():返回日期中的分钟数0-59
getSeconds():返回日期中的秒数0-59
getMilliseconds():返回日期中的毫秒数

var date = new Date(); // Fri Jan 12 2024 10:26:15 GMT+0800 (中国标准时间)
console.log(date.getTime()); // 1705026375622
console.log(date.getFullYear()); // 2024
console.log(date.getMonth()); // 0
console.log(date.getDate()); // 12
console.log(date.getDay()); // 5
console.log(date.getHours()); // 10
console.log(date.getMinutes()); // 26
console.log(date.getSeconds());  // 15
console.log(date.getMilliseconds()); // 622
console.log(date.setFullYear(2023));
date.setFullYear(2023);
date.setMonth(1);
date.setDate(19);
console.log(date.getFullYear(), date.getMonth(), date.getDate()); // 2023 1 19

5.4 RegExp类型

通过RegExp来支持正则表达式。
①使用字面量形式来定义:var expression = / pattern / flags ;
pattern(模式): 可以是任何简单或复杂的正则表达式,可以包含字符类、限定符、分组、向前查找以及反向引用。
flags(标识): 用以表明正则表达式的行为。

  • g:表示全局模式,即模式将被应用于所有字符串
  • i:表示不区分大小写模式
  • m:表示多行模式,会在到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项
    注意:如包括{ [ \ ^ $ | ) ? * + . ] },需要进行转义
// 匹配字符串中所有at的实例
var pattern1 = /at/g;
// 匹配第一个bat或cat,不区分大小写
var pattern2 = /[bc]at/i;
// 匹配所有以at结尾的3个字符的组合,不区分大小写
var pattern3 = /.at/gi;

// 匹配第一个'[bc]at', 不区分大小写
var pattern4 = /\[bc\]at/i;

②使用RegExp构造函数,共接收两个参数:1个是要匹配的字符串模式,另一个是可选的标志字符串
注意:构造函数接受的参数是字符串,即不能将正则表达式字面量传递给RegExp构造函数。
字面量模式: /\[bc]at/ 等价的字符串: "\\[bc\\]at"

var pattern = new RegExp("[bc]at", i); // 等价于 /[bc]at/i;

5.4.1 RegExp 实例属性

  • global: 布尔值,是否设置了g标识
  • ignoreCase: 布尔值,是否设置了i标识
  • lastIndex:整数,表示开始搜索下一个匹配项的字符位置,从0开始
  • multiline:布尔值,是否设置了m标识;
  • source:正则表达式的字符串表示,按照字面量形式而非传入构造函数中字符串模式返回
var pattern1 = /\[bc\]at/i;
console.log(pattern1.global);// false
console.log(pattern1.ignoreCase);// true
console.log(pattern1.lastIndex); // 0
console.log(pattern1.multiline); // false
console.log(pattern1.source); // "\[bc\]at"

5.4.2 实例方法

RegExp对象的主要方法是exec()。接受一个参数(应用模式的字符串),返回包含第一个匹配项信息的数组(包含两个额外属性:index-匹配项在字符串中的位置、input-表示应用正则表达式的字符串);若没有匹配项返回null

var text = 'mon and dad and baby';
var pattern= /mon( and dad( and baby)?)?/gi;
var matches= pattern.exec(text);
console.log(matches.index); // 0
console.log(matches.input);// "mon and dad and baby"
console.log(matches[0]); // "mon and dad and baby"
console.log(matches[1]); //  "and dad and baby"
console.log(matches[2]); // "and baby"

test() ,接受一个字符串参数,在模式与该参数匹配的情况下返回true,否则返回false

var text = '000-00-0000';
var pattern = /\d{3}-\d{2}-\d{4}/;
console.log(pattern.test(text)); // true

5.4.3 RegExp构造函数属性

这些属性分别有一个长属性名和一个短属性名

长属性名短属性名说明
input$_最近一次要匹配的字符串
lastMatch$&最近一次的匹配项
lastParen$+最近一次匹配的捕获组
leftContext$`input字符串中lastMatch之前的文本
multiline$*布尔值,是否使用多行模式
rightContext$’input字符串中lastMatch之后的文本
var text = 'this has been a short summer';
var pattern = /(.)hort/g;
if(pattern.test(text)) {
	console.log(RegExp.input); // "this has been a short summer"
	console.log(RegExp.lastMatch); //short
	console.log(RegExp.lastParen);// s
	console.log(RegExp.leftContext); // this has been a 
	console.log(RegExp.multiline); // false
	console.log(RegExp.rightContext); some
}

5.5 Function类型

函数实际上是对象,每个函数都是Function类型的实例。函数名实际也是一个指向函数对象的指针。
要访问函数的指针而不执行函数的话,需要去掉圆括号

function sum (num1, num2) {
return num1 + num2;
}
var sum1 = function(num1,num2) {
return num1 + num2;
}
console.log(sum(10,10)); // 20
console.log(sum1(10,10)); // 20
var sum2 = sum;
console.log(sum2(10, 10)); // 20

前面也提到过函数没有重载。如果声明两个同名函数,后面的函数会覆盖前面的函数。实际上就是因为函数名是指向函数对象的指针,创建的第二个同名函数实际上覆盖了引用第一个函数的变量
函数内部属性
函数内部有两个特殊的对象:arguments和this.
this引用的是函数据以执行的环境对象

var color = 'red';
var o = {color: 'blue'};
function sayColor(){
console.log(this.color);
}
sayColor(); // "red"
o.sayColor = sayColor; // 这里将函数赋值给对象o,那么这里的this指代的就是o
o.sayColor(); // "blue"

函数属性和方法
length: 表示函数希望接受的命名参数的个数
prototype: 保存所有实例方法, 是不可枚举的(for-in无法发现)
每个函数都包含两个非集成而来的方法 apply() 和call()
apply():接受两个参数,一个是在其中运行函数的作用域,另一个是参数数组(可以是Array实例,可以是arguments对象)

function sum (num1, num2) {
return num1 + num2;
}
function callSum1(num1, num2) {
return sum.apply(this,arguments);
}
function callSum2(num1, num2) {
return sum.apply(this, [num1,num2]);
}
console.log(callSum1(10,10)); // 20
console.log(callSum2(10,10)); // 20

call()方法与apply()作用相同,接受参数的方式不同,第一个参数是this,其余参数必须逐个列举

function sum (num1, num2) {
return num1 + num2;
}
function callSum1(num1, num2) {
return sum.call(this, num1, num2);
}
console.log(callSum1(10,10)); // 20

5.6 基本包装类型

Boolean、Number、String 基本包装类型与引用类型主要区别就是对象的生存期。使用new创建的引用类型实例,在执行流离开当前作用域之前都一直保存在内存中;而自动创建的基本包装类型的对象,只存在于一行代码的执行瞬间,然后立即被销毁。
使用new调用基本包装类型的构造函数 typeof 是Object

var number1 =Number('25'); // 转型函数
var number2 = new Number('25'); // new 构造函数
console.log(typeof number1); // number
console.log(typeof number2); //object

字符串操作方法
concat() 字符串拼接
slice(): 接受2个参数,第二个参数可选。1.制定字符串开始的位置,2.字符串结束的位置(不包含),当第二个参数是负数时,会被转换为参数+字符串长度;
substring():接受2个参数,第二个参数可选。1.制定字符串开始的位置,2.字符串结束的位置(不包含),当第二个参数是负数时,会被转换为0
substr():接受2个参数,第二个参数可选。1.制定字符串开始的位置,2.返回的字符个数, 当第二个参数是负数时,会被转换为0(也就是返回空字符串)

// concat拼接字符串
var value1 = 'hello';
var result = value1.concat('world');
console.log(result) // helloworld
console.log(result.slice(3)); // loworld
console.log(result.substring(3));// loworld
console.log(result.substr(3)); // loworld

console.log(result.slice(3,7)); // lowo
console.log(result.substring(3,7)); //lowo
console.log(result.substr(3,7)); //loworld

5.7 单体内置对象

global对象
不属于任何其他对象的属性和方法,最终都是他的属性和方法。例如isNaN()
Math对象
提供计算的属性和方法
常用方法:
Math.min() 、Math.max() 获取一组数值中的最小值和最大值
Math.ceil() 向上舍入
Math.round() : 标准四舍五入
Math.floor() : 向下取舍

console.log(Math.max(1,2,3,4,5));// 5
console.log(Math.min(1,2,3,4,5));// 1
console.log(Math.ceil(25.9)); //26
console.log(Math.round(25.9));// 26
console.log(Math.floor(25.9)); // 26

总结

1.其他所有类型都是从Object集成了基本的行为
2.Array数组常用的方法
3.Date 日期相关格式化
4.RegExp,提供正则表达式相关功能
5.函数实际是Function类型的实例,因此函数是对象
6.基本包装类型:Boolean Number String
7.this的作用域

  • 32
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值