首页 > 其他分享 >arguments 这种类数组如何遍历

arguments 这种类数组如何遍历

时间:2024-03-24 17:32:29浏览次数:13  
标签:遍历 console name age sex arguments 数组

类数组对象

所谓的类数组对象:

拥有一个 length 属性和若干索引属性的对象

举个例子:

var array = ['name', 'age', 'sex'];

var arrayLike = {
    0: 'name',
    1: 'age',
    2: 'sex',
    length: 3
}

即便如此,为什么叫做类数组对象呢?

那让我们从读写、获取长度、遍历三个方面看看这两个对象。

读写

console.log(array[0]); // name
console.log(arrayLike[0]); // name

array[0] = 'new name';
arrayLike[0] = 'new name';

长度

console.log(array.length); // 3
console.log(arrayLike.length); // 3

遍历

for(var i = 0, len = array.length; i < len; i++) {
   ……
}
for(var i = 0, len = arrayLike.length; i < len; i++) {
    ……
}

是不是很像?

那类数组对象可以使用数组的方法吗?比如:

arrayLike.push('4');

然而上述代码会报错: arrayLike.push is not a function

所以终归还是类数组呐……

调用数组方法

如果类数组就是任性的想用数组的方法怎么办呢?

既然无法直接调用,我们可以用 Function.call 间接调用:

var arrayLike = {0: 'name', 1: 'age', 2: 'sex', length: 3 }

Array.prototype.join.call(arrayLike, '&'); // name&age&sex

Array.prototype.slice.call(arrayLike, 0); // ["name", "age", "sex"] 
// slice可以做到类数组转数组

Array.prototype.map.call(arrayLike, function(item){
    return item.toUpperCase();
}); 
// ["NAME", "AGE", "SEX"]

类数组转数组

在上面的例子中已经提到了一种类数组转数组的方法,再补充三个:

var arrayLike = {0: 'name', 1: 'age', 2: 'sex', length: 3 }
// 1. slice
Array.prototype.slice.call(arrayLike); // ["name", "age", "sex"] 
// 2. splice
Array.prototype.splice.call(arrayLike, 0); // ["name", "age", "sex"] 
// 3. ES6 Array.from
Array.from(arrayLike); // ["name", "age", "sex"] 
// 4. concat
Array.prototype.concat.apply([], arrayLike)

那么为什么会讲到类数组对象呢?以及类数组有什么应用吗?

要说到类数组对象,Arguments 对象就是一个类数组对象。在客户端 JavaScript 中,一些 DOM 方法(document.getElementsByTagName()等)也返回类数组对象。

Arguments对象

接下来重点讲讲 Arguments 对象。

Arguments 对象只定义在函数体中,包括了函数的参数和其他属性。在函数体中,arguments 指代该函数的 Arguments 对象。

举个例子:

function foo(name, age, sex) {
    console.log(arguments);
}

foo('name', 'age', 'sex')

打印结果如下:
在这里插入图片描述

我们可以看到除了类数组的索引属性和length属性之外,还有一个callee属性,接下来我们一个一个介绍。

length属性

Arguments对象的length属性,表示实参的长度,举个例子:

function foo(b, c, d){
    console.log("实参的长度为:" + arguments.length)
}

console.log("形参的长度为:" + foo.length)

foo(1)

// 形参的长度为:3
// 实参的长度为:1

callee属性

Arguments 对象的 callee 属性,通过它可以调用函数自身。

讲个闭包经典面试题使用 callee 的解决方法:

var data = [];

for (var i = 0; i < 3; i++) {
    (data[i] = function () {
       console.log(arguments.callee.i) 
    }).i = i;
}

data[0]();
data[1]();
data[2]();

// 0
// 1
// 2

接下来讲讲 arguments 对象的几个注意要点:

arguments 和对应参数的绑定

function foo(name, age, sex, hobbit) {

    console.log(name, arguments[0]); // name name

    // 改变形参
    name = 'new name';

    console.log(name, arguments[0]); // new name new name

    // 改变arguments
    arguments[1] = 'new age';

    console.log(age, arguments[1]); // new age new age

    // 测试未传入的是否会绑定
    console.log(sex); // undefined

    sex = 'new sex';

    console.log(sex, arguments[2]); // new sex undefined

    arguments[3] = 'new hobbit';

    console.log(hobbit, arguments[3]); // undefined new hobbit

}

