菜单

JavaScript深入之类数组对象及arguments

2018年11月15日 - JavaScript

JavaScript 深入之类数组对象以及 arguments

2017/05/27 · JavaScript
· arguments

原稿出处: 冴羽   

业已去简书,原因参见
http://www.jianshu.com/p/0f12350a6b66。

接近数组对象

所谓的类数组对象:

具一个 length 属性和若干索引属性的靶子

举个例:

var array = [‘name’, ‘age’, ‘sex’]; var arrayLike = { 0: ‘name’, 1:
‘age’, 2: ‘sex’, length: 3 }

1
2
3
4
5
6
7
8
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’;

1
2
3
4
5
console.log(array[0]); // name
console.log(arrayLike[0]); // name
 
array[0] = ‘new name’;
arrayLike[0] = ‘new name’;

章可当本人的 Github
https://github.com/mqyqingfeng/Blog
查看

长度

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

1
2
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++) { …… }

1
2
3
4
5
6
for(var i = 0, len = array.length; i  len; i++) {
   ……
}
for(var i = 0, len = arrayLike.length; i  len; i++) {
    ……
}

大凡休是坏像?

这就是说类数组对象好行使频繁组的章程呢?比如:

arrayLike.push(‘4’);

1
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”]

1
2
3
4
5
6
7
8
9
10
11
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. apply Array.prototype.concat.apply([], arrayLike)

1
2
3
4
5
6
7
8
9
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. apply
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’)

1
2
3
4
5
function foo(name, age, sex) {
    console.log(arguments);
}
 
foo(‘name’, ‘age’, ‘sex’)

打印结果如下:

图片 1

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

length属性

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

function foo(b, c, d){ console.log(“实参的长短也:” + arguments.length)
} console.log(“形参的长度为:” + foo.length) foo(1) // 形参的长也:3
// 实参的尺寸为:1

1
2
3
4
5
6
7
8
9
10
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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’)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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)

1
2
3
4
5
6
7
8
9
// 使用 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
5
function func(…arguments) {
    console.log(arguments); // [1, 2, 3]
}
 
func(1, 2, 3);

应用

arguments的用其实过多,在生单密密麻麻,也尽管是 JavaScript
专题系列被,我们见面在 jQuery 的 extend 实现、函数柯里化、递归等状况看见
arguments 的身形。这首文章就未具体进展了。

若假定总结这些状况吧,暂时能体悟的席卷:

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

迎接留言回复。

深刻系列

JavaScript深入系列目录地址:https://github.com/mqyqingfeng/Blog。

JavaScript深入系列预计写十五篇左右,旨在救助大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。

设若发左或无谨言慎行的地方,请务必与指正,十分谢谢。如果喜欢或者持有启发,欢迎star,对笔者为是一律栽鞭策。

  1. JavaScirpt 深入之从原型到原型链
  2. JavaScript
    深入的词法作用域和动态作用域
  3. JavaScript 深入的推行上下文栈
  4. JavaScript 深入之变量对象
  5. JavaScript 深入的图域链
  6. JavaScript 深入之从 ECMAScript 规范解读
    this
  7. JavaScript 深入的推行上下文
  8. JavaScript 深入的闭包
  9. JavaScript 深入的参数按值传递
  10. JavaScript
    深入的call和apply的套实现
  11. JavaScript 深入之bind的拟实现
  12. JavaScript 深入之new的依样画葫芦实现

    1 赞 2 收藏
    评论

图片 2

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图