Javascript对象属性未定义

时间:2013-01-15 02:24:45

标签: javascript node.js

我正在尝试为node.js构建一个reddit api包装器。我对OO javascript相当新,我在为reddit对象的属性赋值时遇到问题。

var request = require("request");
var subreddit = require("./subreddit").subreddit;

var reddit = function () {

  var self = this,
      userAgent = "node.js api wrapper - https://github.com/theyshookhands/rednode",
      debug = false,
      cookie = "",
      uh = "";  

  self.getJSON = function (url, data, callback) {
    data["api_type"] = "json";
    request(url, { qs: data }, function (error, response, body) {
      if (!error && response.statusCode == 200) {
        callback(body);
      }
    });
  };

  self.post = function (url, data, callback) {
    console.log("in post");
    console.log("cookie: " + self.cookie);
    console.log("uh: " + self.uh);
    data["api_type"] = "json";
    if (self.cookie) {
      request.cookie(self.cookie);
      console.log("cookie assigned");
    }
    if (self.uh) {
      data["uh"] = self.uh;
      console.log("uh assigned");
    }
    console.log("requesting");
    request.post(url, { form: data }, function (error, response, body) {
      if (!error && response.statusCode == 200) {
        console.log("no errors");
        callback(body);
      }
    });
  };

};

reddit.prototype = {

  login: function (username, password, callback) {
    var data = {
      "user": username,
      "passwd": password,
      "rem": false
    };

    this.post("http://www.reddit.com/api/login", data, function (body) {
      var response = JSON.parse(body);
      this.uh = response["json"]["data"]["modhash"];
      this.cookie = response.json.data.cookie;
      console.log("rednode --> logged in as: " + username);
      callback();
    });
  },

  setUserAgent: function (userAgent) {
    this.userAgent = userAgent;
  },

  r: function (name, callback) {
    var sr = new subreddit(name);
    if (callback) {
      sr.exec(callback);
    }
    return sr;
  },

  postLink: function (sr, title, url, callback) {
    var data = {
      "kind": "link",
      "sr": sr,
      "title": title,
      "url": url
    };
    console.log("calling post");
    this.post("http://www.reddit.com/api/submit", data, callback);
  }
}

exports.reddit = reddit;

对象在第15和16行定义。它们在第62和63行给出值。为什么我没有使用

来达到这些值
this.cookie, this.modhash

语法?

4 个答案:

答案 0 :(得分:1)

当您使用关键字this来引用您在“对象”上定义的属性时,它们必须位于函数/对象的相同范围内。

您错误地使用this关键字来引用函数/对象变量/属性,该函数/对象变量/属性实际上将在未命名的回调函数范围内调用reddit.cookie

您必须将Cookie声明为this.cookie ="";才能将其作为reddit.cookie访问。

答案 1 :(得分:1)

在功能中:

var reddit = function () {

为什么要使用一个函数表达式来进行函数声明,并且可能更清晰?按惯例,构造函数以大写字母开头:

function Reddit() {

在功能中:

  var self = this,

函数this的值完全取决于函数的调用方式。由于这是一个构造函数,当使用new调用时,this将引用一个新构造的对象(构造函数的“实例”)。

  var self = this,
      userAgent = "...",
      debug = false,
      cookie = "",

以上在本地执行对象的变量对象上创建变量。您只能按名称访问变量,它们在执行对象的作用域链上解析,以全局对象结束。

...
self.post = function (url, data, callback) {
    console.log("in post");
    console.log("cookie: " + self.cookie);

这里,LHS上的self引用了Reddit实例。在RHS上,函数表达式具有对外部作用域的闭包,因此其self也引用相同的实例,因此您在对象及其cookie链上查找[[Prototype]]属性。

但是您将cookie声明为构造函数的局部变量,因此标识符正在沿着错误的链解析(即您应该在作用域链上查找变量,而不是对象上的属性/ [[Prototype]]链)。

恰好因为关闭,你可以使用:

    console.log("cookie: " + cookie);

解决范围链上的cookie

但似乎你真的想要把它作为一个属性来访问,所以首先要把它作为一个公共财产:

  var self = this,
      userAgent = "...",
      debug = false;

  this.cookie = "", // or self.cookie = '',
  ...

现在您可以使用self.cookie

答案 2 :(得分:0)

JavaScript并没有像您尝试使用它们那样拥有私有实例变量的概念。

只有公共成员(通过说明.whatever =“”明确设置)才能以这种方式访问​​。

否则你仍然可以通过删除self来访问它们,就像任何其他变量一样。在他们面前。

答案 3 :(得分:0)

reddit构造函数中,您可以定义私有变量,例如userAgentcookie。要为reddit对象实例定义公共属性,必须在构造函数中继续这样做:

this.debug = false;

有关更多信息,请参阅this Douglas Crockford article