Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 09-01-2010, 03:07 AM   PM User | #16
DaveyErwin
Regular Coder

 
Join Date: Aug 2010
Posts: 814
Thanks: 12
Thanked 168 Times in 166 Posts
DaveyErwin is on a distinguished road
Quote:
Originally Posted by johnmerlino View Post
So if scope chaining is built into javascript (variable checks parent scope if not defined in current scope), then what's the added benefit of closures? Someone said that the benefit of closures is when interpreter exits parent function (e.g. Validation()), you can call the inner function later (e.g. $.Validation.getRule()) and gain access to the variables of the parent. Yet, in scope chaining, that happens anyway! So I absolutely see no benefit in closures.
I don't know if your talkin to me ?
But just look at the code i posted
for the very simple count down timer,
thats all about closures.
DaveyErwin is offline   Reply With Quote
Old 09-01-2010, 04:18 AM   PM User | #17
DaveyErwin
Regular Coder

 
Join Date: Aug 2010
Posts: 814
Thanks: 12
Thanked 168 Times in 166 Posts
DaveyErwin is on a distinguished road
Quote:
Originally Posted by johnmerlino View Post
I am confused about what the return keyword is actually returning when returning an object, a primitive, or a function.

My confusion is compounded by the fact that I'm not sure if a function is an object or not.
According to the book JavaScript Programmer Reference it is:
"All functions in JavaScript are first class objects , meaning they can be passed around like any other object reference. In fact, regardless of how they are created, functions are instances of a global object named (aptly) Function."

However, someone else states that a function is not an object. An object is a set of primitives and references. A function is executable code. Functions become objects through the use of the new operator. Yet, in the book I mentioned, it says you don't need the new keyword to execute the function as an object, as it already inherits from the object Function when the function keyword is used:
Code:
function functionName([argname1 [, ...[, argnameN]]])
{
statements;
}
So there's one source of contradiction.

Now the bigger issue is what is going on when the return keyword is used. Notice the Validation() function returns an object as its last expression. This technique is common, where you return an object which contains functions in form of object notation. I believe this is done so that we create a closure so that when the intepreter exits the Validation() method, since we created a closure by returning an object, which contains the inner functions addRule and getRule, the local variables of Validation() are not destroyed, given that we can reference them through the two inner functions that make use of the local variables of the outer function. So when we use the return keyword on an object literal, and then exit the function, when we call one of the inner functions as we do later:
Code:
var rule = $.Validation.getRule(types[type]);
essentially getRule() is called, passes an argument, which is received by the inner function as parameter we call name:
Code:
getRule : 
function(name) {  

                return rules[name];
            }
First, note that the return {} is written in object notation, therefore making getRule a local variable and, thus, private function only accessible through the namespace of Validation().

Validation() declares the rules local variable and because of the closure, we can access the rules local variable through the getRule() inner function.

*****Here's the part that really thows me off. We return rules[name]. So let's say name is equal to email. This is an associative array so email (held in name) is a property of rules. So here we return the object's property:
Code:
return rules[name];
And then assign it to a local variable called rule:
Code:
var rule = $.Validation.getRule(types[type]);
So when we return an object rules[name], do we return a reference to an object or a value? In other words, by returning rules[name], where name is equal to email, are we then returning a reference to the following object literal:
Code:
email : {
               check: function(value) {
                   
                   if(value)
                       return testPattern(value,".+@.+\..+");
                   return true;
               },
               msg : "Enter a valid e-mail address."
            }
And if we are returning a reference, by returning a reference, are we essentially pointing to this object when we assign it to rule? In other words, the variable rule is just pointing to the object literal?

And is that the reason we can then access the check function or msg local variable through rule using dot notation, because rule points to the email object literal?

Now the ultimate brain twist for me is that if a function is an object, then why when return a function, it returns a value, such as a boolean, if an object only returns a reference and not the value?

