简体   繁体   English

Javascript - 原型中的数组未定义?

[英]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.drawMapthis是指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.

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