ugrás a tartalomhoz

Firefox core javascript bug: instanceof,isPrototypeOf

inf · 2007. Május. 31. (Cs), 04.18
van az alábbi kód, ami igazából bmilyen faszerkezetre modelt illeszt. szal DOM,FileSystem stb szépen kirajzoltatható vele, de csak IE alatt, firefox szórja rá a szebbnél szebb bugokat, ott kezdődik, hogy instanceof nem működik rendesen(azt alerteztem ki), false értéket ad vissza ott, ahol truet kéne, ha átugroljuk azt a részt, akkor meg ezer másik hibát ad ki.

próbáltam prototypeokkal trükközni az egyes elemtípusoknál, és jól be is szoptam, mert gyanús, hogy core javascript bug van a firefoxban.

jah a kérdés :D meg tudja ezt nekem valaki olyanra csinálni, hogy ne legyen bugos? :D mert én már feladtam, írtam jelentést a bugról, azt jegeltem a projectet
Object.extend=function (o,e){if (o instanceof Object && e instanceof Object) for (var i in e) o[i]=e[i]; return o}
Function.prototype.parameters=function (){for (var i=0,a=[]; i<this.arguments.length; i++) a[i]=this.arguments[i];return a;}
Object.toString=function (o){var s=[];for (var i in o) s.push(i+" => "+o[i]);return s.join(", ");}
String.construct=function (times,iterator){var s="";for (i=0; i<times; i++) s+=iterator;return s}
Function.prototype.write=function (o){this.prototype=o; return this}
Function.prototype.extend=function (e){Object.extend(this.prototype,e); return this}
Object.merge=function (o,e){if (typeof o=="object" && typeof e=="object") for (var i in e) if (!(i in o)) o[i]=e[i]; return o}


function Model()
{
 var nodeTypes={};

 var prototype=
 {
  model: this,
  addChild: function ()
  {
   if (!this.hasChildren) return false;
   var parameters=arguments.callee.parameters(),type=parameters.shift();
   type=type instanceof Type?type:nodeTypes[type];
   if (!(type instanceof Type)) return false;
   this.childNodes.push(new type.setup(type,parameters,this));
   return this.childNodes[this.childNodes.length-1];
  },
  removeChild: function ()
  {

  }
 }


 function Type(key,addon,initialize)
 {
  this.key=key;
  this.prototype=Object.merge(addon,prototype);
  this.initialize=initialize;
  this.setup=function (type,parameters,parent)
  {
   this.nodeType=type;
   this.parentNode=parent;
   this.level=this.parentNode.level+1;
   if (this.hasChildren) this.childNodes=[];
   if (typeof initialize=="function") initialize.apply(this,parameters);
   return this
  }
  this.setup.prototype=addon;
 }


 var setup=function()
 {
  var parameters=arguments.callee.parameters();
  if (this.hasChildren) this.childNodes=[];
  this.level=1;
  alert(Object.toString(this.constructor.prototype))
  if (typeof this.nodeType.initialize=="function") this.nodeType.initialize.apply(this,parameters);
  return this;
 }

 Object.extend(setup,
 {
  addType: function (key,addon,initialize){nodeTypes[key]=new Type(key,addon,initialize)},
  removeType: function (key){delete nodeTypes[key]},
  rootType: function (key){key=key instanceof Type?key:nodeTypes[key]; if (!(key instanceof Type)) return false;this.prototype=key.prototype;this.prototype.nodeType=key;}
 });

 return setup;
}

var FileSystemObject=new Model()
with (FileSystemObject)
{
 addType("root",{hasChildren: true,print: function (){var s="OBJECT TREE<br \/>"+this.name+"<br \/>";for (var i=0; i<this.childNodes.length; i++)s+="&nbsp;"+this.childNodes[i].print();return s}},function (name){this.name=name});
 rootType("root");
 addType("folder",{hasChildren: true,print: function (){var s=this.name+"<br \/>";for (var i=0; i<this.childNodes.length; i++)s+=String.construct(this.level,"&nbsp;")+this.childNodes[i].print();return s}},function (name){this.name=name});
 addType("file",{hasChildren: false,print: function (){return this.name+"<br \/>"}},function (name){this.name=name});
}

