arguments和...arg相关知识点

arguments和...arg相关知识点,第1张

1.什么是类数组

类数组是指在写法上跟数组一样,比如arguments,函数的第一个参数是argument[0],写法上跟数组一样,但是不是数组,他的原型是Object。

function functionName() {

console.log(arguments);

}

functionName(3, 5)

控制台打印:

Arguments(2) [3, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]

0:3

1:5

callee:ƒ functionName()

length:2

Symbol(Symbol.iterator):ƒ values()

__proto__:Object

打印出来之后可以看到其实他的构造函数是Object,只不过这个对象的key值是0,1…写出来之后类似数组的下标,所以叫类数组。

2、 Array.prototype.slice.call

1.在JS里Array是一个类 slice是此类里的一个方法 ,那么使用此方法应该Array.prototype.slice这么去用

slice从字面上的意思很容易理解就是截取(当然你不是英肓的话) 这方法如何使用呢?

arrayObj.slice(start, [end]) 很显然是截取数组的一部分。

2.我们再看call

call([thisObj[,arg1[arg2[[argN]]]]])

thisObj是一个对象的方法

arrg1~argN是参数

那么Array.prototype.slice.call(arguments,1);这句话的意思就是说把调用方法的参数截取出来。

如:

function test(a,b,c,d)

{

var arg = Array.prototype.slice.call(arguments,1);

alert(arg);

}

test("a","b","c","d"); //b,c,d

因为arguments并不是真正的数组对象,只是与数组类似而已,所以它并没有slice这个方法,而Array.prototype.slice.call(arguments, 1)可以理解成是让arguments转换成一个数组对象,让arguments具有slice()方法。要是直接写arguments.slice(1)会报错。

3、真正原理

Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js对象与com对象不能进行转换)

如:

var a={length:2,0:'first',1:'second'};//类数组,有length属性,长度为2,第0个是first,第1个是second

console.log(Array.prototype.slice.call(a,0));// ["first", "second"],调用数组的slice(0);

var a={length:2,0:'first',1:'second'};

console.log(Array.prototype.slice.call(a,1));//["second"],调用数组的slice(1);

var a={0:'first',1:'second'};//去掉length属性,返回一个空数组

console.log(Array.prototype.slice.call(a,0));//[]

function test(){

console.log(Array.prototype.slice.call(arguments,0));//["a", "b", "c"],slice(0)

console.log(Array.prototype.slice.call(arguments,1));//["b", "c"],slice(1)

}

test("a","b","c");

补充:

将函数的实际参数转换成数组的方法

方法一:var args = Array.prototype.slice.call(arguments);

方法二:var args = [].slice.call(arguments, 0);

方法三:

var args = [];

for (var i = 1; i < arguments.length; i++) {

args.push(arguments[i]);

}

3.JavaScript Array slice() 方法
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];

var citrus = fruits.slice(1,3);

citrus 结果输出:

Orange,Lemon

定义和用法

slice() 方法可从已有的数组中返回选定的元素。

slice() 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。

注意: slice() 方法不会改变原始数组。

4、...args剩余参数⽤法

剩余参数语法允许我们将⼀个不定数量的参数表⽰为⼀个数组。

function sum(...theArgs) {

return theArgs.reduce((previous, current) => {

return previous + current;

});

}

console.log(sum(1, 2, 3));

// expected output: 6

console.log(sum(1, 2, 3, 4));

// expected output: 10

语法

function(a, b, ...theArgs) {

// ...

}

描述

如果函数的最后⼀个命名参数以

为前缀,则它将成为⼀个数组,其中从

(包括)到

(排除)的元素由传递给函数的实际参数

...

0

theArgs.length

提供。

在上⾯的例⼦中,

将收集该函数的第三个参数(因为第⼀个参数被映射到

,⽽第⼆个参数映射到

)和所有后续参数。

theArgs

a

b

剩余参数和

对象的区别

arguments

剩余参数和对象之间的区别主要有三个:

剩余参数只包含那些没有对应形参的实参,⽽

对象包含了传给函数的所有实参。

arguments

对象不是⼀个真正的数组,⽽剩余参数是真正的实例,也就是说你能够在它上⾯直接使⽤所有的数组⽅法,⽐如,,或。

