【深入JavaScript日记十一】剖析 类数组对象 和 arguments

news/2024/7/19 15:34:01 标签: javascript, js, 前端

目录

    • 前言
    • 正文内容
      • 类数组对象
        • 读写
        • 长度
        • 遍历
      • 类数组对象调用数组函数的办法
      • arguments
        • arguments 转数组
    • 总结

前言

通过这段时间的学习,我们是时候详细的认识一下 类数组对象了,因为他在我们的使用中是比较频繁的,深入掌握这个可以有效提高我们写代码的效率。

正文内容

类数组对象

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

比如这个:

javascript">    //数组
    var array = ['name', 'age', 'sex'];

    //类数组
    var Fake_array = {
        0: 'name',
        1: 'age',
        2: 'sex',
        length: 3
    }

    console.log(array)
    console.log(Fake_array)

结果
在这里插入图片描述

从前面的学习中我们知道了,之所以叫类数组,就是因为它看起来像,但类似终归是类似,不能替代,有些数组所具备的功能她它不能使用。接下来我们从读写、获取长度、遍历三个基础方面看看。

读写

javascript">    console.log(array[0])			//name
    console.log(Fake_array[0])		//name

都可以通过下标访问

长度

javascript">    //数组
    var array = ['name', 'age', 'sex'];

    //类数组
    var Fake_array = {
        0: 'name',
        1: 'age',
        2: 'sex',
        length: 3
    }

    console.log(array.length)			//3
    console.log(Fake_array.length)		//3

都可以访问长度

遍历

经过实践发现都可以使用 for 循环

javascript">for(var i = 0, len = array.length; i < len; i++) {
   ……
}
for(var i = 0, len = Fake_array .length; i < len; i++) {
    ……
}

唯一需要记住的就是 类数组对象不能调用数组的方法函数
那如果想要调用怎么办?

类数组对象调用数组函数的办法

javascript">    //类数组
    var Fake_array = {
        0: 'name',
        1: 'age',
        2: 'sex',
        length: 3
    }

    //方法一
    var A = Array.prototype.slice.call(Fake_array, 0); 

    console.log(A);
    console.log(Array.isArray(A));			//Array.isArray() 判断是否是数组

输出结果
第一种方式采用 Array.prototype.slice.call() 方法,可以将类数组转化为数组,其中 slice()为切割传入的参数。


javascript">    //类数组
    var Fake_array = {
        0: 'name',
        1: 'age',
        2: 'sex',
        length: 3
    }
    
    //方法二
    var B = Array.prototype.map.call(Fake_array, function(item){
        return item.toUpperCase();
    });

    console.log(B);
    console.log(Array.isArray(B));

结果
第二种方式采用 Array.prototype.map.call() 方法,可以将类数组转化为数组。其中 map()方法为返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组,它不会改变原来的数组。
(简单的理解就是使用了 map函数之后,原本类数组的每一个元素都会被传入一个方法函数中,返回的是一个经历过这个方法函数打磨的新数组)
在这个例子里,这个方法是 toUpperCase(),作用是将小写字母变成大写:

javascript"> function(item){
 	return item.toUpperCase();
 }

javascript">    //类数组
    var Fake_array = {
        0: 'name',
        1: 'age',
        2: 'sex',
        length: 3
    }

	//方法三
    var C = Array.prototype.splice.call(Fake_array, 0); 

    console.log(C);
    console.log(Array.isArray(C));

结果
第三种方式采用 Array.prototype.splice.call 方法,可以将类数组转化为数组。其中 splice()可以用来对 js的数组进行删除,添加,替换等操作,这里是运用了删除操作,传入要操作的对象,然后删除个数设置为 0.


javascript">    //类数组
    var Fake_array = {
        0: 'name',
        1: 'age',
        2: 'sex',
        length: 3
    }
    
	//方法四
    var D = Array.from(Fake_array); 
    
    console.log(D);
    console.log(Array.isArray(D));

第四种方式采用 ES6 语法中的 Array.from(),可以非常高效的进行转换


javascript">    //类数组
    var Fake_array = {
        0: 'name',
        1: 'age',
        2: 'sex',
        length: 3
    }

	//方法五
    var E = Array.prototype.concat.apply([], Fake_array)
    
    console.log(E);
    console.log(Array.isArray(E));

结果
第五种方式采用 Array.prototype.concat.apply([], Fake_array),其本质是使用了数组降维的操作。
这是一篇数组降维的教程

arguments

那说完了类数组,就不得不说 arguments 了,这东西在 JavaScript 中非常常见,也很好用。

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

javascript">    function f(name, age, sex) {
        console.log(arguments);
    }

    f('name', 'age', 'sex')

控制台输出:
在这里插入图片描述
我们可以清晰的看到数组的索引属性、长度,以及原型(__proto__),但是 callee 是什么嘞。
该属性是一个指针,指向拥有这个arguments对象的函数,通过它可以调用函数自身。

