欢迎光临杨雨的个人博客站!

杨雨个人网站-杨雨个人博客-杨照佳

杨雨个人博客网站

关注互联网和搜索引擎的个人博客网站

首页 > WEB开发 > JavaScript >

JavaScriptarguments工具详解

发布时间:2016-11-23  编辑:杨雨个人博客网站   点击:   

1. 什么是 arguments

MDN 上表明:

arguments 是一个类数组工具。代表传给一个function的参数列表。

我们先用一个例子直观相识下 JavaScript 中的 arguments 长什么样子。

function printArgs() {
    console.log(arguments);
}

printArgs("A", "a", 0, { foo: "Hello, arguments" });

执行功效是:

["A", "a", 0, Object]

乍一看,功效是个数组,但并不是真正的数组,以是说 arguments 是一个类数组的工具(想相识真正数组与类数组工具的区别可以一向翻到最后)。

再看看 arguments 暗示的内容,其暗示了函数执行时传入函数的全部参数。在上面的例子中,代表了传入 printArgs 函数中的四个参数,可以别离用 arguments[0]、 arguments[1]... 来获取单个的参数。

JavaScriptarguments器材详解

2. arguments 操纵

2.1 arguments length

arguments 是个类数组工具,其包括一个 length 属性,可以用 arguments.length 来得到传入函数的参数个数。

function func() {
    console.log("The number of parameters is " + arguments.length);
}

func();
func(1, 2);
func(1, 2, 3);

执行功效如下:

The number of parameters is 0
The number of parameters is 2
The number of parameters is 3

2.2 arguments 转数组

凡是行使下面的要领来将 arguments 转换成数组:

Array.prototype.slice.call(arguments);

尚有一个更简短的写法:

[].slice.call(arguments);

在这里,只是简朴地挪用了空数组的 slice 要领,而没有从 Array 的原型层面挪用。

为什么上面两种要领可以转换呢?

起首,slice 要领获得的功效是一个数组,参数即是 arguments。究竟上,满意必然前提的工具都能被 slice 要领转换成数组。看个例子:

const obj = { 0: "A", 1: "B", length: 2 };
const result = [].slice.call(obj);
console.log(Array.isArray(result), result);

执行功效是:

true ["A", "B"]

从上面例子可以看出,前提就是: 1) 属性为 0,1,2...;2) 具有 length 属性;

其它,有一个必要留意的处所就是,不能将函数的 arguments 泄漏可能转达出去。什么意思呢?看下面的几个泄漏 arguments 的例子:

// Leaking arguments example1:
function getArgs() {
    return arguments;
}

// Leaking arguments example2:
function getArgs() {
    const args = [].slice.call(arguments);
    return args;
}

// Leaking arguments example3:
function getArgs() {
    const args = arguments;
    return function() {
        return args;
    };
}

上面的做法就直接将函数的 arguments 工具泄暴露去了,最终的功效就是 V8 引擎将会跳过优化,导致相等大的机能丧失。

你可以这么做:

function getArgs() {
    const args = new Array(arguments.length);
    for(let i = 0; i < args.length; ++i) {
        args[i] = arguments[i];
    }
    return args;
}

那就很好奇了,我们每次行使 arguments 时凡是第一步城市将其转换为数组,同时 arguments 行使不妥还轻易导致机能丧失,那么为什么不将 arguments 直接计划成数组工具呢?

这必要从这门说话的一开始提及。arguments 在说话的早期就引入了,其时的 Array 工具具有 4 个要领: toString、 join、 reverse 和 sort。arguments 担任于 Object 的很大缘故起因是不必要这四个要领。而此刻,Array 添加了许多强盛的要领,好比 forEach、map、filter 等等。那为什么此刻不在新的版本里让 arguments 从头担任自 Array呢?着实 ES5 的草案中就包括这一点,但为了向前兼容,最终照旧被委员会反对了。

2.3 修改 arguments 值

在严酷模式与非严酷模式下,修改函数参数值示意的功效纷歧样。看下面的两个例子:

function foo(a) {
    "use strict";
    console.log(a, arguments[0]);
    a = 10;
    console.log(a, arguments[0]);
    arguments[0] = 20;
    console.log(a, arguments[0]);
}
foo(1);

输出:

1 1
10 1
10 20

另一个非严酷模式的例子:

