[英]Javascript - array undefined in a prototype?
Here's my code, I'm experimenting stuff with canvas: 这是我的代码,我正在用canvas进行实验:
function Map(){
this.personnages = new Array();
}
Map.prototype.addPersonnage = function(perso) {
this.personnages.push(perso);
console.log(this.personnages);
}
Map.prototype.drawMap = function(){
console.log(this.personnages);
for(var i = 0; i < this.personnages.length; i++) {
this.personnages[i].dessinerPersonnage(context);
}
}
The thing is : the first console.log prints the array just fine, but the second one (in Map.prototype.drawMap) returns "undefined" (therefore the loop can't be executed)... I guess that functions are called in a correct order : 问题是:第一个console.log打印数组就好了,但第二个(在Map.prototype.drawMap中)返回“undefined”(因此循环无法执行)...我想这些函数被调用以正确的顺序:
var canvas = document.getElementById('main');
var ctx = canvas.getContext('2d');
var tilesetImage = new Image();
tilesetImage.src = 'img/tileset.png';
var map1 = new Map();
var player = new Personnage("img/player.png", 7, 14, DIRECTION.BAS);
map1.addPersonnage(player);
tilesetImage.onload = map1.drawMap;
I'm kinda new here, please tell me if I gave enough elements. 我在这里有点新意,请告诉我是否给了足够的元素。 Thanks in advance, any little help appreciated!
在此先感谢,任何小小的帮助表示赞赏!
tilesetImage.onload = map1.drawMap;
When map1.drawMap
is executed, this
refers to tilesetImage
, the target of the load
event. 执行
map1.drawMap
, this
是指tilesetImage
,即load
事件的目标。 If you want to keep this
referring to map1
, you can use Function.bind
: 如果你想保持
this
引用map1
,你可以使用Function.bind
:
tilesetImage.onload = map1.drawMap.bind(map1);
Or you can use a function that calls drawMap
on map1
directly. 或者您可以使用直接在
map1
上调用drawMap
的函数。
tilesetImage.onload = function () { map1.drawMap() };
For more information on this
, please see this question . 欲了解更多有关
this
,请参阅这个问题 。
When you do 当你这样做
map1.drawMap();
inside the drawMap
function, this
will refer to map1
object, which has personnages
variable. 在
drawMap
函数中, this
将引用map1
对象,它具有personnages
变量。 That is why map1.addPersonnage(player);
这就是
map1.addPersonnage(player);
works properly. 工作正常。
Now, you are simply assigning drawMap
function to tilesetImage.onload
. 现在,您只需将
drawMap
函数分配给tilesetImage.onload
。 So, when tilesetImage.onload
is invoked, this
will refer to tilesetImage
which will not have personnages
variable. 因此,当调用
tilesetImage.onload
时, this
将引用不具有personnages
变量的tilesetImage
。
That is why the second console.log
prints undefined
. 这就是第二个
console.log
打印undefined
。
To fix this problem, you should bind the map1
object to this
object like this 要解决此问题,您应该将
map1
对象绑定this
对象
tilesetImage.onload = map1.drawMap.bind(map1);
The value of this is not the instance when passing instance function as event handler 将实例函数作为事件处理程序传递时,this的值不是实例
Pass a closure or use bind 通过一个闭包或使用绑定
Its all explained in the following answer https://stackoverflow.com/a/16063711/1641941 under the this variable 这一切都在以下答案https://stackoverflow.com/a/16063711/1641941下解释了这个变量
You call the methode drawMap with help of tilesetImage which is an Image-Object that does not have got the attribute personnages, unless you define it. 你可以在tilesetImage的帮助下调用methode drawMap,它是一个没有属性personnages的Image-Object,除非你定义它。
This code might help you: 此代码可能对您有所帮助:
tilesetImage.onload = map1.drawMap.bind(map1);
Hope this helps a little bit. 希望这有点帮助。
here, take the bush function i wrote. 在这里,采取我写的丛林功能。 it works for standard arrays and associative arrays and jep it also works for Objects to add key/value pairs.
它适用于标准数组和关联数组和jep它也适用于对象添加键/值对。 also added instanceof defineproperty that checks if we have a fresh browser or an old explorer, if so it wont make every array or object you create a child.
还添加了instanceof defineproperty,用于检查我们是否有新的浏览器或旧浏览器,如果是这样,它不会使您创建子项的每个数组或对象。
// DIE BUSCHFUNKTION: OBJEKT.BUSCH FUNKTION
// Object/Array.bush() native function that adds a new
// arrayelement to the beginning of the specified.
// Included it also to work for Object Stacks key/value
// pairs and is 2x to 10x times better then default push
if(!('bush' in Object.prototype)){/****/
if((Object.defineProperty instanceof Function))
{(Object.defineProperty(Object.prototype,'bush',{ //modern
enumerable:false,configurable:true,value:function(key,value)
{if(key&&value){return this[key]=value;}
return this[this.length]=key;}}))}
else{Object.prototype.bush=function(key,value) // compatible
{if(key&&value){return this[key]=value;}
return this[this.length]=key;}}};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.