资讯专栏INFORMATION COLUMN

JS语言核心——“数组”

miqt / 1917人阅读

摘要:创建数组字面量语法数组直接量或构造函数需要注意的是数组直接量的语法允许有可选的结尾的逗号,所以只有两个元素而非三个数组元素的读和写需要注意的是如果是负数或非负来索引数组,数组将转换为字符串,字符串作为属性名来用。

1 创建数组

字面量语法(数组直接量)或构造函数

需要注意的是数组直接量的语法允许有可选的结尾的逗号,所以[,,]只有两个元素而非三个

2 数组元素的读和写

需要注意的是如果是负数或非负来索引数组,数组将转换为字符串,字符串作为属性名来用。

var arr = [];
arr[-12] = 10;
console.log(arr[-12]); //此时这是一个属性

数组也是对象,所以也可以定义getter和setter方法

var arr = [];
Object.defineProperties(arr, {
    name: {
        value: "Oliver",
        writable: true
    },
    getName: {
        set: function(value) {
            this.name = value;
        },
        get: function() {
            return this.name;
        }
    }
})
arr.getName = "Oli"; //写入数据
console.log(arr.getName); //读取数据
3 稀疏数组

定义稀疏数组:

var arr0 = [,,,];                           // 稀疏
var arr1 = [1,,2,];                         // 稀疏
var arr2 = new Array(3);                    // 稀疏
var arr3 = new Array(); arr3.length = 3;    // 稀疏
var arr4 = [1,2,3]; delete arr4[0];         // 稀疏

// 以下都是非稀疏
var arr5 = [undefined, undefined, undefined];
var arr6 = new Array(3); arr6[0] = undefined; arr6[1] = undefined; arr6[2] = undefined;

需要注意的是当在数组直击量中省略值时不回创建稀疏数组。省略的元素在数组中是存在的,值是undefined,可以用in操作符检测

判断是否是稀疏数组:

index in array

forEach

如:下面哪些是稀疏数组

4 数组长度

length属性

另外可以用Object.defineProperty()让数组的length属性变为只读:

var arr = [,,,];
Object.defineProperty(arr, "length", {
    writable: false
})
arr.length = 10; //严格模式下报错

也可以用preventExtensible、seal、freeze来设置权限;

var arr = [,,,];
Object.preventExtensions(arr);
console.log(arr.length); //3
arr.push("hello"); //严格模式下报错
5 数组元素的添加和删除

pop方法

push方法

shift方法

unshift方法

splice方法

delete方法

需要注意的是delete操作不会影响数组的长度

var arr = [1,2,3,4];
delete arr[2];
console.log(arr.toString()); //1,2,,4 变成了稀疏数组
6 数组遍历

使用for循环是遍历数组元素最常见的方法:

// let o = {
//     name: "Oliver",
//     age: 18
// };
let o = ["Oliver", 18];
var keys = Object.keys(o); //属性名数组
var values = [];
for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    values[i] = o[key];
};
console.log(keys.toString()); //属性名
console.log(values.toString()); //值

或for-in循环:

for (let key in arr) {
    console.log(arr[key]);
}
// for (let key in arr) {
//     if (!arr[key]) {
//         continue;
//     }
//     console.log(arr[key]);
// }

for-in循环会枚举到继承的属性,需要过滤:

for (let key in arr) {
    if (!arr.hasOwnProperty(key)) {
        continue;
    }
    console.log(arr[key]);
}

最好不要用forin循环,遍历可能是升序也可能不是。

ES5中规定了新的方法forEach():

let arr = ["Oliver",,null,,,,undefined, 18];
arr.forEach( function(element, index) {
    console.log(element);
    console.log(index);
});
//Oliver 
//0 
//null 
//2 
//undefined 
//6 
//18 
//7 
7 多维数组

所谓的多维数组在JS中就是数组的数组;

8 ES3数组方法 8.1 join()和字符串方法split()
let arr = ["Oliver",,null,,,,undefined, 18];
console.log(arr.length); //8
var result = arr.join(" ");
console.log(result); //Oliver       18
console.log(result.split(" ").length); //8
console.log(result.split(" ").toString()); //Oliver,,,,,,,18
8.2 reverse() 8.3 sort()以及比较函数的参数
let arr = [213, 23, 2123, 1, 4, "Oliver", "Alice", "ali", "oli"];
console.log(arr.sort().toString()); //1,2123,213,23,4 
console.log(arr.sort(compare).toString()); //1,2123,213,23,4,ali,Alice,oli,Oliver 