var FSO=new FileSystemObject("root");
 var alap=FSO.addChild("folder","alap");
  var mely=alap.addChild("folder","mély");
   mely.addChild("file","mély gyerek");
   mely.addChild("file","mély lány");
  var deep=alap.addChild("folder","deep");
   deep.addChild("file","deep girl");
 var ground=FSO.addChild("folder","ground");
  ground.addChild("file","ground girl");
 FSO.addChild("file","settings");
document.write(FSO.print())

var FSO2=new FileSystemObject("root2");
document.write(FSO2.print())
 
1

téma

inf · 2007. Május. 31. (Cs), 04.29
közben sikerült megoldani, kiderült, hogy átugorva mégsem ad hibát a dolog, szal nincs para
viszont az instanceoffal elég komoly bug van ffben. ha megnézem az object konstruktorát, akkor jót ad, de ha instanceoffal kérdezek rá, vagy prototypeoffal, akkor viszont nem. szóval nem értem mi baja, kitöröltem azt a részletet, meg jelentettem a firefoxnál a hibát
2

érdekel

Fraki · 2007. Május. 31. (Cs), 04.33
Szia!

Engem iszonyatosan érdekel ez a dolog, és konyítanék is némileg a js-hez, de amit írsz, abból sajnos nem sokat értek. (Ha a hibajelentésed is így néz ki, kétlem, hogy bárki rá fog nézni.)

Nem tudnál - lehetőleg max 10 soros - mindtakódot mutatni, ami másképp viselkedik ff-ben, mint ie-ben és operában?

Megköszönném,
fraki
3

Tessék

inf · 2007. Május. 31. (Cs), 09.41
Itt a lényege, parancsolj. Ezeknek az együttállása okozza a hibát...
fontos, hogy prototypenak kell elnevezni a változót, és hogy a builder átvegyen a BUGtól paramétert (azt ne kérdezd, hogy miért)

function TEST()
{
 var prototype={}

 function BUG(data)
 {
  this.builder=function ()
  {
   this.data=data;
  }
  this.builder.prototype=prototype;
 }

 this.test=function (){alert("Is it bug?\n"+!(new BUG(100) instanceof BUG))}
}

var a=new TEST()
a.test();
4

reserved keyword?

zzrek · 2007. Május. 31. (Cs), 17.01
Ez tényleg érdekes, de én arra tippelek, hogy a "prototype" szó FF-ben foglalt, és nem kell változónak használni -- mivel valószínűleg a FF teszi ezt. Tippem szerint amikor a builderben a konstruktorfüggvény lokális változójára utalsz, akkor használhatja "belsőleg" a "prototype" kulcsszót, és akkor íródik át ezek miatt az utalás az instanceofra. (vagy valami hasonló)
Végülis miben akadályoz az, ha nem használhatod a "prototype" elnevezést egy változóra?
A bugriportra nem az lesz a válasz, hogy a "prototype" reserved keyword?
6

Nem

inf · 2007. Jún. 1. (P), 20.34
Konrétan nem, megnéztem másik lefoglalt szavak listáját, azon nem volt ott a prototype. IEben érdekes mód nincs lefogllava, meg egyébként sem magyarázza a hibát, ugyanis ha mondjuk amit én data-nak neveztem el, azt kiszeded, szóval nem adsz át paramétert a függvénynek, akkor jól működik ff. Szóval csak ebben a speciális esetben van hiba, ha máshogy használod a prototypeot, akkor tutira műküdik. Egyébként oylan szó nem szokott lefoglalt szó lenne, ami egy objektum tulajdonsága, már bocs...
8

és ha mégis úgy veszed, mintha foglalt szó lenne?

zzrek · 2007. Jún. 1. (P), 23.23
Végülis miben akadályoz az, ha nem használhatod a "prototype" elnevezést egy változóra?
Jól látom, hogy ha máshogy nevezed el, minden rendben van? Ez nem arra utal, hogy a "prototype" szó használata nem szerencsés így vagy úgy?
(láttam ezt a "data" dolgot és írtam rá tippet is, hogy mi lehet) Előfordult már velem máskor, hogy egy reserved szót használtam, és tök odanemillő hibát generált. Ebben az esetben is a "prototype" foglalt név használata egy másik esemény együttálásakor generál hibát, ebben számomra nincs meglepő.
9