Code:
//Validation is a local variable as it is in a self-executing anonymous function. The purpose of the said anonymous function is to pass the jQuery object as a parameter $ so the $() function will be in scope of the anonymous function and not interfere with other libraries that make use of the same function technique - in the global scope. 
(function($) {
        var rules = {
            
            email : {
               check: function(value) {
                   
                   if(value)
                       return testPattern(value,".+@.+\..+");
                   return true;
               },
               msg : "Enter a valid e-mail address."
            },
            url : {

               check : function(value) {

                   if(value)
                       return testPattern(value,"https?://(.+\.)+.{2,4}(/.*)?");
                   return true;
               },
               msg : "Enter a valid URL."
            },
            required : {
                
               check: function(value) {

                   if(value)
                       return true;
                   else
                       return false;
               },
               msg : "This field is required."
            }
        }
        var testPattern = function(value, pattern) {

            var regExp = new RegExp("^"+pattern+"$","");
            return regExp.test(value); //The test() method is built into javascript
        }
        return {
            
            addRule : function(name, rule) {  

                rules[name] = rule;
            },
            getRule : function(name) { 

                return rules[name];
            }
        }
    }
    
    /* 
    Form factory 
    */
    var Form = function(form) {
        
        var fields = [];
    
        $(form[0].elements).each(function() {
            var field = $(this);
            if(field.attr('validation') !== undefined) {
                fields.push(new Field(field));
            }
        });
        this.fields = fields;
    }
    Form.prototype = {
        validate : function() {

            for(field in this.fields) {
                
                this.fields[field].validate();
            }
        },
        isValid : function() {
            
            for(field in this.fields) {
                
                if(!this.fields[field].valid) {
            
                    this.fields[field].field.focus();
                    return false;
                }
            }
            return true;
        }
    }
    
    /* 
    Field factory 
    */
    var Field = function(field) {

        this.field = field;
        this.valid = false;
        this.attach("change");
    }
    Field.prototype = {
        
        attach : function(event) {
        
            var obj = this;
            if(event == "change") {
                obj.field.bind("change",function() {
                    return obj.validate();
                });
            }
            if(event == "keyup") {
                obj.field.bind("keyup",function(e) {
                    return obj.validate();
                });
            }
        },
        validate : function() {
            
            var obj = this,
                field = obj.field,
                errorClass = "errorlist",
                errorlist = $(document.createElement("ul")).addClass(errorClass),
                types = field.attr("validation").split(" "),
                container = field.parent(),
                errors = []; 
            
            field.next(".errorlist").remove();
            for (var type in types) {

                var rule = $.Validation.getRule(types[type]);
                if(!rule.check(field.val())) {

                    container.addClass("error");
                    errors.push(rule.msg);
                }
            }
            if(errors.length) {

                obj.field.unbind("keyup")
                obj.attach("keyup");
                field.after(errorlist.empty());
                for(error in errors) {
                
                    errorlist.append("<li>"+ errors[error] +"</li>");        
                }
                obj.valid = false;
            } 
            else {
                errorlist.remove();
                container.removeClass("error");
                obj.valid = true;
            }
        }
    }
    
    /*
    Validation extends jQuery prototype
    */
    $.extend($.fn, {
        
        validation : function() {
            
            var validator = new Form($(this));
            $.data($(this)[0], 'validator', validator);
            
            $(this).bind("submit", function(e) {
                validator.validate();
                if(!validator.isValid()) {
                    e.preventDefault();
                }
            });
        },
        validate : function() {
            
            var validator = $.data($(this)[0], 'validator');
            validator.validate();
            return validator.isValid();
            
        }
    });
    $.Validation = new Validation();
})(jQuery);
Thanks for any response.
It returns an Object , don't forget my thanks....uh
DaveyErwin is offline   Reply With Quote
Old 09-01-2010, 09:33 AM   PM User | #18
Dormilich
Senior Coder

 
Dormilich's Avatar
 
