www.webdeveloper.com
Results 1 to 9 of 9

Thread: Strict JavaScript and "use strict"

  1. #1
    Join Date
    Dec 2008
    Posts
    488

    Question Strict JavaScript and "use strict"

    A few weeks ago, someone suggested that my PHP methods weren't quite acceptable for programming correctly in JavaScript. So I set out to learn how to program strictly in JavaScript.

    I'm still learning JavaScript, but I'm learning more everyday. I figured learning to be more strict would help me to learn faster. Obviously I still need to learn more about DOM standards and browser compatibility.

    My question is where can I find exact standards on programming using the "use strict"; statement? I read somewhere that browser writers are only just beginning to look at making them compatible with this statement, so there's no way for me to test my strictness. And to make matters worse, JSLint doesn't even find "strict" errors. It only checks for the use of the "use strict"; statement.

    For example, I was trying to practice some simple problem solving skills and decided to write a JavaScript version of the binary clock app on the iPhone, just for fun. I figured it would be a good chance to figure out strict code, so I put it all in JSLint.

    I plan to add functionality to it for dates, epoch time, displaying actual time, color choices, etc. That way, I'll be building a program and building good coding form at the same time:
    Code:
    /*global window, document, setInterval, Date, addEvent, changeDigits, clockToBinaryArray, doccc, leadZero, parseInt, startClockInt */
    
    "use strict";
    
    function addEvent(target, eventName, handlerName) {
    
        //Cross browser event handling
        if (target.addEventListener) {
            target.addEventListener(eventName, handlerName, false);
        }
        else if (target.attachEvent) {
            target.attachEvent("on" + eventName, handlerName);
        }
        else {
            target["on" + eventName] = handlerName;
        }
    }
    
    function leadZero(str, len) {
        var outputBin, z;
    
        // Use a minumum of 4 digits in binary.  Add leading zeros.  Better way to do this?
        outputBin = "";
        for (z = 0; z < (len - str.length); z += 1) {
            outputBin += "0";
        }
    	//add the actual binary string
        outputBin += str;
    
        return outputBin;
    }
    
    function changeDigits(binary) {
        var digits, switches, digID, bcclass;
    
        //Digits = columns, switches = rows, loop through and change the class to use a different background (lights up the switch)
        for (digits = 0; digits < 6; digits += 1) {
            for (switches = 0; switches < 4; switches += 1) {
                //Build the id of the cell
                digID = "dig" + digits + "-" + switches;
    			//Build class name based on 1 or 0, depending on the binary string
                bcclass = "bc-" + binary[digits].charAt(switches);
                document.getElementById(digID).setAttribute("class", bcclass);
            }
        }
    }
    
    function setTrueTime(timeStr) {
        var trueTime;
    
        // The HTML element to contain the normal time for testing
        trueTime = document.getElementById("trueTime");
    	
    	// if none of these work, something's up... I know there's another way to do this with DOM methods.
    	if (document.innerText) {
            trueTime.innerText = timeStr;
        }
        else if (document.textContent) {
            trueTime.textContent = timeStr;
        }
        else {
            try {
    			// This is not DOM standard. Need to replace all of this with DOM methods.
    		    trueTime.innerHTML = timeStr;
    		}
    		catch (e) {
    			// throw an error for testing
    			// throw new Error(e.msg);
    		}
        }
    }
    
    function clockToBinaryArray() {
        var rightNow, timeString, newBin, binDig, newBinDig, stHours, stMinutes, stSeconds, stTime;
    
        rightNow = new Date();
    
        // Create a string of actual time to convert to binary and for comparison
        stHours = leadZero(rightNow.getHours().toString(), 2);
        stMinutes = leadZero(rightNow.getMinutes().toString(), 2);
        stSeconds = leadZero(rightNow.getSeconds().toString(), 2);
        timeString = stHours + stMinutes + stSeconds;
    
        //An array containing each subset of binary for each corresponding digit (loop through standard time string)
        newBin = [];
        for (binDig = 0; binDig < timeString.length; binDig += 1) {
            newBinDig = parseInt(timeString.charAt(binDig), 10);
    		//convert to binary and add leading zeros
            newBin.push(leadZero(newBinDig.toString(2), 4));
        }
    	// change the class of each cell using an array of binary numbers
        changeDigits(newBin);
    
        //For testing, set standard time to compare to binary time
        stTime = stHours + ":" + stMinutes + ":" + stSeconds;
    	//setTrueTime(stTime);
    }
    
    addEvent(window, "load", function () {
        // set the clock to run every tenth of a second
        window.startClockInt = setInterval(clockToBinaryArray, 100);
    });
    Any suggestions on how I can make this more "strict", so that when browsers do start using it, my code will still work?
    Last edited by jamesbcox1980; 12-03-2009 at 11:34 AM.

  2. #2
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    Unfortunately it is not a matter of strict coding, but a matter of crossbrowser coding. Even there are a JavaScript standard (see ECMAScript) and DOM standard (see W3C DOM) no browser follows entirely the standards. IE is the champion of deviations. The good news is that those deviations are not quite so many, or better say many of them are not so important.

    Here's an example, from your code:
    Code:
    document.getElementById(digID).setAttribute("class", bcclass);
    For IE, class is a sort of reserved word, thus it will use className instead of class. Fortunately, there is a simple crossbrowser solution: DOM 0 syntax:
    Code:
    document.getElementById(digID).className= bcclass;
    Same with the addEventListener and attachEvent. Your crossbrowser function is OK, in case you want to add another function to be fired by the event. But if you need simply to create and add a new one, simply use the old DOM 0 trusty syntax:
    Code:
    element.onload=function(){
    // statements, functions, whichever 
    }
    A good and comprehensive site where you can see all the differences (not only for JavaScript and DOM, but for CSS and even HTML as well):

    http://www.quirksmode.org/compatibility.html
    Last edited by Kor; 12-03-2009 at 12:22 PM.

  3. #3
    Join Date
    Dec 2008
    Posts
    488
    Awesome thanks for pointing that out about class. I had been using className= but I ran across some issues with setting "name" and some other things. I figured it was better to go with setAttribute.

    Thanks for that link also! I'd still like to find a little more about strict coding, but that may not even matter until I start working with more advanced scripts and DOM methods.

  4. #4
    Join Date
    Sep 2009
    Posts
    52
    Quote Originally Posted by jamesbcox1980 View Post
    Thanks for that link also! I'd still like to find a little more about strict coding, but that may not even matter until I start working with more advanced scripts and DOM methods.
    http://ejohn.org/blog/ecmascript-5-s...json-and-more/

  5. #5
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    "use strict" enables a watered-down javascript interpreter mode.

    leaving out the most powerful features of javascript like eval and with makes it a lot simpler to pre-optimize and/or JIT compile.

    unlike XHTML, "strict" in javascript has nothing to do with the quality, modernity, or validity of the code.

    Personally, i don't think very highly of "use strict", but i suppose it can be good for building faster libraries, or teaching children programming.

    by my reading, "use strict" looks to be a replacement for ECMA327, aka "compact profile".

    if you want to test for strict-mode compliance now, try to find a ECMA327 engine and see if your code works.
    aside from the new features in ES5, ES-CP should be about the same as "use strict"...
    Last edited by rnd me; 12-03-2009 at 06:25 PM.

  6. #6
    Join Date
    Aug 2007
    Posts
    3,767
    Quote Originally Posted by rnd me View Post
    leaving out the most powerful features of javascript like eval and with makes it a lot simpler to pre-optimize and/or JIT compile.
    Firstly, powerful is a unusual ephitet. I never found a use for with, and very rarely for eval or its cousins.
    I didn't think eval is totally gone? I thought you just couldn't declare variables with it.
    Great wit and madness are near allied, and fine a line their bounds divide.

  7. #7
    Join Date
    Dec 2008
    Posts
    488
    Apparently "eval" has some security issues if you don't trust the source of your JSON. That being said, "eval" is great for processing JSON. In fact, I think it's the only way to get JSON to produce results. So I agree that it is powerful.

    See, I thought that strict mode had to do with the quality of the code and gave more warnings for standards and security. I guess you're saying that's not the case, but that it's more of a reduction in functionality for security reasons. That makes sense. I guess I'll just stick to JSLint's requirements.

    I had emailed Douglas Crockford to find out exactly what JSLint does with strict mode, since I read that JSLint doesn't find run-time strict mode errors (yeah I bothered the poor guy), and all he said was:

    "The 'use strict' directive is a feature of ES5, which removes or redefines some of the bad parts."

    I thought that didn't said much, but now that I've heard the extended version and read a little about JSLint, I see that it actually says a lot.

  8. #8
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    On the other hand, in the web matters strict might be understood as the way you instruct the browser's interpretor to parse the codes on the client's level (HTML, CSS, JavaScript).

    From this point of view "strict mode" means to use a certain Doctype, while "quirks mode" (aka no Doctype) means to leave the interpreter to approximate the codes on his own.

    In quirks mode, browsers (IE mainly) do act in weird ways...

    If so, the general feeling is ferm: never let the browser in the "quirks mode". Documents must bear always a Doctype.
    Last edited by Kor; 12-04-2009 at 01:51 PM.

  9. #9
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    Quote Originally Posted by Declan1991 View Post
    Firstly, powerful is a unusual ephitet. I never found a use for with, and very rarely for eval or its cousins.
    I didn't think eval is totally gone? I thought you just couldn't declare variables with it.
    I don't think it's a security concern, it's a speed concern. There are plenty of ways to run code without eval or Function... ES-CP doesn't have eval or with either... last i heard, eval was a syntax error under "use strict", but perhaps they backed down or i/they are mistaken.


    i left eval alone for a long time. As i became more interested in expanding the language, i've realized that eval is about the only way to do so. Function() just doesn't have the scope. I hope eval still works, i'm just getting started making language extensions...

    Performance is not everything, and with TraceMonkey and V8 type technologies becoming the norm, we should be able to get away with a lot more than we've become accustomed to.

    for example, this expanded syntax can work only by using eval (and only by using it inside the closure of the constructor):

    Code:
    function Person(strName){ 
    
    	var born=new Date;			// private property (default)
    	private: var safeName=	escape(strName);// (default)
    	static:  var lastBorn= 	born; 		// bound to constructor object
    	proto: 	 var previous= 	7567; 		// prototype property (inherently static)
    	global:	 var lastRun= 	born.getTime()	// global property (not in resulting object)
    	public:  var bornOn=	born;		// regular properties are usually public
    	public:  var getBirth=	function(){	// regular methods are usually public
    	  		return String(this.bornOn); 
    		  }//end getBirthday
    	lambda:	var age=	function(){return (new Date).getTime() - born.getTime(); }
    
     this.api=(Crass(eval(Crass(arguments,this))));	// run Crass!
    
    }//end Person()
    efficient? not really, but not as terrible as you might think...
    neat? i think so, this is just one flavor; labels can do anything you code...

    with can also be used simulate classes, smuggle closures, and speedup code by eliminating long-winded property lookups.
    If a needed prop is behind a getter, you can't simply use a variable cache, you need with...

    given the persistent bad-mouthing, i am just getting into experimenting with with and eval over the past year.

    Don't get me wrong;
    a "use strict" function library will likely transform a bitmap image quicker than a standard one would (for now),
    but, let's not proclaim "use strict" to be anything other than castrated ES5.

    $0.02
    Last edited by rnd me; 12-04-2009 at 06:34 PM.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles