将对象分配给原型
assigning object to prototype
我正在尝试将一个对象分配给一个原型,但我一直收到该对象未定义的错误消息。我正在尝试这样做
//x.prototype.y = {};
StreetEasy.prototype.neighborhoodPaths = {};
稍后在代码中我试图在另一个原型函数中访问该对象并使用
推送新数据
//x.prototype.assignData = function(z, a){
// this.y[z] = a;
//}
StreetEasy.prototype.findNeighborhoodPath = function(areaQuery, callback){
var data = {q: areaQuery, key: this.apiKey, format: this.format};
var query = qs.stringify(data);
var url = AreaSearchUrl + '?' + query;
var areaQ = areaQuery.toLowerCase();
if (this.neighborhoodPaths[areaQ]) {
callback(this.neighborhoodPaths[areaQ].path);
} else {
http.get(url, function(response){
response.setEncoding('utf8');
response.on('data', function (rData){
rData = JSON.parse(rData);
callback(rData);
rData.areas.every(function(element){
-----------error is here-> this.neighborhoodPaths[element.name.toLowerCase()].path = element.path;
});
}).on('error', function(e){
console.error('ERROR: ' + e.message + ' | ' + e.statusCode );
});
});
}
};
节点不断返回
TypeError:无法读取未定义的 属性 z。我做错了什么?
编辑更多代码:
StreetEasy.prototype.neighborhoodPaths = {};
StreetEasy.prototype.findNeighborhoodPath = function(areaQuery, callback){
var data = {q: areaQuery, key: this.apiKey, format: this.format};
var query = qs.stringify(data);
var url = AreaSearchUrl + '?' + query;
var areaQ = areaQuery.toLowerCase();
if (this.neighborhoodPaths[areaQ]) {
callback(this.neighborhoodPaths[areaQ].path);
} else {
http.get(url, function(response){
response.setEncoding('utf8');
response.on('data', function (rData){
rData = JSON.parse(rData);
callback(rData);
rData.areas.every(function(element){
-----------error is here-> this.neighborhoodPaths[element.name.toLowerCase()].path = element.path;
});
}).on('error', function(e){
console.error('ERROR: ' + e.message + ' | ' + e.statusCode );
});
});
}
};
(请参阅下面的更新,既然您已经发布了代码。)
这很可能是您调用方式的结果 assignData
。这会起作用,例如:
var obj = new x();
obj.assignData("foo", "bar");
这不会:
var obj = new x();
f = obj.assignData;
f("foo", "bar");
出于同样的原因,这不会:
callMeBack(obj.assignData, "foo", "bar");
function callMeBack(method, z, a) {
method(z, a);
}
在这两种情况下,问题是 assignData
调用中的 this
没有引用对象,而是全局对象。当您通过 属性 引用调用函数 not 时,this
被设置为全局对象(在松散模式下;在严格模式下它将是 undefined
).这是通过 属性 引用 调用它 的操作,将 this
设置为 属性 来自的对象。
更多 (在我的博客上):
更新,现在您已经发布了代码。我假设 findNeighborhoodPath
是您在原始问题中调用 assignData
的函数。
问题确实是你输了 this
,但不是上面的方式。
您传递的回调 http.get
将通过 this
引用全局对象,而不是调用 findNeighborhoodPath
的实例;同样,您传递给 Array#every
的回调将 this
引用全局对象,因为您没有告诉它做其他事情。
如果你想使用那个实例,最简单的方法是声明一个引用它的变量,然后使用这个变量:
var self = this; // <== Variable to remember `this`
http.get(url, function(response) {
response.setEncoding('utf8');
response.on('data', function(rData) {
rData = JSON.parse(rData);
callback(rData);
rData.areas.every(function(element) {
self.neighborhoodPaths[element.name.toLowerCase()].path = element.path;
// ^^^^ --- using it
});
}).on('error', function(e) {
console.error('ERROR: ' + e.message + ' | ' + e.statusCode);
});
// ...
});
或者,您可以使用 Function#bind
和 Array#every
的 thisArg
参数:
http.get(url, function(response) {
response.setEncoding('utf8');
response.on('data', function(rData) {
rData = JSON.parse(rData);
callback(rData);
rData.areas.every(function(element) {
this.neighborhoodPaths[element.name.toLowerCase()].path = element.path;
}, this); // <=== Note passing `this` as the second arg to `every`
}).on('error', function(e) {
console.error('ERROR: ' + e.message + ' | ' + e.statusCode);
});
// ...
}.bind(this)); // <=== Note the .bind(this)
在 JavaScript 的下一个版本中,ECMAScript6,我们将拥有 "fat arrow" 函数,这些函数具有 "lexical this
binding," 一个奇特的术语,意思是函数内的 this
将是在创建函数的上下文中与 this
相同。因此,一旦 V8 支持它们,并且 Node 更新为使用该版本的 V8(这两个都会很快),您将能够执行此操作(注意下面的两个 =>
):
http.get(url, (response) => {
response.setEncoding('utf8');
response.on('data', function(rData) {
rData = JSON.parse(rData);
callback(rData);
rData.areas.every((element) => {
this.neighborhoodPaths[element.name.toLowerCase()].path = element.path;
});
}).on('error', function(e) {
console.error('ERROR: ' + e.message + ' | ' + e.statusCode);
});
// ...
});
我正在尝试将一个对象分配给一个原型,但我一直收到该对象未定义的错误消息。我正在尝试这样做
//x.prototype.y = {};
StreetEasy.prototype.neighborhoodPaths = {};
稍后在代码中我试图在另一个原型函数中访问该对象并使用
推送新数据//x.prototype.assignData = function(z, a){
// this.y[z] = a;
//}
StreetEasy.prototype.findNeighborhoodPath = function(areaQuery, callback){
var data = {q: areaQuery, key: this.apiKey, format: this.format};
var query = qs.stringify(data);
var url = AreaSearchUrl + '?' + query;
var areaQ = areaQuery.toLowerCase();
if (this.neighborhoodPaths[areaQ]) {
callback(this.neighborhoodPaths[areaQ].path);
} else {
http.get(url, function(response){
response.setEncoding('utf8');
response.on('data', function (rData){
rData = JSON.parse(rData);
callback(rData);
rData.areas.every(function(element){
-----------error is here-> this.neighborhoodPaths[element.name.toLowerCase()].path = element.path;
});
}).on('error', function(e){
console.error('ERROR: ' + e.message + ' | ' + e.statusCode );
});
});
}
};
节点不断返回
TypeError:无法读取未定义的 属性 z。我做错了什么?
编辑更多代码:
StreetEasy.prototype.neighborhoodPaths = {};
StreetEasy.prototype.findNeighborhoodPath = function(areaQuery, callback){
var data = {q: areaQuery, key: this.apiKey, format: this.format};
var query = qs.stringify(data);
var url = AreaSearchUrl + '?' + query;
var areaQ = areaQuery.toLowerCase();
if (this.neighborhoodPaths[areaQ]) {
callback(this.neighborhoodPaths[areaQ].path);
} else {
http.get(url, function(response){
response.setEncoding('utf8');
response.on('data', function (rData){
rData = JSON.parse(rData);
callback(rData);
rData.areas.every(function(element){
-----------error is here-> this.neighborhoodPaths[element.name.toLowerCase()].path = element.path;
});
}).on('error', function(e){
console.error('ERROR: ' + e.message + ' | ' + e.statusCode );
});
});
}
};
(请参阅下面的更新,既然您已经发布了代码。)
这很可能是您调用方式的结果 assignData
。这会起作用,例如:
var obj = new x();
obj.assignData("foo", "bar");
这不会:
var obj = new x();
f = obj.assignData;
f("foo", "bar");
出于同样的原因,这不会:
callMeBack(obj.assignData, "foo", "bar");
function callMeBack(method, z, a) {
method(z, a);
}
在这两种情况下,问题是 assignData
调用中的 this
没有引用对象,而是全局对象。当您通过 属性 引用调用函数 not 时,this
被设置为全局对象(在松散模式下;在严格模式下它将是 undefined
).这是通过 属性 引用 调用它 的操作,将 this
设置为 属性 来自的对象。
更多 (在我的博客上):
更新,现在您已经发布了代码。我假设 findNeighborhoodPath
是您在原始问题中调用 assignData
的函数。
问题确实是你输了 this
,但不是上面的方式。
您传递的回调 http.get
将通过 this
引用全局对象,而不是调用 findNeighborhoodPath
的实例;同样,您传递给 Array#every
的回调将 this
引用全局对象,因为您没有告诉它做其他事情。
如果你想使用那个实例,最简单的方法是声明一个引用它的变量,然后使用这个变量:
var self = this; // <== Variable to remember `this`
http.get(url, function(response) {
response.setEncoding('utf8');
response.on('data', function(rData) {
rData = JSON.parse(rData);
callback(rData);
rData.areas.every(function(element) {
self.neighborhoodPaths[element.name.toLowerCase()].path = element.path;
// ^^^^ --- using it
});
}).on('error', function(e) {
console.error('ERROR: ' + e.message + ' | ' + e.statusCode);
});
// ...
});
或者,您可以使用 Function#bind
和 Array#every
的 thisArg
参数:
http.get(url, function(response) {
response.setEncoding('utf8');
response.on('data', function(rData) {
rData = JSON.parse(rData);
callback(rData);
rData.areas.every(function(element) {
this.neighborhoodPaths[element.name.toLowerCase()].path = element.path;
}, this); // <=== Note passing `this` as the second arg to `every`
}).on('error', function(e) {
console.error('ERROR: ' + e.message + ' | ' + e.statusCode);
});
// ...
}.bind(this)); // <=== Note the .bind(this)
在 JavaScript 的下一个版本中,ECMAScript6,我们将拥有 "fat arrow" 函数,这些函数具有 "lexical this
binding," 一个奇特的术语,意思是函数内的 this
将是在创建函数的上下文中与 this
相同。因此,一旦 V8 支持它们,并且 Node 更新为使用该版本的 V8(这两个都会很快),您将能够执行此操作(注意下面的两个 =>
):
http.get(url, (response) => {
response.setEncoding('utf8');
response.on('data', function(rData) {
rData = JSON.parse(rData);
callback(rData);
rData.areas.every((element) => {
this.neighborhoodPaths[element.name.toLowerCase()].path = element.path;
});
}).on('error', function(e) {
console.error('ERROR: ' + e.message + ' | ' + e.statusCode);
});
// ...
});