我正在尝试为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
语法?
答案 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
构造函数中,您可以定义私有变量,例如userAgent
,cookie
。要为reddit
对象实例定义公共属性,必须在构造函数中继续这样做:
this.debug = false;
有关更多信息,请参阅this Douglas Crockford article。