foo('name', 'age')

传入的参数,实参和 arguments 的值会共享,当没有传入时,实参与 arguments 值不会共享

除此之外,以上是在非严格模式下,如果是在严格模式下,实参和 arguments 是不会共享的。

传递参数

将参数从一个函数传递到另一个函数

// 使用 apply 将 foo 的参数传递给 bar
function foo() {
    bar.apply(this, arguments);
}
function bar(a, b, c) {
   console.log(a, b, c);
}

foo(1, 2, 3)

强大的ES6

使用ES6的 … 运算符,我们可以轻松转成数组。

function func(...arguments) {
    console.log(arguments); // [1, 2, 3]
}

func(1, 2, 3);

应用

1、参数不定长
2、函数柯里化
3、递归调用
4、函数重载 …

标签:遍历,console,name,age,sex,arguments,数组
From: https://blog.csdn.net/weixin_57837275/article/details/136990999

相关文章

  • Go数组的扩容规则
    Go数组的扩容规则Go数组的扩容规则技术要点先是双倍扩容,然后是一定的比例扩容,逐渐向1.25进行靠近在目前的实现里面,在小于256的时候会进行double,在大于256的时候,会根据一定的生长因子进行扩容,但是总体来说还是会逐渐的靠近到1.25funcgrowslice(et*_type,olds......
  • 一个操作让数组处理速度快了5倍,到底是为什么
     概述:通过对数组进行排序,代码更好地利用了缓存,从而提高了程序的性能。这种现象通常被称为"缓存友好"(cache-friendly)或"空间局部性"(spatiallocality)今天做一个数组数据计算时,发现一个效率问题,给大家分享一下一个数组排序和不排序时同样的逻辑处理速度是不一样的。排序后速度......
  • JAVA数组和内存
    目录数组的概述和静态初始化介绍定义数组的初始化静态初始化动态初始化区别索引数组遍历常见问题数组练习求最值交换数据打乱数据数组的内存图!两个数组指向同一个空间的内存图总结数组的概述和静态初始化介绍1、数组是一种容器,用来存放同种数据类型的......
  • Java零基础-数组
    哈喽,各位小伙伴们,你们好呀,我是喵手。  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把......
  • Java零基础-数组:异常处理和错误处理
    哈喽,各位小伙伴们,你们好呀,我是喵手。  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把......
  • 和为 K 的子数组 - LeetCode 热题 10
    大家好!我是曾续缘......
  • 后缀数组学习笔记(未完成
    后缀数组定义与实现定义后缀从字符串某个位置i到字符串末尾的子串,定义s的第i个字符为第一个元素的后缀为suf(i)。后缀数组把s的每一个后缀按照字典序排序,后缀数组sa[i]表示排名为i的后缀的起始位置的下标。rk[i]数组代表起始位置为i的后缀的排名。rk[]和sa[]是一一对应关系......
  • C105 整体二分+树状数组 P2617 Dynamic Rankings
    视频链接:C105整体二分+树状数组P2617DynamicRankings_哔哩哔哩_bilibili  C96树状数组套权值线段树P2617DynamicRankings-董晓-博客园(cnblogs.com)C104【模板】整体二分+树状数组P3834可持久化线段树2-董晓-博客园(cnblogs.com)LuoguP2617Dynamic......
  • HashMap的数组最大容量为什么要设计为2的30次方?而不是2的31次方-1?数组容量为什么一定
    目录问题 数组容量为什么一定要设计为2的幂(2的n次方)?1、首先要清楚HashMap的底层基本原理2、再来看下怎么通过hash值决定存放在哪个桶中?首先看下hash值再看下怎么确定当前key存放在哪个数组下标下的为什么要做按位与而不用模运算符%?为什么要n-1呢?n是一个什么样的数......
  • 数据结构(五)——二叉树的遍历和线索二叉树
    5.3.二叉树的遍历和线索二叉树5.3.1_1二叉树的先中后序遍历遍历:按照某种次序把所有结点都访问一遍二叉树的递归特性:        ①要么是个空二叉树        ②要么就是由“根节点+左子树+右子树”组成的二叉树先序遍历:根左右(NLR)中序遍历:左根右(LNR)后序遍......