举例子

javascript">    function factorial(num){
        if(num<=1){
            return 1;
        }else{
            return num*factorial(num-1);
        }
    }
    
    console.log(factorial(5))

这是一段计算阶乘的代码,通过调用函数自己实现递归。


关于 arguments 还有一个注意到地方

javascript">    function foo(name, age, sex, hobbit) {

        // 正常传入的参数
        console.log(name, arguments[0]); //小A
        
        // 未传入的参数
        console.log(sex); // undefined

        //在函数里给实参赋值
        sex = '男';
        console.log(sex, arguments[2]); // 男  undefined

        //在函数里给 arguments 赋值
        arguments[3] = '打篮球';
        console.log(hobbit, arguments[3]); // undefined  打篮球

    }

    foo('小A', '20')
  • 非严格模式下】arguments 的属性可以和函数的实参共享,但是前提必须是调用函数时已经传入的参数,未传入的参数临时添加给二者的任何一个都不能共享
  • 严格模式下】不能共享

arguments 还有一个作用,就是配合 apply 传递参数

javascript">    function A() {
        B.apply(this, arguments);
    }

    function B(a, b, c) {
        console.log(a, b, c);       //1,2,3
    }

    A(1, 2, 3)

arguments 转数组

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

func(1, 2, 3);

强大的 ES6 运算符…跟玩一样就转好了

总结

类数组对象是 JavaScript 很重要的一个东西,很有必要单独拎出来学习一下。


http://www.niftyadmin.cn/n/644321.html

相关文章

【前端技术笔试排坑一】“符号间”的加法运算

目录前言正文内容总结前言 这个东西来源在于本人开学推迟了之后呢&#xff0c;寻思着在家刚好可以去找个地方实习&#xff0c;因为刚刚结束大二&#xff0c;看了下相关岗位需求&#xff0c;因为计网还没学…只能去勉强试试前端开发&#xff0c;嗯然后投简历&#xff0c;hr筛选…

MySQL里的wait_timeout

MySQL里的wait_timeout 如果你没有修改过MySQL的配置&#xff0c;缺省情况下&#xff0c;wait_timeout的初始值是28800。 wait_timeout过大有弊端&#xff0c;其体现就是MySQL里大量的SLEEP进程无法及时释放&#xff0c;拖累系统性能&#xff0c;不过也不能把这个指设置的过小&…

ca30a_demo_C++_指针和const限定符_特殊的指针E0349

/*30_C_指针和const限定符txwtech 特殊的指针 1.指向const常对象的指针 2.const指针&#xff0c;一旦指向一个对象&#xff0c;就不可以修改&#xff0c;不能指向其它的 3.指向const对象的const指针&#xff0c;//定义时必须初始化。数据不可以修改。 指针和typedef 理解复杂的…

Linux 平台PostGIS安装

1.前提条件&#xff1a; postgresql 9.6.1 已经通过源码方式安装完成并可成功运行。 2. other OS packets OS: CentOS 6.4 X64 X64: libxml2-devel 3.geos-3.6.0 http://download.osgeo.org/geos/geos-3.6.0.tar.bz2 # tar xjvf geos-3.6.0.tar.bz2 ./configure ...... ......…

【深入JavaScript日记十二】剖析继承的多种方式

目录前言正文内容原型链继承构造函数继承组合继承[常用]原型式继承寄生式继承寄生组合式继承[最高效]总结前言 在之前的学习中总能看到继承这个词&#xff0c;今天就拿出来单独学习一下 正文内容 原型链继承 //父类function Parent() {this.name 小A同学;this.age 18;}//子…

ca31a_demo_31_C++_C风格字符串c_strcpy_strcmp_strcat

/* ca31a_demo_31_C_C_txwtech风格字符串c_strcpy_strcmp_strcat C风格字符串的使用 const char *cp"some value"; 字符常量数组 C风格字符串的标准函数 永远不要忘记字符串结束符null--\0 使用strn函数处理C风格字符串 尽可能使用标准库类型string cout << &…

【深入JavaScript_笔记一_防抖与节流】

目录前言正文内容防抖非立即执行方式立即执行方式节流时间戳节流定时器节流防抖和节流的区别总结前言 在前段日子&#xff0c;在内心的逼迫下跟着众多大佬的脚步&#xff0c;磨磨蹭蹭慢慢悠悠的学完了一些原生JavaScript底层的知识。产生了很多感触&#xff0c;编程技术太多了…

最近的学习---一句话收获(备查用)(2)

1.在内核中分配大内存问题。 首先要明白内核没有义务为你分配连续的物理内存&#xff0c;因此你需要的内核中连续的物理内存就是苛刻的要求&#xff0c;既然在计算机系统抽象给用户一个连续的美丽的一维的虚拟内存&#xff0c;那么任何时候计算机都没有义务让你看到物理内存&am…