Join Date: Jan 2010
Location: Behind the Wall
Posts: 2,907
Thanks: 10
Thanked 293 Times in 289 Posts
Dormilich is on a distinguished road
you’re misunderstanding closures. a closure not only has access to its inner and outer variables, it also preserves them over the usual lifetime. (basically having acces to variables that would normally have been destroyed)

PHP Code:
Function.prototype.bind = function (obj) {
    var 
fn this;
    return function () {
        return 
fn.apply(objarguments);
    }
}; 
without the closure, the variable fn would be destroyed after calling (local variables exist only while the function is called). due to the closure, JS "remembers" (keeps in memory) the value of fn (in this case a reference to a said function object)

Quote:
Originally Posted by DaveyErwin View Post
It returns an Object , don't forget my thanks....uh
lol
__________________
please post your code wrapped in [CODE] [/CODE] tags

Last edited by Dormilich; 09-01-2010 at 09:40 AM..
Dormilich is offline   Reply With Quote
Old 09-01-2010, 12:42 PM   PM User | #19
DaveyErwin
Regular Coder

 
Join Date: Aug 2010
Posts: 814
Thanks: 12
Thanked 168 Times in 166 Posts
DaveyErwin is on a distinguished road
Quote:
Originally Posted by Dormilich View Post
you’re misunderstanding closures. a closure not only has access to its inner and outer variables, it also preserves them over the usual lifetime. (basically having acces to variables that would normally have been destroyed)

PHP Code:
Function.prototype.bind = function (obj) {
    var 
fn this;
    return function () {
        return 
fn.apply(objarguments);
    }
}; 
without the closure, the variable fn would be destroyed after calling (local variables exist only while the function is called). due to the closure, JS "remembers" (keeps in memory) the value of fn (in this case a reference to a said function object)


lol
can you be specific about what i have misunderstood.
i beleve you are deeply mistaken.
DaveyErwin is offline   Reply With Quote
Old 09-01-2010, 05:05 PM   PM User | #20
Dormilich
Senior Coder

 
Dormilich's Avatar
 
Join Date: Jan 2010
Location: Behind the Wall
Posts: 2,907
Thanks: 10
Thanked 293 Times in 289 Posts
Dormilich is on a distinguished road
Quote:
Originally Posted by DaveyErwin View Post
can you be specific about what i have misunderstood.
i beleve you are deeply mistaken.
this was the answer to post #15. it’s not directly related to your post above it.
__________________
please post your code wrapped in [CODE] [/CODE] tags
Dormilich is offline   Reply With Quote
Old 09-01-2010, 06:16 PM   PM User | #21
DaveyErwin
Regular Coder

 
Join Date: Aug 2010
Posts: 814
Thanks: 12
Thanked 168 Times in 166 Posts
DaveyErwin is on a distinguished road
Quote:
Originally Posted by Dormilich View Post
this was the answer to post #15. it’s not directly related to your post above it.
Sorry, myBad.
Overly defensive by nature.
DaveyErwin is offline   Reply With Quote
Old 09-01-2010, 08:03 PM   PM User | #22
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,553
Thanks: 9
Thanked 480 Times in 463 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
Originally Posted by DaveyErwin View Post
Quote that spec please.
Also the specs are not implimintation.
It is always an object .
Explain the process of conversion.

all implementations follow the spec (more or less), that's why they are interoperable.

Code:
// ALL true:
typeof "wrong" === "string";
typeof 7734 === "number";
typeof "wrong".bold() === "string";
check yourself before you wreck yourself.
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:15.2% IE7:0.5% IE8:8.4% IE9:8.5% IE10:8.5%
rnd me is offline   Reply With Quote
Old 09-01-2010, 09:00 PM   PM User | #23
DaveyErwin
Regular Coder

 
Join Date: Aug 2010
Posts: 814
Thanks: 12
Thanked 168 Times in 166 Posts
DaveyErwin is on a distinguished road
Quote:
Originally Posted by rnd me View Post
all implementations follow the spec (more or less), that's why they are interoperable.

