第五章 JavaScript引用类型
程序员文章站
2022-07-12 17:49:06
...
引用类型
- 引用类型是一种数据结构,用于将数据和功能组织在一起,描述了一类对象所具有的属性和方法.
- JavaScript是面向对象的,但不具有传统的面向对象语言所支持的类和接口等基本结构.
- 引用类型的值(对象)是引用类型的一个实例.
5.1 Ojbect类型
创建Object实例的两种方式
- new:
var person = new Object();
- 字面量:
var person = {};
访问对象属性的方式
- 点表示法:
person.name
- 方括号表示法:
person[name]
方括号表示法的优点
- 可以通过变量访问属性
var propertyName = 'name';
person[propertyName];
- 属性名中包含空格:
person['first name']
;
5.2 Array类型
创建数组的两种方式
- Array构造函数
var colors = new Array();
var colors = new Array("yellow");
- 数组字面量
var colors = ["red","blue"]
注意: 数组的length属性有个特点 – 不是只读的.可以直接设置:
arr.length = XXX
5.2.1 检测数组
-Array.isArray(value)
var arr = ["yellow"];
// 输出 true
console.log(Array.isArray(arr));
5.2.2 转换方法
-
valueOf()
返回数组本身,输出含有[]
var arr = ['yellow','blue'];
// 输出: [ 'yellow', 'blue' ]
console.log(arr.valueOf())
-
toString()
数组中每个值的字符串形式以逗号分隔拼接而成的字符串. 输出无[]
-
toLocaleString()
需要数组中的对象重写toLocaleString(), 否则同toString(), 输出无[]
-
join()
自定义分隔符, 输出无[]
var arr = ["yellow","blue","green"];
// 输出: yellow666,blue666,green
console.log(arr.join("666,"));
注意: 如果数组中某一项的值是
null
或者undefined
,那么该值toString()
,join()
,toLocaleString()
3个方法返回的结果中以空字符串表示:var arr = ["yellow",null,undefined]; // 输出: yellow,, console.log(arr.toString()); console.log(arr.toLocaleString()); console.log(arr.join(","));
valueOf()
有点特殊var arr = ["yellow",null,undefined]; // 输出: [ 'yellow', null, undefined ] console.log(arr.valueOf())
5.2.3 栈方法
-
push()
: 接受任意数量的参数, 添加至数组末尾. 返回修改后的数组长度. -
pop()
: 从数组末尾移除最后一项, 减少数组长度. 返回被移除的项.
5.2.4 队列方法
-
unshift()
: 在数组的前端, 添加任意项. 返回新数组的长度. -
shift()
: 从数组的前端移除一项, 返回移除的项.
5.2.5 重排序方法, 会改变原始数组
-
reverse()
: 反转数组项的顺序 -
sort()
:sort()
方法会调用每项的toString()
方法, 比较字符串,默认升序
但会有问题var arr = [0,5,10]; arr.sort(); // 输出: [ 0, 10, 5 ] console.log(arr.valueOf())
-
sort()
可以传入比较函数. 比较函数接受两个参数: 如果第一参数应该在第二个之前则返回一个负数. 如果两个参数相等返回0, 如果第一个参数位于第二个参数之后则返回一个正数.
var arr = [0,5,10]; arr.sort(compare); // 输出: [ 0, 5, 10 ] console.log(arr.valueOf()) function compare(v1, v2){ return v1 - v2; }
-
5.2.6 操作方法
-
concat()
: 基于当前数组项创建一个新数组, 参数可以为任意个数组或者单个的值. 不会影响原数组 -
slice()
: 从数组中截取值,形成新数组. 不会影响原数组.- 接收一个参数, 从参数位置截取到数组末尾
- 接受两个参数, 截取值含头不含尾.
注意: 如果slice()方法中,有一个是负数, 则用数组长度加上该数来确定位置. 例如在一个5项的数组上调用slice(-2, -1)
= `slice(3, 4). 如果结束位置<起始位置, 则返回空数组.
var arr = [0,5,10]; var arr2 = arr.slice(1,0); // 输出: [] console.log(arr2)
-
splice()
: 会改变原数组- 删除: 两个参数,要删除的第一项的位置和删除的项数. 例如:
splice(0,2)
删除前两项 - 插入/替换: 三个参数. 起始位置, 要删除的项数, 和要插入的项.
- splice()返回值: 从原始数据中删除的项组成的数组. 如果没有删除的项, 则返回空数组.
- 删除: 两个参数,要删除的第一项的位置和删除的项数. 例如:
5.2.7 位置方法
方法都接收两个参数: 起始位置(可选)和要查找的项.没找到返回-1.
indexOf()
lastIndexOf()
当查找项和数组中每一项进行比较时, 会使用全等操作符(===).
5.2.8 迭代方法
-
every()
/some()
查询数组中的项是否满足某个条件.-
every()
传入的函数必须对每一项都返回true
, 这个方法才返回true
; 否则返回false
-
some()
传入的函数对有一项返回true
, 就会返回true
- 例子
var arr = [3,4,5,6,7]; // 每一项都大于3 ? false console.log(arr.every(function(item, index, array){ return item > 3 })); // 有一些项大于3 ? true console.log(arr.some(function(item, index, array){ return item > 3; }));
-
-
filter()
: 利用指定的函数筛选出符合条件的项组成的数组.
var arr = [3,4,5,6,7];
var filterResult = arr.filter(function(item, index, array){
return item > 5;
});
// [ 3, 4, 5, 6, 7 ] 不会改变原数组
console.log(arr);
// [ 6, 7 ]
console.log(filterResult);
-
map()
: 返回一个数组, 该数组的每一项是在原始数组中对应项上运行传入函数的结果.
var arr = [3,4,5,6,7];
var mapResult = arr.map(function(item, index, array){
return item * 2;
});
// [ 3, 4, 5, 6, 7 ] 不会改变原数组
console.log(arr);
// [ 6, 8, 10, 12, 14 ]
console.log(mapResult);
-
foreach()
: 对数组中的每一项运行传入的函数. 方法没有返回值.
var arr = [3,4,5,6,7];
arr.forEach( function(item, index) {
if (item == 5) {
arr = [];
}
});
// [] 可以改变原始数组
console.log(arr);
5.2.9 归并方法
-
reduce()
/reduceRight()
:reduce()
从做到右,reduceRight()
从右到左.两个参数: 每一项上调用的函数和归并起始值(可选的).返回求和的结果.
var arr = [0,1,2];
// 只传递一个参数时: pre是0, cur是1.
var sum = arr.reduce(function(pre, cur, index, array){
return pre + cur;
})
// 3
console.log(sum);
5.3 Date类型
new Date()
- 构造函数不传递参数, 新创建的对象自动获得当前日期和时间.
- 传参需要传递日期毫秒数.
- 计算日期毫秒数的两个方法: Date.parse(), Date.UTC().
var dateTest = new Date(2005, 4, 5, 17,55, 55);
// 2005年5月5日, 下午5点55分55秒
console.log(dateTest);
上述构造函数中会默认调用: Date.UTC();
月份是从0开始小时是24小时制
5.4 RegExp类型
5.5 Function类型
- JavaScript函数是对象, 函数名是指向函数对象的指针.
- js函数没有重载.
- 函数声明与函数表达式的区别: js代码执行前会有函数声明提升的过程.
5.4.4 函数内部属性
1. arguments
-
arguments
是一个类数组对象,包含传入的所有参数. - 该对象有一个
callee
属性, 该属性是一个指针, 指向拥有这个arguments
对象的函数.
function factorial(num) {
// true
console.log(factorial === arguments.callee)
// [Function: factorial]
console.log(arguments.callee)
// [Function: factorial]
console.log(factorial)
}
2.this
-
this
引用的是函数执行的环境对象 - 具体请参考阮一峰: http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html
3. Function.caller === arguments.callee.caller
-
caller
这个属性保存调用当前函数的函数的引用 - 如果在全局作用域中调用当前函数, 他的值为
null
function inner(num) {
// true
console.log(inner.caller === outer)
// [Function: outer]
console.log(inner.caller)
}
function outer() {
inner();
}
outer()
5.5.5 函数的属性和方法
- length和prototype属性
- length属性是函数的参数数量
- prototype是函数原型
- apply() / call()方法: 在特定的域中调用函数,两个参数,第一参数为运行函数的作用域, 第二个: apply()为数组, call()为所有单个参数
function sayColor(){
console.log(this.color);
}
window.color = "red";
var obj = {
color : "blue"
}
// red
sayColor.apply(window);
// blue
sayColor.apply(obj);
-
bind()
: 创建一个函数实例, 其this的值会绑定到传给bind()函数的值
function sayColor(){
console.log(this.color);
}
window.color = "red";
var obj = {
color : "blue"
}
var objeSayColor = sayColor.bind(obj);
// blue
objeSayColor();
// red
sayColor();
5.6 基本包装类型
- 每当读取一个基本类型的值的时候, 后台会创建一个对应的基本包装类型的对象.从而能够调用一些方法操作这些数据.
例如:
var s1 = "some text";
var s3 = s1.substring(2)
s1是字符串,基本类型的值.理论上不应该有方法.第二行代码访问s1时处于读取模式, 后台会自动完成下列处理.
var s1 = "some text";
var s2 = s1.substring(2);
s1 = null;
- Object构造函数会像工厂方法一样, 根据传入的值的类型返回相应基本包装类型的实例(Number, String, Boolean).
var obj = new Object(1);
// true
console.log(obj instanceof Number);
使用new操作调用基本包装类型的构造函数, 与直接调用同名的转型函数是不一样的.例如:
var value = 25;
var number = Number(value);
// number
console.log(typeof number);
var number = new Number(value);
// obj
console.log(typeof number);
5.6.1 Boolean类型
需要理解基本类型的布尔值与Boolean对象之间的区别 – 建议永远不要使用boolean对象.
var obj = new Boolean(false);
// [Boolean: false]
console.log(obj);
// true, 布尔表达式中所有的对象都会被转换为true
console.log(obj && true);
5.6.2 Number类型
-
toString()
带参数,返回几进制的字符串形式.
var num = 10;
// 10 默认十进制
console.log(num.toString())
// 1010
console.log(num.toString(2))
// 12
console.log(num.toString(8))
// 10
console.log(num.toString(10))
// a
console.log(num.toString(16))
-
toFixed()
四舍五入保留一定的小数位
var num = 10.345;
// 10.35
console.log(num.toFixed(2));
var num2 = 0.345;
// 0.34 据MDN介绍,toFixed会要必要时对数值进行四舍五入,但所谓的必要时指的是啥就不清楚了,或许要查看源码实现了
console.log(num2.toFixed(2));
-
toExponential()
, 该方法返回指数表示法.接受一个参数,表示小数位数.
var num = -10.1;
// -1.01e+1
console.log(num.toExponential(2));
-
toPrecision()
可能返回fixed格式也可能是指数格式;具体规则是看哪种格式最合适, 接受一个参数表示数字位数.
var num = 99;
// 1e+2
console.log(num.toPrecision(1));
// 99
console.log(num.toPrecision(2));
// 99.0
console.log(num.toPrecision(3));
5.6.3 String类型
- 字符方法
-
charAt()
: 返回某个位置的字符 -
charCodeAt()
: 返回某个位置的字符的ASCII码
- 字符串操作方法
-
concat()
同 +var str = "hello"; console.log(str.concat(" world")); console.log(str+" world")
-
slice()
/substring()
/substr()
- 两个参数都是正数
slice()
与substring()
含义相同
var str = "hello"; // 一个参数截取到末尾 ello console.log(str.slice(1)); // 两个参数含头不含尾 el console.log(str.slice(1,3)); console.log(str.substring(1)); console.log(str.substring(1,3)); // 一个参数截取到末尾 ello console.log(str.substr(1)); // 两个参数: 从1开始截取3个数 ell console.log(str.substr(1,3));
- 参数有负数
-
slice()
将所有负值与字符串的长度相加 -
substr()
将负的第一个参数加上字符串的长度, 将负的第二个数转换为0 -
substring()
将所有负参数都转换为0
- 两个参数都是正数
substring()
会将较小的数作为开始位置,所以substring(3,0)相当于substring(0,3)
- 字符串位置方法
-
indexOf()
/lastIndexOf()
: 两个参数,第一个要搜索的子串,第二个可选的起始位置.
-
trim()
去除字符串两边的空格, 返回字符串副本, 不影响原字符串.
5.7 单体内置对象
内置对象: 由ECMAScript实现提供的, 不依赖于宿主环境的对象, 这些对象在ECMAScript程序执行之前就已经存在了.
5.7.1 Global对象
- URI编码方法
- eval()方法
- Global对象的属性
- window对象
5.7.2 Math对象
-
Math
对象的属性 -
min()
和max()
方法用于确定一组数值中的最小值和最大值,也可以用于数组
var maxValue = Math.max(1,2,3,4,5); // 5 console.log(maxValue); var values = [1,2,3,4,5]; // 5 console.log(Math.max.apply(Math,values))
-
舍入方法
-
Math.ceil()
: 向上舍入最接近的整数 -
Math.floor()
: 向下舍入最接近的整数 -
Math.round()
: 四舍五入最接近的整数
// 2
console.log(Math.ceil(1.9))
// 1
console.log(Math.floor(1.9))
// 2
console.log(Math.ceil(1.9))
-
random()
: [0,1)的随机数
- 从某个整数范围内随机选择一个值
值 = Math.floor(Math.random() * 可能值的总数 + 第一个可能的值)
例如: 选择一个2到10之间的值
// 2到10总共9个数
var num = Math.floor(Math.random() * 9 +2);