【问题标题】:When to use `this` when defining variables in a function在函数中定义变量时何时使用 `this`
【发布时间】:2014-01-27 13:41:41
【问题描述】:

根据我目前所读到的内容,我们可以使用一个函数在 javascript 中创建一个具有“private”/“public”成员的对象。顺带一提:

function foo(param1) {
    this.publicVar= param1;
    privateVar = "can't touch this";

    this.MC = function(){
        var ret = privateVar + ", " + this.publicVar; 
        return ret;
    };
}

当使用var f = new foo("hammer time"); 调用时,我可以使用f.publicVarf.MC(),但我无法触摸privateVar

正如您在jsbin 中看到的,一切似乎都正常。

我不明白在这种情况下使用this。 使用this.privateVar 将是未定义的,使用publicVar 而不使用this 将是未定义的。

这是一个更详细的示例:jsfiddle
有 2 个选项来创建对象,并尊重地调用它们:

function Option1(aX,aY) {
    var x,y;

    x = aX || 0;    // `||` serves as guard, in case parameters
    y = aY || 0;    // are not defined, initializes to 0;

this.toString = function() {
        var retStr =  "from Option 1: I am here: <br/>"+
        "x: " + x + "<br/>" +           // 1
        "y: " + y + "<br/>" +           // 1 
        "this.x: " + this.x + "<br/>" + // undefined
        "this.y: " + this.y + "<br/>" + // undefined
        "aX: " + aX + "<br/>" +         // 1
        "aY: " + aY ;                   // 1
        return retStr;
    };
    // `this` is returned implicitly 
}

// first has only toString() as "public" member
var first = new Option1(1,1);

问题 1
toString 内部,xy 出现在 chrome 调试器中 scope variables 中的 closure 内部,但无法通过 this 访问。

function Option2(aX,aY) {
    var x,y;

    this.x = aX || 0;
    this.y = aY || 0;

    this.toString = function() {
        var retStr =  "from Option 2: I am here: <br/>"+
        "x: " + x + "<br/>" +           // undefined
        "y: " + y + "<br/>" +           // undefined
        "this.x: " + this.x + "<br/>" + // 22
        "this.y: " + this.y + "<br/>" + // 22
        "aX: " + aX + "<br/>" +         // 22
        "aY: " + aY  ;                  // 22
        return retStr;
    };

}

// second has x,y & toString() as "public" members
var second = new Option2(22,22);

问题 2
在这个 toStringxy 内部 不要 出现在 chrome 调试器中 scope variablesclosure 内部,并且只能通过 this 访问。

我希望Option2 能够访问x,因为它会从外部函数继承它,但如果没有this,这是不可能的。

任何澄清将不胜感激。干杯。

【问题讨论】:

  • 您可以通过“特权方法”访问私有变量。(来自 Douglas Crockford)
  • 有什么问题?
  • Option1,为什么我不能用this.x,在Option2为什么我不能用x
  • 我认为这更多是 Chrome 开发工具问题(或误用),您的概念很好。

标签: javascript scope closures


【解决方案1】:

在选项 1 中(我将仅使用一个变量来制作示例)

function Option1(aX) {
    var x; //defining x variable with a certain memory adress   
    x = aX || 0; //assigning to it a value

    //in this case "this.x" doesn't exist   

}

在选项 2 中:

function Option2(aX) {
    var x;//defining x variable with a certain memory adress

    this.x = aX || 0; //defining another variable with different memory address and
                      //assign to it the value of the passing parameter


   //in this case this.x != x

}

因为这样是互相学习,如果我错了请纠正我

【讨论】:

    【解决方案2】:

    感谢 cPu1daguru,我想我现在更了解发生了什么。
    siledh:我想我会的很快就开始读那本书。

    这是一个更新的 - - > jsbin link

    最近从C#出来,习惯在函数中定义我的变量,所以在上面Option2中,xy是未定义的,是因为我已经将它们定义为私有变量.

    如果我不这样做,如果我尝试在没有this 的情况下使用它们,就会引发异常,因为变量将不存在(导致x is not defined)。

    xy 用作全局变量会隐藏问题,因为它只会说x is undefined 或回退到它的全局值,除非您理解或具有特定值,否则可能只是造成更多混乱。

    回顾:调用变量和结果:

    1. 对于函数中的“私有”变量(使用var privateVar = something; 定义)

      • 从方法内部
        • 使用privateVar 调用 -> 为您提供局部变量,如果未定义(局部或全局)则抛出错误
        • 使用this.privateVar 调用 -> 返回undefine(因为它会在对象上创建一个?)
      • privateVar 不能从方法外部访问
    2. 对于函数中的“公共”变量(使用this.publicVar = something; 定义)

      • 从方法内部
        • 使用this.publicVar 调用 -> 为您提供(如果)定义的局部变量
        • 使用publicVar 调用-> 会引发ReferenceError(除非您在函数中定义了具有该名称的私有变量,或者您有一个具有该名称的全局变量,在这种情况下,您将获得该变量。)
          注意:这非常愚蠢,但正如我的问题所证明的那样,它确实发生了。
      • publicVar 可从方法外部访问(使用对象)

    希望这可以帮助某人并为他们节省一些头发:)

    【讨论】:

      【解决方案3】:

      您绝对应该阅读 Douglas Crockford 撰写的 here 关于 Private Members in JavaScript 的内容,其中解释了 JavaScript 中的 privatepublic 变量,并将解释为什么您的函数 Option1Option2表现得如此。

      【讨论】:

      • 那篇文章很有用,但我要么在某个地方失败了,要么他最后有一些不清楚的地方。模式 -> 私人 -> 你无法联系到membername,而他将其用作varfunction??
      • @Noctis 他的意思是这些是创建private 成员的不同方式。
      猜你喜欢
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-07
      • 2018-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多