Khmm

inf · 2007. Jún. 2. (Szo), 11.44
Azt hiszem ez meddő vita, magyarázd már el nekem, hogy ebben a listában te hol látod a prototype szót? Mert én sehol.
12

Új link

attlad · 2007. Jún. 2. (Szo), 14.29
Amit linkeltél az egy 4 éves doksi, már jó ideje a developer.mozilla.org ahova járni szokás, az az aktuális. Ott megtalálható a linked aktuális verziója. A javaslatban a prototype syntactic keyword. De hogy mi a helyzet jelenleg a példáddal majd biztos kiderül a bugreportodból.
13

OK

inf · 2007. Jún. 2. (Szo), 14.48
Hmm akkor módosítok ezen az egészen, ie sokkal logikusabban kezeli a fenntartott szavakat, mint ff, mert ieben kapsz egy szép hibaüzenetet, ha fenntartott szót használsz, ffben viszont nem.
15

Remek, így tovább :)

attlad · 2007. Jún. 2. (Szo), 16.05
Reméljük a mesterek (IE team) a semmitmondó "unspecified error" hibaüzenetek javítására, a hibaüzenetek helyének pontos jelzésére és a JS motor fejlesztésére is időt tudnak majd szakítani.
16

Reméljük

inf · 2007. Jún. 2. (Szo), 16.49
Reméljük :D Azért iet nem csak szidni lehet, 1-2 dolgot értelmesebben csináltak meg, mint ffben (ha túlnyomó részét nem is..)
5

törekedj a lényegre

Marcell · 2007. Május. 31. (Cs), 18.52
Ha a hibajelentésed is így néz ki, kétlem, hogy bárki rá fog nézni.
Nemcsak a hibajelentés, hanem már a fórumhozzászólás is...

Egyrészről nem értem, hogy miért kell 5 oldalnyi kódot beilleszteni, ahelyett, hogy csak a problémára összpontosítanál pár sorban??? Én (és még sztem sokan mások is) az ilyen témákat kapásból átugrom, mert mire kibogarásznám a kódot, lemegy a nap - megjegyzem reggel 04:18-kor nem is meglepő, hogyha senki nem jön rá a megoldásra. Másrészről ez nem az első ilyen témád... A múltkori is (Firefox removeChild bug) pont ilyen volt, kilóméteres kód, majd 5 perc múlva egy "ja, megoldottam" komment - persze a megoldást már nem írtad oda, csak miután megkértek. Nem értem a logikád, meg hogy ezeknek mi értelme van...

Hogy konstruktív is legyek, talán tényleg foglalt a prototype kulcsszó: http://www.quackit.com/javascript/javascript_reserved_words.cfm
7

xxx

inf · 2007. Jún. 1. (P), 20.40
Legtöbbször úgy dolgozom, hogy megírom előre a kódot, ami kb iylen terjedelmű, mint ez itt, utána debuggolom, de mondjuk ilyen speckó hibáknál, mint ez itt, meg a removeChildos volt - amiről mondjuk sehol nem esik szó - nem sokra jutok. A múltkorinál leírtam, hogy mik a tünetek, meg hol keressétek a kódban a hibát, de hát ha egyből átugrod, és bele sem olvasol, arról nem tehetek. Másik amiért nem kezdem el jobban leszűkíteni a hibát hajnal 4kor, az az, hogy eetleg fáradt vagyok. Jah és nem egyből írtam rá a megoldást, csak másnap miután kipihentem magam, és újra ránéztem, hogy mi is lehet a gond.
Csak hogy konstruktív legyek érdekes módon az ezzel foglalkozó szakemberek komolyan veszik a kérdésem, oda is leírtam az új kódot, amit ide, és nem volt ilyen felvetésük, hogy a prototype foglalt, vagy semmi hasonló.
11

Idővel majd csak rájössz, hogy érdemes okosan kérdezni.