function foo(a) {
    console.log(a, arguments[0]);
    a = 10;
    console.log(a, arguments[0]);
    arguments[0] = 20;
    console.log(a, arguments[0]);
}
foo(1);

输出功效为:

1 1
10 10
20 20

从上面的两个例子中可以看出,在严酷模式下,函数中的参数与 arguments 工具没有接洽,修改一个值不会改变另一个值。而在非严酷模式下,两个会相互影响。

2.4 将参数从一个函数转达到另一个函数

下面是将参数从一个函数转达到另一个函数的保举做法。

function foo() {
    bar.apply(this, arguments);
}
function bar(a, b, c) {
    // logic
}

2.5 arguments 与重载

许多说话中都有重载,但 JavaScript 中没有。先看个例子:

function add(num1, num2) {
    console.log("Method one");
    return num1 + num2;
}

function add(num1, num2, num3) {
    console.log("Method two");
    return num1 + num2 + num3;
}

add(1, 2);
add(1, 2, 3);

执行功效为:

Method two
Method two

以是,JavaScript 中,函数并没有按照参数的差异而发生差异的挪用。

是不是 JavaScript 中就没有重载了呢?并不是,我们可以操作 arguments 模仿重载。照旧上面的例子。

function add(num1, num2, num3) {
    if (arguments.length === 2) {
        console.log("Result is " + (num1 + num2));
    }
    else if (arguments.length === 3) {
        console.log("Result is " + (num1 + num2 + num3));
    }
}

add(1, 2);
add(1, 2, 3)

执行功效如下:

Result is 3
Result is 6

3. ES6 中的 arguments

3.1 扩展操纵符

直接上栗子:

function func() {
    console.log(...arguments);
}

func(1, 2, 3);

执行功效是:

1 2 3

简捷地讲,扩展操纵符可以将 arguments 展开成独立的参数。

3.2 Rest 参数

照旧上栗子:

function func(firstArg, ...restArgs) {
    console.log(Array.isArray(restArgs));
    console.log(firstArg, restArgs);
}

func(1, 2, 3);

执行功效是:

true
1 [2, 3]

从上面的功效可以看出,Rest 参数暗示除了明晰指定剩下的参数荟萃,范例是 Array。

3.3 默认参数

栗子:

function func(firstArg = 0, secondArg = 1) {
    console.log(arguments[0], arguments[1]);
    console.log(firstArg, secondArg);
}

func(99);

执行功效是:

99 undefined
99 1

可见,默认参数对 arguments 没有影响,arguments 照旧仅仅暗示挪用函数时所传入的全部参数。

3.4 arguments 转数组

Array.from() 是个很是保举的要领,其可以将全部类数组工具转换成数组。

4. 数组与类数组工具

数组具有一个根基特性:索引。这是一样平常工具所没有的。

const obj = { 0: "a", 1: "b" };
const arr = [ "a", "b" ];

我们操作 obj[0]arr[0] 都能取得本身想要的数据,但取得数据的方法确实差异的。obj[0] 是操作工具的键值对存取数据,而 arr[0] 却是操作数组的索引。究竟上,Object 与 Array 的独一区别就是 Object 的属性是 string,而 Array 的索引是 number。

下面看看类数组工具。

伪数组的特征就是长得像数组,包括一组数据以及拥有一个 length 属性,可是没有任何 Array 的要领。再详细的说,length 属性是个非负整数,上限是 JavaScript 中能准确表达的最大数字;其它,类数组工具的 length 值无法自动改变。

怎样本身建设一个类数组工具?

function Foo() {}
Foo.prototype = Object.create(Array.prototype);

const foo = new Foo();
foo.push('A');
console.log(foo, foo.length);
console.log("foo is an array? " + Array.isArray(foo));

执行功效是:

["A"] 1
foo is an array? false

也就是说 Foo 的示例拥有 Array 的全部要领,但范例不是 Array。

假如不必要 Array 的全部要领,只必要部门怎么办呢?

function Bar() {}
Bar.prototype.push = Array.prototype.push;

const bar = new Bar();
bar.push('A');
bar.push('B');
console.log(bar);

执行功效是:

Bar {0: "A", 1: "B", length: 2}
本文地址:http://itbyc.com/web/javascript/13032.html
转载请注明出处。
分享是一种快乐,也是一种美德:
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
博客首页 | WEB开发 | 网站运营 | CMS使用教程 滇ICP备14002061号-1