arguments

对象还有⼀些附加的属性(如

属性)。

arguments

callee

从 arguments 到数组

引⼊了剩余参数来减少由参数引起的样板代码。

// Before rest parameters, the following could be found:

function f(a, b) {

var args = Array.prototype.slice.call(arguments, f.length);

// …

}

// to be equivalent of

function f(a, b, ...args) {

}

解构剩余参数

剩余参数可以被解构,这意味着他们的数据可以被解包到不同的变量中。请参阅。

function f(...[a, b, c]) {

return a + b + c;

}

f(1) // NaN (b and c are undefined)

f(1, 2, 3) // 6

f(1, 2, 3, 4) // 6 (the fourth parameter is not destructured)

⽰例

因为

是个数组,所以你可以使⽤

属性得到剩余参数的个数:

theArgs

length

function fun1(...theArgs) {

alert(theArgs.length);

}

fun1(); // d出 "0", 因为theArgs没有元素

fun1(5); // d出 "1", 因为theArgs只有⼀个元素

fun1(5, 6, 7); // d出 "3", 因为theArgs有三个元素

下例中,剩余参数包含了从第⼆个到最后的所有实参,然后⽤第⼀个实参依次乘以它们:

function multiply(multiplier, ...theArgs) {

return theArgs.map(function (element) {

return multiplier * element;

});

}

var arr = multiply(2, 1, 2, 3);

console.log(arr); // [2, 4, 6]

下例演⽰了你可以在剩余参数上使⽤任意的数组⽅法,⽽

对象不可以:

arguments

function sortRestArgs(...theArgs) {

var sortedArgs = theArgs.sort();

return sortedArgs;

}

alert(sortRestArgs(5,3,7,1)); // d出 1,3,5,7

function sortArguments() {

var sortedArgs = arguments.sort();

return sortedArgs; // 不会执⾏到这⾥

}

alert(sortArguments(5,3,7,1)); // 抛出TypeError异常:arguments.sort is not a function

为了在

对象上使⽤

⽅法,它必须⾸先被转换为⼀个真正的数组。

arguments

Array

function sortArguments() {

var args = Array.prototype.slice.call(arguments);

var sortedArgs = args.sort();

return sortedArgs;

}

console.log(sortArguments(5, 3, 7, 1)); // shows 1, 3, 5, 7

6.JavaScript 中 call()、apply()、bind() 的用法

其实是一个很简单的东西,认真看十分钟就从一脸懵B 到完全 理解!

先看明白下面:

例 1

obj.objAge; // 17

obj.myFun() // 小张年龄 undefined

例 2

shows() // 盲僧 

比较一下这两者 this 的差别,第一个打印里面的 this 指向 obj,第二个全局声明的 shows() 函数 this 是 window ;

1,call()、apply()、bind() 都是用来重定义 this 这个对象的!

如:

obj.myFun.call(db);    // 德玛年龄 99

obj.myFun.apply(db);    // 德玛年龄 99

obj.myFun.bind(db)();   // 德玛年龄 99

以上出了 bind 方法后面多了个 () 外 ,结果返回都一致!

由此得出结论,bind 返回的是一个新的函数,你必须调用它才会被执行。

2,对比call 、bind 、 apply 传参情况下

 

obj.myFun.call(db,'成都','上海');     // 德玛 年龄 99 来自 成都去往上海

obj.myFun.apply(db,['成都','上海']); // 德玛 年龄 99 来自 成都去往上海

obj.myFun.bind(db,'成都','上海')(); // 德玛 年龄 99 来自 成都去往上海

obj.myFun.bind(db,['成都','上海'])();   // 德玛 年龄 99 来自 成都, 上海去往 undefined  

微妙的差距!

从上面四个结果不难看出:

call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了:

call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,'成都', ... ,'string' )。

apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,['成都', ..., 'string' ])。

bind 除了返回是函数以外,它 的参数和 call 一样。

当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!

参考:

Array.prototype.slice.call()方法详解 - 简书

...args剩余参数用法 - 百度文库

JavaScript 中 call()、apply()、bind() 的用法 | 菜鸟教程

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/945443.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-18
下一篇 2022-05-18

发表评论

登录后才能评论

评论列表(0条)

保存