-1

我正在尝试为 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

4 回答 4

1

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

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

但是,您必须声明 cookiethis.cookie ="";才能访问它reddit.cookie

于 2013-01-15T02:35:35.077 回答
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);

在这里,self在 LHS 上引用了 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.

于 2013-01-15T03:52:39.060 回答
0

在您尝试使用它们的方式中,JavaScript 并没有真正具有私有实例变量的概念。

只有公共成员(通过 this.whatever = "" 明确设置)可以通过这种方式访问​​。

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

于 2013-01-15T02:35:56.797 回答
0

在您的reddit构造函数中,您定义私有变量,如userAgent, cookie。要为您的对象实例定义公共属性reddit,您必须在构造函数中像这样进行:

this.debug = false;

有关更多信息,请参阅这篇 Douglas Crockford 文章

于 2013-01-15T02:36:49.867 回答