Code:
// ALL true:
typeof "wrong" === "string";
typeof 7734 === "number";
typeof "wrong".bold() === "string";
check yourself before you wreck yourself.
The string is an object that has the ability to
reveal its self as a string . It is always an object.
DaveyErwin is offline   Reply With Quote
Old 09-01-2010, 09:02 PM   PM User | #24
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,556
Thanks: 62
Thanked 4,054 Times in 4,023 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Give it up, RndMe. He won't read the specifications. He thinks he knows the answers without reading them.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 09-01-2010, 09:20 PM   PM User | #25
DaveyErwin
Regular Coder

 
Join Date: Aug 2010
Posts: 814
Thanks: 12
Thanked 168 Times in 166 Posts
DaveyErwin is on a distinguished road
Quote:
Originally Posted by Old Pedant View Post
Give it up, RndMe. He won't read the specifications. He thinks he knows the answers without reading them.
Please quote the relevant text.
DaveyErwin is offline   Reply With Quote
Old 09-01-2010, 09:44 PM   PM User | #26
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,556
Thanks: 62
Thanked 4,054 Times in 4,023 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
http://interglacial.com/javascript_s...4.html#a-4.3.2

That's exactly what it says in the PDF doc on the official ECMA site, but in HTML form so easy to refer to.

Also 4.3.9, 4.3.11, 4.3.13, 4.3.16, 4.3.19

Note the distinctions that are *CAREFULLY* made between type and object. For example, 4.3.17 vs. 4.3.18 and 4.3.20 vs. 4.3.21.

See also chapters 8 and 9.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 09-01-2010, 10:18 PM   PM User | #27
DaveyErwin
Regular Coder

 
Join Date: Aug 2010
Posts: 814
Thanks: 12
Thanked 168 Times in 166 Posts
DaveyErwin is on a distinguished road
Quote:
Originally Posted by Old Pedant View Post
http://interglacial.com/javascript_s...4.html#a-4.3.2

That's exactly what it says in the PDF doc on the official ECMA site, but in HTML form so easy to refer to.

Also 4.3.9, 4.3.11, 4.3.13, 4.3.16, 4.3.19

Note the distinctions that are *CAREFULLY* made between type and object. For example, 4.3.17 vs. 4.3.18 and 4.3.20 vs. 4.3.21.

See also chapters 8 and 9.
Could you please quote the relevant text?
DaveyErwin is offline   Reply With Quote
Old 09-01-2010, 10:31 PM   PM User | #28
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,556
Thanks: 62
Thanked 4,054 Times in 4,023 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
No. That paragraph is two short sentences long. It's all relevant. Read it.

I'm not continuing this thread.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 09-01-2010, 10:33 PM   PM User | #29
DaveyErwin
Regular Coder

 
Join Date: Aug 2010
Posts: 814
Thanks: 12
Thanked 168 Times in 166 Posts
DaveyErwin is on a distinguished road
Unhappy

Quote:
Originally Posted by old pedant View Post
no. That paragraph is two short sentences long. It's all relevant. Read it.

I'm not continuing this thread.
DaveyErwin is offline   Reply With Quote
Old 09-01-2010, 10:41 PM   PM User | #30
gmatrix21
New to the CF scene

 
Join Date: Sep 2010
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
gmatrix21 is an unknown quantity at this point
We treat our advertisers and publishers not only as business partners but also as family. We deliver the highest ROI and have a strong management team to meet both our advertisers and publishers needs to grow both their businesses.

http://www.globalmatrixmedia.com/
gmatrix21 is offline   Reply With Quote
Reply

Bookmarks

Tags
function, javascript, object, return

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 03:13 AM.


Advertisement
Log in to turn off these ads.