JavaScript - Abt Constructor And Prototype
hi, i'm currently stumped by the following code.
what's the point of using x.constructor.prototype? (highlighted in red) why not directly use x.prototype.classname to check whether 'classname' property is in this class? thx in advance Code: function getType(x) { // If x is null, return "null" if (x == null) return "null"; // Next try the typeof operator var t = typeof x; // If the result is not vague, return it if (t != "object") return t; // Otherwise, x is an object. Use the default toString( ) method to // get the class value of the object. var c = Object.prototype.toString.apply(x); // Returns "[object class]" c = c.substring(8, c.length-1); // Strip off "[object" and "]" // If the class is not a vague one, return it. if (c != "Object") return c; // If we get here, c is "Object". Check to see if // the value x is really just a generic object. if (x.constructor == Object) return c; // Okay the type really is "Object" // For user-defined classes, look for a string-valued property named // classname, that is inherited from the object's prototype if ("classname" in x.constructor.prototype && // inherits classname typeof x.constructor.prototype.classname == "string") // its a string return x.constructor.prototype.classname; // If we really can't figure it out, say so. return "<unknown type>"; } Similar TutorialsHi, all~..According to ECMAScript, the root of the prototype chain is Object.Prototype. Each object has an internal property [[Prototype]] that could be another object or NULL.... However, it also says that every function has the Function prototype object: Function.Prototype, it confused me, because a function is an object, for a function object, what is its function prototype and object prototype..For example: Code: var x = function (n) {return n+1;}; what is the relationships of x, Object.Prototype and Function.Prototype Thx a lot !!!!!!!!! hi, I'm trying to inherit with prototype but I'm not able to do so. The problem is that I have a few functions which use some common variables and common functions and I want to inherit a Resource object with all these parameters. I also whant this inheritance to be done when I load the function, so no extra functions are loaded unless I need them. Here's the code Code: function Resource(){ this.url=''; this.object=new Object(); this.id=''; this.categories=new Array(); } function Users(){ Users.prototype=new Resource(); this.url='user/'; this.name=''; this.email=''; }; function test(){ var users = new Users(); alert(users.id); }; When I run the test function for the first time I get an undefined. a second time works fine. I I get the prototype definition outside the User() function it also works fine, but I want the inherited function to be loaded when I need it. Any ideas? As always, thank you for your help. Anyone wanna give me some pointers on how prototypes work exactly? ;o Especially in the context of this code: Code: var chatscroll = new Object(); chatscroll.Pane = function(scrollContainerId){ this.bottomThreshold = 20; this.scrollContainerId = scrollContainerId; this._lastScrollPosition = 100000000; } chatscroll.Pane.prototype.activeScroll = function(){ var _ref = this; var scrollDiv = document.getElementById(this.scrollContainerId); var currentHeight = 0; var _getElementHeight = function(){ var intHt = 0; if(scrollDiv.style.pixelHeight)intHt = scrollDiv.style.pixelHeight; else intHt = scrollDiv.offsetHeight; return parseInt(intHt); } var _hasUserScrolled = function(){ if(_ref._lastScrollPosition == scrollDiv.scrollTop || _ref._lastScrollPosition == null){ return false; } return true; } var _scrollIfInZone = function(){ if( !_hasUserScrolled || (currentHeight - scrollDiv.scrollTop - _getElementHeight() <= _ref.bottomThreshold)){ scrollDiv.scrollTop = currentHeight; _ref._isUserActive = false; } } if (scrollDiv.scrollHeight > 0)currentHeight = scrollDiv.scrollHeight; else if(scrollDiv.offsetHeight > 0)currentHeight = scrollDiv.offsetHeight; _scrollIfInZone(); _ref = null; scrollDiv = null; } It's code to make the scrollbars autoscroll down. Full article and extra info he http://radio.javaranch.com/pascarell...837038219.html I sort of understand it but I'm not clear on what prototypes are. G'day, How would I go about copying all the prototype functions AND the constructor from one object into another object, and then call them? Code: function myOriginal() { alert('Hello'); } myOriginal.prototype.example = function() { alert('In example '+this.test); } function myNewThing() { // Copy myOriginal into this object here this.oldconstructor(); // Should now display "Hello" this.test = 'from myNewThing'; this.example(); // Should now display "In example myNewThing" } I know I can use this.example.call(this), but that's not an acceptable solution. I want to deploy this style over dozens, potentially hundreds of objects. Thanks muchly, Your friend from server-side... im currently using a prototype add on for one of my sites and id like to convert it to mootools... problem is, i dont know the first thing about prototype! i stumbled upon this before i learned any javascript and ive gotten to know mootools and like using it... heres the code, let me know if anyone can help! Code: /** * @author Bruno Bornsztein <bruno@missingmethod.com> * @copyright 2007 Curbly LLC * @package Glider * @license MIT * @url http://www.missingmethod.com/projects/glider/ * @version 0.0.3 * @dependencies prototype.js 1.5.1+, effects.js */ /* Thanks to Andrew Dupont for refactoring help and code cleanup - http://andrewdupont.net/ */ Glider = Class.create(); Object.extend(Object.extend(Glider.prototype, Abstract.prototype), { initialize: function(wrapper, options){ this.scrolling = false; this.wrapper = $(wrapper); this.scroller = this.wrapper.down('div.scroller'); this.sections = this.wrapper.getElementsBySelector('div.section'); this.options = Object.extend({ duration: 1.0, frequency: 3 }, options || {}); this.sections.each( function(section, index) { section._index = index; }); this.events = { click: this.click.bind(this) }; this.addObservers(); if(this.options.initialSection) this.moveTo(this.options.initialSection, this.scroller, { duration:this.options.duration }); // initialSection should be the id of the section you want to show up on load if(this.options.autoGlide) this.start(); }, addObservers: function() { var controls = this.wrapper.getElementsBySelector('div.controls a'); controls.invoke('observe', 'click', this.events.click); }, click: function(event) { this.stop(); var element = Event.findElement(event, 'a'); if (this.scrolling) this.scrolling.cancel(); this.moveTo(element.href.split("#")[1], this.scroller, { duration:this.options.duration }); Event.stop(event); }, moveTo: function(element, container, options){ this.current = $(element); Position.prepare(); var containerOffset = Position.cumulativeOffset(container), elementOffset = Position.cumulativeOffset($(element)); this.scrolling = new Effect.SmoothScroll(container, {duration:options.duration, x:(elementOffset[0]-containerOffset[0]), y:(elementOffset[1]-containerOffset[1])}); return false; }, next: function(){ if (this.current) { var currentIndex = this.current._index; var nextIndex = (this.sections.length - 1 == currentIndex) ? 0 : currentIndex + 1; } else var nextIndex = 1; this.moveTo(this.sections[nextIndex], this.scroller, { duration: this.options.duration }); }, previous: function(){ if (this.current) { var currentIndex = this.current._index; var prevIndex = (currentIndex == 0) ? this.sections.length - 1 : currentIndex - 1; } else var prevIndex = this.sections.length - 1; this.moveTo(this.sections[prevIndex], this.scroller, { duration: this.options.duration }); }, stop: function() { clearTimeout(this.timer); }, start: function() { this.periodicallyUpdate(); }, periodicallyUpdate: function() { if (this.timer != null) { clearTimeout(this.timer); this.next(); } this.timer = setTimeout(this.periodicallyUpdate.bind(this), this.options.frequency*1000); } }); Effect.SmoothScroll = Class.create(); Object.extend(Object.extend(Effect.SmoothScroll.prototype, Effect.Base.prototype), { initialize: function(element) { this.element = $(element); var options = Object.extend({ x: 0, y: 0, mode: 'absolute' } , arguments[1] || {} ); this.start(options); }, setup: function() { if (this.options.continuous && !this.element._ext ) { this.element.cleanWhitespace(); this.element._ext=true; this.element.appendChild(this.element.firstChild); } this.originalLeft=this.element.scrollLeft; this.originalTop=this.element.scrollTop; if(this.options.mode == 'absolute') { this.options.x -= this.originalLeft; this.options.y -= this.originalTop; } }, update: function(position) { this.element.scrollLeft = this.options.x * position + this.originalLeft; this.element.scrollTop = this.options.y * position + this.originalTop; } }); Code: /** * @class TestInheritance * * This is a class and it's constructor all in one but the constructor is not set yet */ function TestInheritance(){ this.testName; return this; } /** * @extends Util * Make sure this is called after the constructor/class declaration */ TestInheritance.prototype = new Util(); /** * @ctor TestInheritance * Set it to itself if there isn't an explicit constructor */ TestInheritance.prototype.constructor = TestInheritance; /** * @extends Util * This specifically is set to allow TestInheritance to access it's parent's identity */ TestInheritance.prototype.parent = new Util(); /** * @extends Util * @argument testName String * All functions are called after setting the prototype */ TestInheritance.prototype.setTestName = function(testName){ this.testName = testName; } How would I reference the same Util class on both the prototype and the parent? Hi I am using a program called aptabs which uses the Protoype framework. The problem is that when I create a new tab and refresh the page, the newly created tab disappears. How can I resolve this ? NOTE: The zip file for aptabs is attached. Thanks Hi, I'm trying to use a javascript tabstrip script called aptabs, which uses prototype.js. However, prototype.js won't load properly, because the following error occurs in prototype.js: destination is undefined on the following line (3042): destination[property] = value.methodize(); The function this line is in is: Code: function copy(methods, destination, onlyIfAbsent) { onlyIfAbsent = onlyIfAbsent || false; for (var property in methods) { var value = methods[property]; if (!Object.isFunction(value)) continue; if (!onlyIfAbsent || !(property in destination)) destination[property] = value.methodize(); } } I've tried using versions 1.6.0 all the way up to 1.6.1, but I still get the same error. Can someone suggest what this error could be caused by and possible fixes? Debbie Hi there I am trying to retrieve xml data using the prototype Ajax.Request. I think I am getting the xml though I am unsure as to how to retrieve the text from the nodes here is the function I am using to try and populate a text field Code: function makeMarkerXml() { new Ajax.Request('coords.xml', { method:'post', onSuccess: function(transport){ ////this will not work///////// var coord = transport.responseXML.childNodes(0).childNodes(0).firstChild.text; /////////////////////////////// }, onFailu function(){ alert('Call failed') } }); } can anyone help? I need to detect the "name" of the constructor of an object. For example, myArray.constructor === Array is true, but I want something where that === 'Array' is true. I've heard of Object.constructor.name, but it's not widely compatible. Any ideas (preferably without involving regular expressions)? Thanks in advnce, Julian I had read from books that the constructor property of object is inherited from its prototype. And the prototype can be changed dynamically. New property can be added to or deleted from object even it was created before the prototype change. But I got confused on below codes. Code: function A() { this.title = "A"; } function B() { this.title = "B"; } document.write("<br>"); var b = new B(); document.write(b.constructor); document.write("<br>"); document.write(B.prototype.constructor); document.write("<br>"); B.prototype = new A(); document.write(b.constructor); // Suppose to output "function A() ..." document.write("<br>"); document.write(B.prototype.constructor); document.write("<br>"); B.prototype.constructor = B; document.write(b.constructor); document.write("<br>"); document.write(B.prototype.constructor); document.write("<br>"); But the actual result (both IE and firefox) is Code: function B() { this.title = "B"; } function B() { this.title = "B"; } function B() { this.title = "B"; } function A() { this.title = "A"; } function B() { this.title = "B"; } function B() { this.title = "B"; } Please help me. thanks. I have a dice simulator. Basically, a user enters how many sides they want on their die, and then I digitally roll 2 of them. And produce the output in a document.writeln. I think I'm having trouble with the this.sides in the constructor function (in the head section). Also, I'm getting a syntax error in Safari : 25TypeError: 'null' is not an object (evaluating 'element.value') Am I not suppose to put the variable in the constructor function? Any help would be appreciated. <head> var element = document.getElementById("number"); var sides = element.value; function Die( ) { this.sides = sides; this.roll = function( ) { return parseInt((Math.random( ) * 1000) % this.sides) + 1; } } </script> </head> <body> <h1>Adam's Dice Rolling Game!</h1><br/> <form action="" method="post"> <p> <input type="text" name="number" id="number"/> </p> <p> <input type="button" value="Roll the dice!" id="roll_me"/> </p> </form> <script type="text/javascript"> var d = new Die( ); d.sides = sides; var rolled_value = d.roll( ); var r1 = document.getElementById( "roll_me" ); r1.onclick = function Die () { document.writeln ( d.roll () ); } </script> How to extend the constructor for the date object of the javasccript so that whenever a call is made to the constructor, I want to perform a particular action? Basically how to define wrappers for default javascript methods or objects like Date() so that I can perform some action and then invoke the original method? So basically if I have something like var a = new Date(); I want it to (say) alert the value of the date everything Date() is called and then execute the default date constructor. TIA Hi - In am learning Javascript and trying to understand why, the following line : Code: arguments.callee.superclass cannot be replaced by : Code: this.constructor.superclass In the following code sample : ( the explanation given is that if someone creates a subclass of PositionedRectangle, then this.constructor will refer to the new subclass constructor, not to PositionedRectangle - but why? 'this' here to my knowledge represents the object 'PositionRectangle' and if not I can't understand why not. ) Code: // Here is a simple Rectangle class. // It has a width and height and can compute its own area function Rectangle(w, h) { this.width = w; this.height = h; } Rectangle.prototype.area = function( ) { return this.width * this.height; } // Here is how we might subclass it function PositionedRectangle(x, y, w, h) { // First, invoke the superclass constructor on the new object // so that it can initialize the width and height. // We use the call method so that we invoke the constructor as a // method of the object to be initialized. // This is called constructor chaining. PositionRectangle.superclass = Rectangle; arguments.callee.superclass .call(this, w, h); // Now store the position of the upper-left corner of the rectangle this.x = x; this.y = y; } // Create a prototype for the subclass that inherits from the prototype // of the superclass. function heir(p) { function f(){} f.prototype = p; return new f(); } PositionRectangle.prototype = heir(Rectangle.prototype); PositionRectangle.prototype.constructor = PositionRectangle; Hey All - I asked this a few days ago.. what I came up with works just fine, but I feel it doesn't take advantage of "classes". If you think I could make this better by turning it into a class or using some other notation, that would be great. Keep in mind, ALL this does is rewrite a pagination.... for a search return in a lightbox. I have this function called in the return function... Code: var srcpagParams = $H(); function buildPagi(param, currdsplyNum){ var temDsply = new Template('<strong>[#{total_display}<span id="count">#{prevImg} #{links} #{nextImg}</span>'), crnt_link = srcpagParams.set('crnt_link', param), // the page we want to see dsplyNum = srcpagParams.get('paginateNum'), // what is the number of returns per page ttl_lnks = Math.ceil( srcpagParams.get('numFound') / srcpagParams.get('paginateNum')), // total pages data_template = new Hash(); data_template.set('total_display',srcpagParams.get('numFound')); bldImg = function() { var prvB = '<a href="#content" id="pagiPrev" onclick="firesrc(this)">Prev<img src="blank.gif" /></a>'; var nxtB = '<a href="#content" id="pagiNext" onclick="firesrc(this)">Next<img src="blank.gif" /></a>'; data_template.set('prvImg',(crnt_link > 1) ? prvB : ""); data_template.set('nxtImg',(crnt_link < ttl_lnks) ? nxtB : ""); } bldLk = function(){ var holder = ""; if(ttl_lnks > 1){ var linkStr = new Template(' <a href="#content" onclick="firesrc(#{pos});"> Go to page #{pos}</a> '); $R(1,ttl_lnks).each(function(n) { var posit = {pos : n} holder += (crnt_link == n) ? " " + n + " " : linkStr.evaluate(posit); }); data_template.set('links',linkholder); } } bldRng = function(){ var currPaneRg = (dsplyNum * crnt_link) - (dsplyNum - currdsplyNum); data_template.set('range',((crnt_link - 1) * (dsplyNum) + 1 ) + " - " + currPaneRg); $('pages').update(temDsply.evaluate(data_template)).show(); } firesrc = function(cl){ var pagiPane = (typeof cl === "number") ? cl : (cl.id == "pagiNext") ? crnt_link + 1 : crnt_link - 1; var start = crnt_link * srcpagParams.get('paginateNum'); Alertsrc( $F('query') ,(pagiPane)) // pass the query to the json to return the current search request } bldImg(); buildLnk(); bldRng(); }; Since some of the data declared at the top changes depending on the return, I didn't know if I could "initialize" it in a class. But could I turn this into a class and if so - what I just use: var buildPagi = create.Class({ initialize: object.extend({ }) }) Call the function when we are passed some data: Code: buildPagi(somevalue, somevalue2) ** NOTE: I use the libraries prototype and jquery.. so use Create.Class and new Template are within the libraries... etc.. so, is there a more eloquent, or robust way to write what I did above? The code below looks elementary, but it gives absurd results. Can you tell how I should have written it? I am slowly beginning to understand why it fails. But I do not understand why the JavaScript tutorials I've studied never warned against this trap. Any ship needs a list of crew members. The total number of persons onboard must be known too, for the case the ship sinks. We place these two properties in a prototype, so that we won't have to repeat them for each kind of ship. A passenger list is needed only if the ship is a passenger ship, so we decide not to place the passenger list in a prototype. Code: function Ship() { this.crew = []; this.persons = 0; } function PassengerShip(name) { this.name = name; this.passengers = []; } PassengerShip.prototype = new Ship; Passengers and crew arrive one by one shortly before departure. The first thing they do onboard is to check in: Code: Ship.prototype.checkin = function(list, person) { this[list].push(person); ++this.persons; } (Instead of the push function, we could as well have used a statement such as Code: this[list][ this[list].length ] = person; I have tried. Same wrong result.) Let us launch two passenger ships and check some persons in. Code: var msFloat = new PassengerShip("M/S Float"); msFloat.checkin("crew", "Captain"); msFloat.checkin("crew", "Cook"); msFloat.checkin("passengers", "Alice"); msFloat.checkin("passengers", "Bob"); var msFlawed = new PassengerShip("M/S Flawed"); msFlawed.checkin("crew", "Capt'n"); msFlawed.checkin("crew", "Sailor"); msFlawed.checkin("passengers", "Charlie"); The shipping company wants a report when everybody has checked in. But I'm not sure they will like it: Code: Ship.prototype.report = function() { function makeList(ship, list) { if (!ship[list]) return (ship.name + " has no list of " + list + ".\n"); if (!ship[list].length) return (ship.name + " has no " + list + ".\n"); return (list + ": " + ship[list].join(", ") + "\n"); } alert("\nPre-Departure Report For '" + this.name + "'\n\n" + makeList(this, "passengers") + makeList(this, "crew") + "\nNumber of persons onboard: " + this.persons + "\n\n"); } msFloat.report(); // OK: Alice, Bob as passengers; Captain, Cook as crew msFlawed.report(); // WRONG CREW: Captain, Cook, Capt'n, Sailor The number of persons (passengers + crew) is reported correctly for both ships, and so is the passenger list. But the "M/S Flawed" reports four crew members. Two of those never checked in on that ship. How can such a thing happen? What kind of blunder did I make? An "edit+execute" version of the code is available at bjarne.altervista.org/sailor.html together with a little testoutput, some considerations based on that testoutput, and a workaround (which is not the same as a solution - it looks ridiculous). It seems as if arrays placed in prototypes do not always work as expected. Can that be true? The testoutput suggests that JavaScript sometimes forgets to create a much-needed own property in the this object, and instead changes the prototype. But that sounds incredible, doesn't it? I am not too familiar with the deeper theory of JavaScript, and I hope to get a response. Here is the code concatenated and embedded: Code: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><title>Array In JavaScript Prototype</title></head> <body> <script type="text/javascript" language="JavaScript"> function Ship() { this.crew = []; this.persons = 0; } function PassengerShip(name) { this.name = name; this.passengers = []; } PassengerShip.prototype = new Ship; Ship.prototype.checkin = function(list, person) { this[list].push(person); ++this.persons; } Ship.prototype.report = function() { function makeList(ship, list) { if (!ship[list]) return (ship.name + " has no list of " + list + ".\n"); if (!ship[list].length) return (ship.name + " has no " + list + ".\n"); return (list + ": " + ship[list].join(", ") + "\n"); } alert("\nPre-Departure Report For '" + this.name + "'\n\n" + makeList(this, "passengers") + makeList(this, "crew") + "\nNumber of persons onboard: " + this.persons + "\n\n"); } var msFloat = new PassengerShip( "M/S Float" ); msFloat.checkin("crew", "Captain"); msFloat.checkin("crew", "Cook"); msFloat.checkin("passengers", "Alice"); msFloat.checkin("passengers", "Bob"); msFloat.report(); // OK: Alice, Bob as passengers; Captain, Cook as crew var msFlawed = new PassengerShip( "M/S Flawed" ); msFlawed.checkin("crew", "Capt'n"); msFlawed.checkin("crew", "Sailor"); msFlawed.checkin("passengers", "Charlie"); msFlawed.report(); // WRONG CREW: Captain, Cook, Capt'n, Sailor </script> </body> </html> I have spent much time struggling with this kind of error, which is reproducible in 5 different browsers. This is the first time I have been able to reproduce it in a form that can be presented to others. Is there a well-established programming practice that can prevent it? What do experienced JavaScript programmers do? Regards Bjarne Pagh Byrnak Array.prototype.each = function (fn) { this.map(fn) } This is my each function that works great in every other browser but IE. UGH! What am I doing wrong? the error points to the this in the function. Is it that IE doesn't like map? Has anyone seen this before? I thought my code was correct. Works perfect in FF, chrome and opera. the canvas text doesn't work in opera, but it does render the features so the each function is working. I'll post the code if needed, but it's huge. here's the script running. http://www.pdxbusiness.com/canvas/golf/ Hello, I'm trying to write my class with member properties and functions like below. What I want to learn is that is there any problem to use prototype object in the class that we want to use with it? I asked because I generally see that prototype object definition and member functions and properties created outside of the class unlike my class that I wrote like below. Is there any problem writing my class like below? Thanks. Code: function Point() { Point.prototype.x = this._x; Point.prototype.y = this._y; function _setX(x) { this.x = x; } Point.prototype.setX = _setX; function _setY(y) { this.y = y; } Point.prototype.setY = _setY; function _show() { alert(this.x + this.y); } Point.prototype.Show = _show; } function callMyClass() { var p = new Point(); p.setX(3); p.setY(5); p.Show(); } Hello all I have been trying in vain for many days to resolve a conflict between javascript libraries. I have read far and wide and still have failed to fix this problem, most likely because my programming skills are just about copy and pasting. My homepage uses jquery horizontal css menubar + a combined mootool and prototype accordian type sliding information box in the middle of the webpage. I find that the highlighter of the css menubar does not work when prototype.js is also loaded on the same page. I have read somewhere that $ should be replaced however I have tried every possible option and none works. I have jquery loading first as it is on my template, with this <script type='text/javascript' src='../Web/Templates/jquery-1.3.2.js'></script> <script type='text/javascript' src='js/example.js'></script> And my mootool and prototype loades further below like this <script type="text/javascript" src="scripts/intro/prototype.lite.js"></script> <script type="text/javascript" src="scripts/intro/moo.fx.js"></script> <script type="text/javascript" src="scripts/intro/moo.fx.pack.js"></script> <script type="text/javascript"> function init(){ var stretchers = document.getElementsByClassName('box'); var toggles = document.getElementsByClassName('tab'); var myAccordion = new fx.Accordion( toggles, stretchers, {opacity: false, height: true, duration: 600} ); //hash functions var found = false; toggles.each(function(h3, i){ var div = Element.find(h3, 'nextSibling'); if (window.location.href.indexOf(h3.title) > 0) { myAccordion.showThisHideOpen(div); found = true; } }); if (!found) myAccordion.showThisHideOpen(stretchers[0]); } </script> Could someone please offer me further assistance and enlighten me what other information you require to assist me further. I have attached the example.js inside example.zip file if someone could kindly edit it for myself. Looking forward to your assistance. Sincerely, Lex Hi All, Why is the Option constructor converting my text as follows? text = ' 1:30 pm' Option tag that gets generated: <option value="10">&nbsp;&nbsp;1:30 pm</option> How do I suppress the conversion of the & to & by the constructor? I've tried escaping the & but that's a no go. Thanks in advance for any help on this. JD |