Marcell · 2007. Jún. 2. (Szo), 13.25
...de hát ha egyből átugrod, és bele sem olvasol, arról nem tehetek.
De igen, pontosan te tehetsz róla, mert zavarosan adod elő és nincs kedve az embernek 100 olyan sort végigolvasni, amiből a felének köze sincs a hibához. Mint a 2. hozzászólás is mutatja, nem csak én vagyok így vele, és meg merem kockáztatni, hogy még jó sokan gondolkoznak hasonlóan időhiány miatt. Nem nekem lesz rosszabb, hanem neked, mert lassabban jutsz el a megoldásig.
Másik amiért nem kezdem el jobban leszűkíteni a hibát hajnal 4kor, az az, hogy eetleg fáradt vagyok.
Talán akkor küld be a kérdést csak másnap és akkor még talán az is megeshet (mint az utóbbi 2 alkalommal), hogy már meg sem kell kérdezni, mert közben megoldódik.
Csak hogy konstruktív legyek érdekes módon az ezzel foglalkozó szakemberek komolyan veszik a kérdésem, oda is leírtam az új kódot, amit ide, és nem volt ilyen felvetésük, hogy a prototype foglalt, vagy semmi hasonló.
Nem ismerek olyan helyet, hogy "ott", másrészt nem hinném, hogy "itt" nem lennének hozzáértő szakemberek.
14

Egyszer majd csak, de hogy nem most, és nem miattad :D

inf · 2007. Jún. 2. (Szo), 15.10
Jó, tény, hogy a kérdés kicsit zavaros volt, az előző már nem ennyire. Az sem tetszett, nem lehet, hogy benned, meg a sztereotípiáidban van a hiba. Ha valaki hosszú kódot ír, az már alapból rossz, mert lusta vagy végignézni :> De mondjuk igazából nem azért írok hosszú kódot, hogy ránézésre megmondd, hogy mi a hiba, hanem azért, hogy szépen használd az ügyes kezecskéidet meg a ctrl+c-t és bemásold egy fájlba, és megnézd, hogy jé, télleg hibát ad, xedik sorban. És akkor kattintasz egyet a firefoxnál a hibakonzolban, és jé odaugrik az xedik sorra, és megnézed a hibaüzit, meg, hogy mivel kapcsolatos, és ha már láttál ilyet, akkor egyből tudod, hogy mi a gond, ha meg nem, akkor vagy lusta vagy, és nem nézed tovább, vagy esetleg nézegeted, mert érdekel.
Igazából mondjuk az alap, ami átvillan az ember agyán, ha hosszú kódot lát, az az, hogy honnan másolta a kérdező. Nah most ha így állsz ahhoz amit írok, akkor a kérdéseim nem hozzád szólnak, így nem tartok igényt a válaszaidra. (Persze tudom, hogy erről szó sem volt, csak próbálom elképzelni, hogy kb mit gondolhatsz, mert én is írok megoldásokat prog.hu-ra, és van valamennyi tapasztalatom ezzel kapcsolatban.)
17

ezt a vonalat nem kéne erőltetni

Fraki · 2007. Jún. 2. (Szo), 21.44
Ezt a vonalat nem kéne erőltetni, hosszú kódot csak nagyon indokoltan illik posztolni (magyarul úgy általában nem illik). A címben kérdőjelezd meg a bugos feltételezésed.
18

OK

inf · 2007. Jún. 2. (Szo), 21.50
Akkor úgy látszik csökkent a szociális érzékem :D
10

Nem figyeltél

inf · 2007. Jún. 2. (Szo), 11.49
A listában amit írtál az "Other JavaScript Keywords"-ben van a prototype, ami semmit nem jelent.
Prototypeja egyébként meg csak függvénynek lehet, szóval objectben, változóban nem értem miért ne lehetne ez a név.
19

ajjaj

Fraki · 2007. Jún. 2. (Szo), 21.56
Ez így nem egészen pontos. prototype-ja minden objektumnak van, és mivel JS-ben minden object (vagy primitív), ezért prototype-ja is mindennek van (a primitíveket kivéve).

Nem véletlenül szintaktikai kulcsszó a mozillás specifikációban, mivel a prototype chain elég core JS fícsör, következésképp objektummezőt ennek elnevezni elég nagy bornírtság.
21

Ez sem egészen pontos sztem :-)

inf · 2007. Jún. 2. (Szo), 23.30
Szóval konstruktora van minden objectnek, prototypeja pedig a konstruktorhoz tartozó tulajdonság. Kb úgy működhet az új object létrehozása, hogy a prototypeot lemásolja a javascript, és a kapott objecten alkalmazza a konstruktor függvényt. Nah most ha bmelyik objectet megnézel, akkor {}.prototype undefinedet ad, viszont {}.constructor.prototype már nem. Ez eddig okés. A constructort is lehet használni private változóként elméletileg. Egyik sem tiltott elméletileg, gyakorlatilag meg úgy tűnik nem ajánlott semmi olyat használni, amik benn vannak a core javascript szavai közt. A kódot módosítani fogom, mondjuk így: var _prototype={} stb..
22

Igen

Fraki · 2007. Jún. 3. (V), 10.14
Így van, ez a pontos leírás.
20

ecma 262-ben nem lefoglalt szó

Fraki · 2007. Jún. 2. (Szo), 22.01
kis adalék: ecma 262-ben nem lefoglalt szó
23

Pontosan

Pusztai Tibor · 2007. Jún. 3. (V), 12.21
Pontosan. A bug kapcsán inf3rno-nak adok igazat. Ez tényleg egy bug, mégpedig a SpiderMonkey-ban. A működése nem felel meg az
ECMAScript (3rd edition) specifikációban leírtaknak. Szerintem nem jogos arra hivatkozni, hogy az már egy több, mint 7 éves dokumentum, inkább vegyük alapul a JS 2.0 wiki oldalát (ECMAScript v4)... Az is bug lenne, ha a böngésző hibásan kezelne egy a html 4.01-ben specifikált (az a speci is szinte pontosan egyidős az előbbivel) tag-et, akkor is, ha az esetleg a html 5 piszkozatában már nem létezik (de még akkor sem, ha az nem piszkozat). Ha a doctype 4.01-et jelöl, akkor úgy kell feldolgozni. Nem véletlen, hogy már a JS 1.7 használatát is külön jelölni kell a böngésző(k)ben: ott mások a kulcsszavak, mint 1.6-ban. Így egy 1.6-ben működő kód esetleg kiakad JS 1.6-al értelmezve, mert egy ilyen kulcsszót használ azonosítóként. (lást bővebben)

A témakezdéssel viszont én sem értek egyet. Egy bug report-nak az a lényege, hogy leírd azt a minimális kódot, amiben máshogy viselkedik, mint ahogy kéne. Tény, hogy a weblabor fóruma nem egy bugtracker, de ha már azt a tényt állítod, hogy bug, akkor mutass egy könnyen érthető kódot hozzá. Ha valaki le akarná ellenőrizni, hogy itt tényleg bug-ról van szó, akkor először meg kéne értenie a programod működését, realizálni, hogy nem valami tervezési hiba vagy ilyesmi a probléma. Szerintem az égvilágon senki sem kötött volna bele, hogyha éjjel 4 óra helyett 9 órakor nyitod a témát, és már csak a TEST osztályos kódodat mutatod. (Amúgy ott sem teljesen értem, hogy minek kell a TEST osztály ehhez, de ez még elnézhető.) A lényeg ennyi:

var prototype, x;
	
function Bug() {
	var func = function () {
		x;
	};
	prototype;
}

alert(
	 "Bug: "+ !(new Bug instanceof Bug)
);
Tehát ha a konstruktor tartalmaz egy hivatkozást egy külső, "prototype" nevű változóra és egy olyan függvényt, ami egy külső változóra hivatkozik, akkor az ezen konstruktorral készített objektumok az instaceof szerint nem a ebből készültek.

Legtöbbször úgy dolgozom, hogy megírom előre a kódot, ami kb ilyen terjedelmű, mint ez itt, utána debuggolom

Fene tudja, ez már lehet, hogy személyeskedés (akkor bocsi), de azért én mégis úgy gondolom, hogy nem ez a helyes út. Mégpedig pont a hibakeresés szempontjából (akár a környezet hibája, akár a Tiéd). De szíved joga, ha Neked így gyorsabb, kényelmesebb a fejlesztés, akkor nem szólok bele. De az biztos, hogy bugot nem ilyen terjedelmű kóddal kell jelenteni, mert esetleg nem fognak komolyan venni.

