一、数组
1、数据类型
在JavaScript中,除了5种原始数据类型之外,其他所有的都是对象,包括函数(Function)。
基本数据类型:String,boolean,Number,Undefined, Null
引用数据类型:Object(Array,Date,RegExp,Function)
2、创建数组
var arr = [];//这是使用数组直接量(Array Literal)创建数组
var arr = new Array();//构造函数Array() 创建数组对象
3、什么是数组
- 数组就是一组数据的集合
- 其表现形式就是内存中的一段连续的内存地址
- 数组名称其实就是连续内存地址的首地址
注:数组具有一个最基本特征:索引,这是对象所没有的
var obj = {};
var arr = [];
obj[2] = 'a';
arr[2] = 'a';
console.log(obj[2]); // 输出 a
console.log(arr[2]); // 输出 a
console.log(obj.length); // 输出 undefined
console.log(arr.length); // 输出 3
(1)obj[2]与arr[2]的区别
- obj[2]输出'a',是因为对象就是普通的键值对存取数据
- 而arr[2]输出'a' 则不同,数组是通过索引来存取数据,arr[2]之所以输出'a',是因为数组arr索引2的位置已经存储了数据
(2)obj.length与arr.length的区别
- obj.length并不具有数组的特性,并且obj没有保存属性length,那么自然就会输出undefined
- 而对于数组来说,length是数组的一个内置属性,数组会根据索引长度来更改length的值。
(3)为什么arr.length输出3,而不是1呢?
- 这是由于数组的特殊实现机制,对于普通的数组,如果它的索引是从0开始连续的,那么length的值就会等于数组中元素个数
- 而对于上面例子中arr,在给数组添加元素时,并没有按照连续的索引添加,所以导致数组的索引不连续,那么就导致索引长度大于元素个数,那么我们称之为稀疏数组。
二、伪数组
1、定义
- 拥有length属性,其它属性(索引)为非负整数(对象中的索引会被当做字符串来处理,这里你可以当做是个非负整数串来理解)
- 不具有数组所具有的方法
伪数组,就是像数组一样有 length 属性,也有 0、1、2、3 等属性的对象,看起来就像数组一样,但不是数组,比如
var fakeArray = {
length: 3,
"0": "first",
"1": "second",
"2": "third"
};
for (var i = 0; i < fakeArray.length; i++) {
console.log(fakeArray[i]); //first second third
}
console.log(Array.prototype.join.call(fakeArray,'+')) // first+second+third
注:伪数组是一个 Object,而真实的数组是一个 Array
console.log(fakeArray instanceof Array === false); // true
console.log(Object.prototype.toString.call(fakeArray) === "[object Object]") ; // true
var arr = [1,2,3,4,6];
console.log(arr instanceof Array === true); // true
console.log(Object.prototype.toString.call(arr) === "[object Array]"); // true
2、伪数组的常见种类
- arguments 参数列表
- DOM 对象列表(比如通过 document.getElementsByTags 得到的列表)
- jQuery 对象(比如 $("div"))
3、判断伪数组
(1)《javascript权威指南》上给出了代码用来判断一个对象是否属于“类数组”
// Determine if o is an array-like object.
// Strings and functions have numeric length properties, but are
// excluded by the typeof test. In client-side JavaScript, DOM text
// nodes have a numeric length property, and may need to be excluded
// with an additional o.nodeType != 3 test.
function isArrayLike(o) {
if (o && // o is not null, undefined, etc.
typeof o === 'object' && // o is an object
isFinite(o.length) && // o.length is a finite number
o.length >= 0 && // o.length is non-negative
o.length===Math.floor(o.length) && // o.length is an integer
o.length < 4294967296) // o.length < 2^32
return true; // Then o is array-like
else
return false; // Otherwise it is not
}
(2) Array.isArray方法
Array.isArray(fakeArray) === false;
Array.isArray(arr) === true;
4、伪数组转化为数组
(1)[].slice.call
;(function(a, b, c) {
let arr = [].slice.call(arguments)
console.log(arr) // ["a", "b", "c"]
})('a', 'b', 'c')
(2) Array.prototype.slice.call
;(function(a, b, c) {
let arr = Array.prototype.slice.call(arguments)
console.log(arr) // ["a", "b", "c"]
})('a', 'b', 'c')
(3)for循环
;(function(a, b, c) {
let arr = [], len = arguments.length;
for (let i = 0; i < len; i++) {
arr.push(arguments[i]);
}
console.log(arr) // ["a", "b", "c"]
})('a', 'b', 'c')
(4)Function.prototype.call.bind
;(function(a, b, c) {
var func = Function.prototype.call.bind(Array.prototype.slice);
console.log(func(arguments)) // ["a", "b", "c"]
})('a', 'b', 'c')
(5)...解构赋值
;(function(a, b, c) {
console.log(arguments); // Arguments(3) ["a", "b", "c", callee: ƒ, Symbol(Symbol.iterator): ƒ]
let arr = [...arguments];
console.log(arr); // ["a", "b", "c"]
})('a', 'b', 'c')
(6)Array.from
;(function(a, b, c) {
console.log(arguments); // Arguments(3) ["a", "b", "c", callee: ƒ, Symbol(Symbol.iterator): ƒ]
let arr = Array.from(arguments);
console.log(arr); // ["a", "b", "c"]
})('a', 'b', 'c')