隐式的函数参数 this 和 arguments

680 阅读3分钟

隐式的函数参数 this 和 arguments


隐式的函数参数 thisarguments。两者会被静默地传递给函数,并且可以像函数体内显式声明的参数一样被正常访问。

参数 this 表示被调用函数的上下文对象,而 arguments 参数表示函数调用过程中传递的所有参数

这两个参数在 JavaScript 代码中至关重要。参数 this 是 JavaScript 面向对象编程的基本要素之一,通过 arguments 参数我们可以访问函数调用过程中传递的实际参数。


arguments 参数

arguments 参数是传递给函数的所有参数集合。无论是否有明确定义对应的形参,通过它我们都可以访问到函数的所有参数。

借此可以实现原生 JavaScript 并不支持的函数重载特性,而且可以实现接收参数数量可变的可变函数。其实,借助剩余参数(rest parameter),对 arguments 参数的需求已经大大减少了。

尽管如此,理解 arguments 参数的工作原理依然很重要,因为在处理旧代码的时候势必还会涉及。

arguments 对象有一个名为 length 的属性,表示实参的确切个数。

我们要跳出思维定势,避免把 arguments 参数当作_数组_。你可能会被它的用法误导,毕竟它有length属性,而且可以通过数组下标的方式访问到每一个元素。

但它并非 JavaScript 数组,如果你尝试在 arguments 对象上使用数组的方法,会发现最终会报错

arguments 对象仅是一个类数组的结构,在使用中要尤为注意。

将 arguments 对象作为函数参数的别名使用时会影响代码的可读性,因此在JavaScript 提供的严格模式(strict mode)中将无法再使用它

//使用arguments获取实参
function sum(){
    var sum = 0;
    for(var i = 0; i < arguments.length; i++){
        sum += arguments[i];
    }
    return sum;
}

sum(1, 2, 3); //6
sum(1, 2, 3, 4); //10
//严格模式下改变arguments
function getSamurai(samurai){
    "use strict"
    arguments[0] = "Ishida";
    return samurai;
}
function getNinja(ninja){
    arguments[0] = "Fuma";
    return ninja;
}

var samurai = getSamurai("Toyotomi"); //Toyotomi
var ninja = getNinja("Yoshi"); //Fuma

this 参数

this 表示函数上下文,即与函数调用相关联的对象。函数的定义方式和调用方式决定了 this 的取值。

当调用函数时,除了显式提供的参数外,this 参数也会默认地传递给函数。this 参数是面向对象 JavaScript 编程的一个重要组成部分,代表函数调用相关联的对象。因此,通常称之为函数上下文

函数上下文是来自面向对象语言(如 Java)的一个概念。在这些语言中,this 通常指向定义当前方法的类的实例

但是要小心!正如接下来要提到的,在 JavaScript 中,将一个函数作为方法(method)调用仅仅是函数调用的一种方式。

事实上,this 参数的指向不仅是由定义函数的方式和位置决定的,同时还严重受到函数调用方式的影响。真正理解 this 参数是面向对象JavaScript 编程的基础。

  • 函数的调用方式影响 this 的取值。

    • 如果作为函数调用,在非严格模式下,this 指向全局 window 对象;在严格模式下,this 指向 undefined。

    • 作为方法调用,this 通常指向调用的对象。

    • 作为构造函数调用,this 指向新创建的对象。

    • 通过 callapply 调用,this 指向 call 或 apply 的第一个参数

  • 箭头函数没有单独的 this 值,this 在箭头函数创建时确定。

  • 所有函数均可使用 bind 方法,创建新函数,并绑定到 bind 方法传入的参数上。被绑定的函数与原始函数具有一致的行为。

//严格模式下,函数调用this指向
function whoAmI1(){
    "use strict";
    return this;
}
function whoAmI2(){
    return this;
}
whoAmI1(); //underfind
whoAmI2(); //window
function Ninja(){
    this.whoAmI = () => this;
}
var ninja1 = {
    whoAmI: function(){
        return this;
    }
};

var ninja2 = new Ninja();
var ninja3 = {
    whoAmI: ninja2.whoAmI
};

ninja1.whoAmI(); //ninja1
ninja2.whoAmI(); //ninja2
ninja2.whoAmI(); //ninja2

小结

最后,让我们一起加油吧!

gg.jpg

都看到这了,不如顺手点个赞再走 ( *ˇωˇ* )