Üdv.
24

foglalt szagú

zzrek · 2007. Jún. 3. (V), 15.28
Én akkor sem használnék olyan változónevet, ami "foglalt szagú". (Talán a 7 évvel ezelőtti specifikáció bugos ;-) Nekem mindegy, hogy bug, vagy foglalt változónév: emiatt nem működik. Tapasztaltam, hogy bölcsebb megelőzni az ilyen problémákat. (Ráadásul ha ezen múlik, hogy a verziófüggetlen kompatibilis marad...)
25

Neked mindegy :)

Pusztai Tibor · 2007. Jún. 3. (V), 16.23
Az természetes, hogy nem kéne használni, nem is javaslom senkinek. Viszont azért az nem mindegy, hogy ez bug vagy jó viselkedés. Mert ha bug, akkor illene megkeresni az okát, akár még az is lehetséges, hogy más hibát is előidéz. De természesetesen abból a szempontból mindegy, hogy ha használod, akkor nem várt következménye lehet firefox allatt.

Amúgy JS 2.0-ban sem igazi foglalt név, csak "syntactic keyword". Azaz van olyan szintaktikai környezet, amikor különleges jelentéssel bír: mégpedig egy class definicó belsejében a var illetve function előtt. Jelenleg is sok forgalomban lévő javascript kód (prototypejs, yahoo ui, jquery, base2, ...) használja a get, type, xml, namespace neveket, amik ugyanúgy syntactic keyword-ök 2.0-ban.
26

off

zzrek · 2007. Jún. 3. (V), 19.33
(Igen, nekem mindegy hogy bug-e, mert nem vagyok FF fejlesztő. Lehetőleg olyan kódot akarok gyártani, ami "bugos" böngészővel is megy: nem nyerek vele túl sokat, hogy tudom, "ez egy bug" és egyszer majd kijavítják)
Hmmm valahogy nem örülök neki, hogy 2.0-ban lesznek class definiciók. Nekem nagyon szimpatikus (volt) a jelenlegi JS objektum modellje.
(Mellesleg a YUI stb helyében sem használnám ezeket a neveket -- bár ők talán elég nagyok ahhoz, hogy nyomást gyakoroljanak a szabványra és miattuk biztosan nem fogják az FF fejlesztők egyszer véletlenül pl. az XML nevet -kis vagy nagy betűvel?- foglaltá tenni valamelyik verzióban :-)
27

:-)

inf · 2007. Jún. 3. (V), 23.49
A TEST osztályig úgy jutottam el, hogy levagdostam részeket az eredeti kódból, azt hittem, hogy annál specifikusabb a hiba, mint amit te írtál, így nem is próbálkoztam ennél is tömörebb formára hozni.
A témakezdés tényleg nem volt a legjobb :-) majd legközelebb kicsit jobban átgondolom.
Az meg, hogy hogyan dolgozom magánügy, de ha már ennyire érdekel, akkor azért debuggolok a végén, mert ritkán szoktam hibát találni, és így csomó felesleges próbálgatástól kímélem meg magam, és mondjuk ekkora méretű kódot csak ilyen extrém esetben nehéz debuggolni, amikor a hiba oka ismeretlen, legtöbb esetben nem szokott gondot okozni a dolog.
Ha nincs ellenvetésed a kódodat hozzáírom a bugreporthoz, kösz.

(csak halkan jegyzem meg, hogy az eredeti kódnak igazából csak a bugreport a haszna, mert ugyanazt a melót, amit csinál xml+xsl lazán elvégzi - gondolom sokkal rövidebb idő alatt. szóval csak tényleg nagyon speciális esetekben tudom hasznát venni, a dolognak - vagy akkor sem :D persze erre csak ma jöttem rá, miután jobban beleástam magam az xslbe, és rájöttem, hogy kb ugyanazt akarom megvalósítani javascriptben, mint ezek az emberkék az xml+xsl kombóval)
28

Megoldás

inf · 2007. Jún. 4. (H), 11.39
A bugreportra született megoldás, amit sajnos nem tudok értelmezni, mert Chez lövetem sincs, de következő firefoxban gondolom már nem lesz benne a hiba. Kösz a hozzászólásokat.