简体   繁体   English

Javascript对象属性未定义

[英]Javascript object property undefined

I am trying to build a reddit api wrapper for node.js. 我正在尝试为node.js构建一个reddit api包装器。 I am fairly new to OO javascript and I am having an issue with assigning a value to my reddit object's properties. 我对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;

The objects are defined at lines 15 and 16. They are given values at lines 62 and 63. Why am I not reaching these values using the 对象在第15和16行定义。在第62和63行给它们指定值。为什么我不能使用

this.cookie, this.modhash

syntax? 句法?

When you use the keyword this to reference properties you have defined on your "object" they have to be within the same scope of the function/object. 当您使用关键字this来引用您在“对象”上定义的属性时,它们必须在功能/对象的同一范围内。

You are incorrectly using the this keyword to reference the function/object variable/property which will actually be called reddit.cookie inside the scope of an unnamed callback function. 您错误地使用this关键字来引用函数/对象变量/属性,该函数/对象变量/属性在未命名的回调函数范围内实际上将被称为reddit.cookie

You must declare cookie as this.cookie =""; 您必须将cookie声明为this.cookie =""; for it to be accessible as reddit.cookie however. 使其可作为reddit.cookie访问。

In the function: 在函数中:

var reddit = function () {

Why use a function expression where a function declaration will do and is likely clearer? 为什么在函数声明可以使用并且可能更清晰的地方使用函数表达式? And by convention, constructors start with a capital letter: 按照约定,构造函数以大写字母开头:

function Reddit() {

In the function: 在函数中:

  var self = this,

The value of a function's this is determined entirely by how the function is called. 函数的this的值完全取决于函数的调用方式。 Since this is a constructor, when called with new its this will reference a newly constructed object (an "instance" of the constructor). 由于这是一个构造函数,当用所谓的newthis将引用一个新构造的对象(构造的一个“实例”)。

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

The above creates variables on the local execution object's variable object. 上面的代码在本地执行对象的变量对象上创建变量 You can only access variables by name, they are resolved on the scope chain of execution objects, ending with the global object. 您只能按名称访问变量,它们在执行对象的作用域链上进行解析,以全局对象结尾。

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

Here, self on the LHS references the Reddit instance. 在这里,LHS上的self引用Reddit实例。 On the RHS, the function expression has a closure to the outer scope so its self also references the same instance so you are looking for a cookie property on the object and its [[Prototype]] chain. 在RHS上,函数表达式对外部作用域具有闭包,因此其self也引用相同的实例,因此您要在对象及其[[Prototype]]链上查找cookie属性。

But you declared cookie as a local variable of the constructor, so the identifier is being resolved along the wrong chain (ie you should be looking for a variable on the scope chain, not a property on the object/ [[Prototype]] chain). 但是您将cookie声明为构造函数的局部变量,因此标识符在错误的链上被解析(即,您应该在作用域链上寻找变量,而不是object / [[Prototype]]链上的属性) 。

It just so happens that because of the closure, you can use: 碰巧由于封闭,您可以使用:

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

to resolve cookie on the scope chain. 解决作用域链上的cookie

But it seems like you really want to access it as a property, so just make it a public property in the first place: 但似乎您真的想将其作为属性来访问,因此首先要使其成为公共属性:

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

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

Now you can use self.cookie . 现在您可以使用self.cookie

JavaScript doesn't really have the concept of private instance variables in the way you're trying to use them. JavaScript实际上并没有使用私有实例变量的概念。

Only public members (explicitly set by saying this.whatever = "") can be accessed that way. 只能以这种方式访问​​公共成员(通过说this.whatever =“”明确设置)。

Otherwise you can still access them like any other variable by dropping the self. 否则,您仍然可以通过删除self来像访问其他变量一样访问它们。 In front of them. 在他们面前。

In your reddit constructor function, you define private variables like userAgent , cookie . reddit构造函数中,您可以定义私有变量,例如userAgentcookie To define public properties for your reddit object instances, you must proceed like this in your constructor function : 要为您的reddit对象实例定义公共属性,您必须在构造函数中按以下步骤进行操作:

this.debug = false;

See this Douglas Crockford article for more informations. 有关更多信息,请参见Douglas Crockford的这篇文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM