此函数甚至如何访问变量?

时间:2019-09-15 16:54:52

标签: javascript function variables global-variables

我很困惑为什么这个函数尽管没有声明要传递给函数的变量仍然可以工作。

所以我是这样开始的:

    let player1;
    let player2;
    let player;
    let showPlayerInfo;

    player1 = {
        name: 'Luis',
        health: 70,
        place: 'The Start',
        feetHair: '',
        items: 'a mobile, a watch, a 20-pound bill'
    };

    player2 = {
        name: 'Anna',
        health: 70,
        place: 'The Great Door',
        feetHair: '',
        items: 'a broom, a TV set, a 10-pound bill'
    };
    // HERE I AM DECLARING THE VARIABLE "PLAYER" INSIDE THE FUNCTION
    showPlayerInfo = function(player){ 
        console.log(`Player name is ${player.name} with health at ${player.health}.`);
        console.log(`It all starts at ${player.place}.`);
        console.log(`${player.name} has ${player.items} on them.`);
    }

    // HERE I AM CALLING THE FUNCTION DECLARING THE VARIABLE "PLAYER" TO BE USED
    player = player1;
    showPlayerInfo(player);

    // HERE I AM CALLING THE FUNCTION DECLARING THE VARIABLE "PLAYER" TO BE USED
    player = player2;
    showPlayerInfo(player);

    //IT WERKS!!!!

好的,上面的代码可以正常工作,所以我进一步走了一步,并从函数中取消声明变量“ player”,该函数仍然有效,因为我认为我正在函数调用中对变量名进行硬编码:

    // I AM NOT DECLARING THE VARIABLE "PLAYER" INSIDE THE FUNCTION
    showPlayerInfo = function(){ 
        console.log(`Player name is ${player.name} with health at ${player.health}.`);
        console.log(`It all starts at ${player.place}.`);
        console.log(`${player.name} has ${player.items} on them.`);
    }

    // Still calling function with variable "player"
    player = player1;
    showPlayerInfo(player);

    // Still calling function with variable "player"
    player = player2;
    showPlayerInfo(player);

    //IT WERKS!!!!

上面的代码仍然有效。我进一步走了一步,从函数和函数调用中完全取消声明了变量名“ player”,我什至不知道它怎么知道从哪里获取变量?这是什么魔法?下面的代码仍然有效:

    // I AM NOT DECLARING THE VARIABLE "PLAYER" INSIDE THE FUNCTION
    showPlayerInfo = function(){ 
        console.log(`Player name is ${player.name} with health at ${player.health}.`);
        console.log(`It all starts at ${player.place}.`);
        console.log(`${player.name} has ${player.items} on them.`);
    }

    // Not declaring variable "player" from the call
    player = player1;
    showPlayerInfo();

    // Not declaring variable "player" from the call
    player = player2;
    showPlayerInfo();

    //IT WERKS! BUT HOW???

最后,我做了一个实验,从函数调用中取消声明变量,但将其保留在函数本身中,并且代码返回错误(未捕获的TypeError:无法读取showPlayerInfo处未定义的属性“名称”)。什么???为什么?

    // I AM DECLARING THE VARIABLE "PLAYER" INSIDE THE FUNCTION
    showPlayerInfo = function(player){ 
        console.log(`Player name is ${player.name} with health at ${player.health}.`);
        console.log(`It all starts at ${player.place}.`);
        console.log(`${player.name} has ${player.items} on them.`);
    }

    // Not declaring variable "player" from the call
    player = player1;
    showPlayerInfo();

    // Not declaring variable "player" from the call
    player = player2;
    showPlayerInfo();

    //IT DOESNT WORK! BUT WHY???

2 个答案:

答案 0 :(得分:1)

var声明(无论出现在何处)都将在执行任何代码之前进行处理。这称为吊装。

var声明的变量的范围是其当前的执行上下文,它是封闭的函数,或者对于在任何函数之外声明的变量,是全局的。如果您重新声明一个JavaScript变量,它将不会丢失其值。

在执行分配时,将值分配给未声明的变量会隐式地将其创建为全局变量(它成为全局对象的属性)。已声明和未声明的变量之间的区别是:

  1. 已声明的变量在声明它们的执行上下文中受到约束。未声明的变量始终是全局变量。

  2. 在执行任何代码之前创建声明的变量。在执行分配给它们的代码之前,未声明的变量不存在。

  3. 声明的变量是其执行上下文(函数或全局)的不可配置属性。未声明的变量是可配置的(例如可以删除)。

由于这三个差异,声明变量失败很可能导致意外结果。因此,建议始终声明变量,而不管它们是在函数范围内还是在全局范围内。在ECMAScript 5严格模式下,将其分配给未声明的变量将引发错误。

了解更多https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var

答案 1 :(得分:0)

let player1;
let player2;
let player;
let showPlayerInfo;

您总是在最高范围内声明了播放器变量,即使用该变量:)