I am trying to build a reddit api wrapper for node.js. I am fairly new to OO javascript and I am having an issue with assigning a value to my reddit object's properties.
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
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.
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.
You must declare cookie as this.cookie ="";
for it to be accessible as reddit.cookie
however.
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. Since this is a constructor, when called with new
its this
will reference a newly constructed object (an "instance" of the constructor).
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. 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.
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).
It just so happens that because of the closure, you can use:
console.log("cookie: " + cookie);
to resolve cookie
on the scope chain.
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
.
JavaScript doesn't really have the concept of private instance variables in the way you're trying to use them.
Only public members (explicitly set by saying this.whatever = "") can be accessed that way.
Otherwise you can still access them like any other variable by dropping the self. In front of them.
In your reddit
constructor function, you define private variables like userAgent
, cookie
. To define public properties for your reddit
object instances, you must proceed like this in your constructor function :
this.debug = false;
See this Douglas Crockford article for more informations.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.