function compare(a, b) {
    var a = a.toString().toLowerCase();
    var b = b.toString().toLowerCase();
    if (a > b) { //从小到大
        return 1;
    } else if (a = b) {
        return 0;
    } else {
        return -1;
    }
}
8.4 返回新数组 concat() 接收可选的多个参数 不改变原来的数组 8.5 返回子数组 slice() 接收可选的一个或两个参数 不改变原来的数组 8.6 插入和删除数组 splice() 接收可选的一个起始位置、删除的个数以及任意的要插入的元素
let arr = [213, 23,1,3,4,43];
var a = arr.splice(1,0,"hello");
console.log(arr.toString()); //213,hello,23,1,3,4,43 
console.log(a.toString()); //空 没有元素被删除
8.7push()和pop(),unshift()和shift() 8.8 toString()和toLocaleString() 9 ES5数组方法 9.1 forEach()

接收一个函数,该函数可以有三个参数:

数组元素

元素的索引

数组本身

语法:

array.forEach( function(element, index, array) {
    // statements
});
let arr = [1,2,3,4,5];
arr.forEach( function(element, index, array) {
    switch (arr[index]) {
        case 1:
            array[index] = element + "st";
            break;
        case 2:
            array[index] = element + "nd";
            break;
        case 3:
            array[index] = element + "rd";
            break;
        default:
            array[index] = element + "th";
            break;
    }
});
console.log(arr.toString()); //1st,2nd,3rd,4th,5th 
9.2 map()

该方法将调用的数组的每个元素传递给指定的函数,并返回一个数组,包含该函数的返回值,也就是说,传递给map方法的函数必须有返回值。map方法返回的是新的数组

语法:

var newArray = array.map(function (item) {
    // body...
})
let arr = [1,2,3,4,5];
let newArray = arr.map(function (item) {
    var index = arr.indexOf(item);
    if (arr[index + 1]) {
        return item + arr[index + 1]
    }
});
console.log(newArray.join(";"));
9.3 filter()

该方法接收的函数是用来逻辑判定的,如果为真,则将该子集的成员添加到一个作为返回值中的数组中;

语法:

var newArray = array.filter(function (x) {
    // body...
});
var arr = [1, 2, 3, 4, 5, 6];
var smaller = arr.filter(function(x) {
    if (x < 4) return true;
});
console.log(smaller.toString()); //1,2,3

var doubles = arr.filter(function(a, b) {
    if ((a + b) === 5) {
        return true
    }
});
console.log(doubles.toString()); //3

filter方法会跳过稀疏数组中缺少的元素,返回的数组是稠密的,可以用来压缩稀疏数组

var arr = [1, , undefined, , null, 6];
var anotherA = arr.filter(function(item) {
    return true;
});
console.log(anotherA.toString()); //1,,,6

也可以压缩空缺并删除undefined和null元素

var arr = [1, , undefined, , null, 6];
var anotherA = arr.filter(function(item) {
    return item !== undefined && item !== null;
});
console.log(anotherA.toString()); //1,6
9.4 every()和some()

every方法,当且仅当数组中的成员在判定函数中都返回true,才返回true;

some方法,至少有一个数组中的成员在判定函数中返回true,就返回true;

9.5 reduce()和reduceRight()

reduce方法

将数组进行组合,生成单个值,第二个参数为初始值(如果没有指定初始值,那么使用数组的第一个元素作为其初始值)

语法:

var result = array.reduce(function(previous, current, index, array) {
    //body...
}, initialValue);
var arr = [1,2,3,4,5,6];
var result = arr.reduce(function (x,y) {
    return x + y;
}, 0);
console.log(result); //21

实际运用(多维数组的扁平化):

var matrix = [
    [1, 2],
    [3, 4],
    [5, 6, 7],
    [8, 9, 10, 11]
];

var result = matrix.reduce(function(previous, current, index, array) {
    return previous.concat(current);
});

console.log(result.toString()); //1,2,3,4,5,6,7,8,9,10,11

reduceRight方法(从右到左的顺序)

var matrix = [
    [1, 2],
    [3, 4],
    [5, 6, 7],
    [8, 9, 10, 11]
];

var result = matrix.reduceRight(function(previous, current, index, array) {
    return previous.concat(current);
});

console.log(result.toString()); //8,9,10,11,5,6,7,3,4,1,2
9.6 indexOf()和lastIndexOf() 10 数组类型

检测是否数组:

Array.isArray()

Object.prototype.toString.call()

console.log(Array.isArray([])); //True
console.log(Object.prototype.toString.call([]).slice(8, -1)); //Array
11 类数组对象

创建类数组对象

//新建空的Object,a
let a = {};
//向a添加属性
var i = 0;
while (i < 10) {
    a[i] = i;
    i++
}
//添加length属性
a.length = i;

//完成
//当做数组遍历它
for (var i = 0; i < a.length; i++) {
    console.log(a[i]);
};
//输出0-9
12 作为数组的字符串

字符串可以当做数组,使用方括号语法访问数据;但是字符串是不可变值,类似Array.prototype.push()等方法不可用。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79086.html

相关文章

  • task0002(一)- JavaScript数据类型及语言基础

    摘要:不过让流行起来的原因应该是是目前所有主流浏览器上唯一支持的脚本语言。经过测试,数字字符串布尔日期可以直接赋值,修改不会产生影响。再考虑对象类型为或者的情况。对于结果声明其类型。判断对象的类型是还是,结果类型更改。 转载自我的个人博客 欢迎大家批评指正 1. 第一个页面交互 这里最需要学习的老师的代码中,每一部分功能都由函数控制,没有创建一个全部变量。且最后有一个函数来控制执行代码...

    elarity 评论0 收藏0
  • JavaScript 语言核心笔记(持续更新)

    摘要:在同一个块内,不允许用重复声明变量。中为新增了块级作用域。自带遍历器的对象有数组字符串类数组对象对象的对象等和结构对象。返回一个遍历器,使遍历数组的键值对键名键值。 目录 1.语法 2.类型、值和变量 3.表达式和运算符 4.语句 5.数组 6.对象 7.函数 8.全局属性和方法 9.词法作用域、作用域链、闭包 10.原型链、继承机制 11.this的理解 12.ES5新特性 13.E...

    suosuopuo 评论0 收藏0
  • JS语言核心——“正则表达式的模式匹配”

    摘要:正则表达式一个描述字符模式的对象正则表达式的定义构造函数正则表达式直接量一对斜杠新特性正则的扩展引用类型类型的注意要点用于模式匹配的方法不支持全局搜索忽略表达式参数中的修饰符两个参数第一个是正则表达式,第二个是要替换的字符串接收一个正则表达 正则表达式(regular expression):一个描述字符模式的对象 1 正则表达式的定义 RegExp()构造函数 正则表达式直接量(一...

    李世赞 评论0 收藏0
  • JS语言核心——“函数”

    摘要:比如,以对象的方法的形式调用函数并传入两个参数可以传入的参数可以是数组和类数组的。方法的该方法主要作用是将函数绑定至某个对象,方法返回一个新的函数,调用这个新的函数会把绑定的函数在对象中当做方法来调用。 参数 形参(parameter):函数中定义的变量 实参(argument):运行时的函数调用时传入的参数 上下文(context):通过对象来调用函数时,这个对象就是thi...

    EsgynChina 评论0 收藏0
  • 以vue依赖统计为核心的框架(函数),mve

    摘要:试用过几回,不满的地方,是一个框架,必须最好按它的方式来编码,与混编,使用文件。经过一翻网络搜索,勉强明白了依赖更新的实现方式,便尝试着自己去实现一个框架。如今有依赖更新这种技术的存在,我觉得找到了可能。 初接触vue,惊为天人,它的更新方式极为取巧,但也是人们保持路人的原因:似乎没有一个严格的数学证明保证按它的方式能精确更新到DOM。不过脑子里推演的似乎不会发生失败,而且每次界面都能...

    Carl 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<