面向对象的JavaScript - "this"关键字和访问对象内部函数

4

我第一次尝试使用面向对象的JavaScript编程。以下是我目前的代码:

var myObj = {
1   site_url: window.location.protocol + "//" + window.location.hostname + "/",
2   site_host: window.location.hostname,
3   site_brand: this.readCookie('aCookieName'),
4   site_full_url: this.site_url + window.location.pathname,
5   /***
6   Read a cookie by its name;
7   **/
8
9   readCookie: function(name) {
10      var nameEQ = name + "=";
11      var ca = document.cookie.split(';');
12      for(var i=0;i < ca.length;i++) {
13          var c = ca[i];
14          while (c.charAt(0) == ' ') c = c.substring(1, c.length);
15          if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
16      }
17      return null;
18  },
19
20  /***
20  ***/
22  SaySomeThing: function() {
23      alert(this.site_brand);
24  }
}

请您耐心等待,我是一名新手。我遇到的问题是:

第3行 - 我遇到了一个错误:readCookie未定义;
第4行 - 另外一个错误:site_url未定义;

请帮我解决以上问题。


我非常喜欢“面向对象的JavaScript”这个术语。 - David
@David:是的,有点啰嗦,不是吗? - Martijn
1
随着使用 JavaScript 的深入,您可能会发现自己会放弃部分“面向对象”的意图。您很可能会感到沮丧,因为没有一种单一的方法可以完成您想要做的事情。因此,在 Stack Overflow 上搜索其他人询问有关面向对象 JavaScript 的问题,并注意它们用于将函数添加到对象中的模式。我建议的一件事是,如果您正在使用一次性类/单例,请查看揭示模块模式:http://www.wait-till-i.com/2007/08/22/again-with-the-module-pattern-reveal-something-to-the-world/ - pc1oad1etter
5个回答

4
在JavaScript中,对象没有“this”的概念。
在一个函数中,“this”关键字的值是由该函数的调用方式决定的。
例如,在您的“myObj”中,如果您执行以下操作:
myObj.readCookie('someName');

然后在readCookie函数内部,this将被设置为myObj

如果您想让site_brand调用readCookie函数,则应该给site_brand自己的函数来调用它:

site_brand: function() { return this.readCookie('aCookieName'); },

...然后像这样调用:

myObj.site_brand()

...因此,在site_brand函数内部,this是对myObj的引用。


编辑:问题中的代码有点变化(我想是由于格式)。

答案是相同的,但我只想指出,在SaySomeThing函数中调用this.site_brand是可以的,只要SaySomeThing是从myObj中调用的。

 // this is fine
SaySomeThing: function() {
   alert(this.site_brand);
}

 // as long as you're calling it something like
myObj.SaySomeThing();

非常感谢,今天我学到了新东西。那么现在我可以将myObj.site_brand()的输出分配给一个变量,例如site_cookie: myObj.site_brand 或 site_cookie: this.site_brand吗? - lshettyl
@LShetty:是的,只要它调用的readCookie()方法返回了某些东西,那么site_brand()将返回相同的值,所以您只需要这样做var result=myObj.site_brand();(目前看起来readCookie只返回null。) - user113716
我看到你更新了评论。记住你只能在函数内部使用this。如果你想向myObj添加一个属性,那么在site_brand函数内部,可以这样做:this.siteCookie = this.readCookie('aCookieName')。这将向myObj添加一个siteCookie属性(如果它不存在),并将其赋值为从readCookie返回的结果。 - user113716

0

尝试将您的 site_ 属性包装在函数中:

site_brand: function() { return this.readCookie('aCookieName'); }

0
问题在于this不是你想象中的那样。它将具有周围范围内this值的价值。除了其他用户发布的内容之外,如果您希望利用ECMAScript 5,可以使用新的getter语法。
get site_brand() {
    return this.readCookie('aCookieName');
}

这将允许您在不使用括号的情况下使用该属性。

obj.site_brand // Call the getter.

0

避免使用this。除非是在非常特殊的情况下,你通常不需要它。以下是我匆忙写的代码:

var myObj = (function {
    /***
    Read a cookie by its name;
    ***/
    var readCookie = function(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for(var i=0;i < ca.length;i++) {
          var c = ca[i];
          while (c.charAt(0) == ' ') c = c.substring(1, c.length);
          if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
        }
        return null;
    };
    var saySomeThing = function() {
        alert(this.site_brand);
    };

    var result = {
        site_url: window.location.protocol + "//" + window.location.hostname + "/",
        site_host: window.location.hostname
        site_brand: readCookie('aCookieName'),
        site_full_url: null, // you can't access other parts of the same object in an object literal
        saySomeThing: saySomeThing
    };
    result.site_full_url = result.site_url + window.location.pathname;

    return result;
})();

假设您不需要从myObj对象外部使用readCookie函数,并且您确实希望从对象外部访问saySomeThing

通过将整个定义包装在立即执行的匿名函数中,您可以将“readCookie”和“saySomeThing”函数隐藏起来,除了新创建的对象之外,其他人都无法访问。

我强烈建议您阅读Douglas Crockford。 :-)


0
根据上面的语法高亮显示,您似乎已经注释掉了您的readCookie方法。这是您实际代码的样子吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接