Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Dr Monkeysee
Oct 11, 2002

just a fox like a hundred thousand others
Nap Ghost

Kobayashi posted:

I don't remember what I was doing, but the other day I ran into the arguments keyword and I feel like I've just fallen down the rabbit hole. I've always known that Javascript is a "prototype based language," and that "functions are first class objects," but I don't think I really "get" what any of that means. With arguments, it seems that function overloading doesn't work the same way that it does in object-oriented languages -- I can call a function with whatever arguments I want and welp, YOLO.

Just a nit-picky technical thing but JavaScript's arguments behavior doesn't have anything to do with being a prototype-based language and method overloading is not an inherent feature of object-oriented languages. Method-overloading is typically a feature of languages that rely on statically-typed method signatures. Some OOP languages have it (Java, C#) and some don't (Smalltalk, Objective-C).

JavaScript does not have statically-typed method definitions and therefore "overloading" doesn't make sense (because there's no information to the interpreter to tell which "foo" method you're trying to call). arguments is a particular quirk of JavaScript but other languages have something sorta similar (C# has params arguments, C/C++ has variadic functions, and nearly every dynamic language has *some* way of passing arbitrary arg lists to methods).

Dr Monkeysee fucked around with this message at 22:07 on Aug 15, 2014

Adbot
ADBOT LOVES YOU

necrotic
Aug 2, 2005
I owe my brother big time for this!

Dr Monkeysee posted:

arguments is a particular quirk of JavaScript but other languages have something sorta similar (C# has params arguments, C/C++ has variadic functions, and nearly every dynamic language has *some* way of passing arbitrary arg lists to methods).

The main difference between Javascript's arguments and other languages is that arguments a) contains all of the passed arguments and b) is not actually an array. Any other language I can think of that supports variable argument definitions has both an explicit way of defining access to them (*args in ruby) and the list of variable arguments is not some special "object".

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

JS arguments, pre-strict is a 2-way binding to the arguments themselves, which I guess is a little unusual. It also includes the named arguments, and not just the variadic "overflow". The non-Array-ness probably cost me 6 months off my life, it's hard to justify given what we know in TYOOL 2014 (or 1999).

Malfeasible
Sep 10, 2005

The sworn enemy of Florin
The book "Effective JavaScript", which was my introduction to the JavaScript rabbit hole, recommends converting it to an Array if you are going to use it. At least I think I remember it saying that, I don't have it on hand at the moment.
code:
var args = [].slice.call(arguments);
I like the idea of using an options object if there are going to be a lot of arguments. I find it irritating to have to worry about what order all my args are in.
code:
var options = {"fname":"Jon", "lname":"Smith", "age":50};
exampleFunction(options);
edit:

Subjunctive posted:

JS arguments, pre-strict is a 2-way binding to the arguments themselves, which I guess is a little unusual. It also includes the named arguments, and not just the variadic "overflow". The non-Array-ness probably cost me 6 months off my life, it's hard to justify given what we know in TYOOL 2014 (or 1999).

Can you elaborate a little on the implications of that 2-way binding? Are you saying the strict pragma prevents that binding? Does putting the arguments into an Array before working with them accomplish the same thing (aside from also enabling the use of Array methods on the arguments collection)?

Malfeasible fucked around with this message at 04:45 on Aug 16, 2014

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Malfeasible posted:

The book "Effective JavaScript", which was my introduction to the JavaScript rabbit hole, recommends converting it to an Array if you are going to use it. At least I think I remember it saying that, I don't have it on hand at the moment.
code:

var args = [].slice.call(arguments);

The ugliness of that haunts me at least weekly. Would Arguments.prototype.toArray() have killed us? No, no it would not have.

quote:

I like the idea of using an options object if there are going to be a lot of arguments. I find it irritating to have to worry about what order all my args are in.
code:

var options = {"fname":"Jon", "lname":"Smith", "age":50};
exampleFunction(options);

I think at least one JS engine optimizes away the object creation and assignments if the extraction in the callee is straightforward enough, too. It's a good pattern.

Malfeasible
Sep 10, 2005

The sworn enemy of Florin

Subjunctive posted:

JS arguments, pre-strict is a 2-way binding to the arguments themselves, which I guess is a little unusual. It also includes the named arguments, and not just the variadic "overflow". The non-Array-ness probably cost me 6 months off my life, it's hard to justify given what we know in TYOOL 2014 (or 1999).

I did a quick test in Firebug to see this in action.

code:
function testFunction(first, second) {
    //"use strict";
    
    var argsArray = Array.prototype.slice.call(arguments);
    
    console.log("named argument: " + first);
    console.log("named argument: " + second);
    console.log("arguments: " + arguments[0]);
    console.log("arguments: " + arguments[1]);
    console.log("Array[0]: " + argsArray[0]);
    console.log("Array[1]: " + argsArray[1]);
    
    // these assignments have no effect on the argsArray elements
    // and only affect the arguments object when not in strict mode
    first = "edited 1";
    second = "edited 2";
    
    console.log("named argument: " + first);
    console.log("named argument: " + second);
    console.log("arguments: " + arguments[0]);
    console.log("arguments: " + arguments[1]);
    console.log("Array[0]: " + argsArray[0]);
    console.log("Array[1]: " + argsArray[1]);
}

testFunction("one", "two");
Output with "use strict" commented out:
named argument: one
named argument: two
arguments: one
arguments: two
Array[0]: one
Array[1]: two
named argument: edited 1
named argument: edited 2
arguments: edited 1
arguments: edited 2
Array[0]: one
Array[1]: two


Output with "use strict" pragma:
named argument: one
named argument: two
arguments: one
arguments: two
Array[0]: one
Array[1]: two
named argument: edited 1
named argument: edited 2
arguments: one
arguments: two
Array[0]: one
Array[1]: two

qntm
Jun 17, 2009

Skiant posted:

They have almost a whole page inside explaining that they know the difference for assholes like you.

So?

Peanut and the Gang
Aug 24, 2009

by exmarx

qntm posted:

Which has a samurai on the cover...

Skiant posted:

They have almost a whole page inside explaining that they know the difference for assholes like you.

The moral of the story is: Don't judge a book by its cover.

Chenghiz
Feb 14, 2007

WHITE WHALE
HOLY GRAIL
John Resig is a huge ukiyo-e nerd (he runs http://ukiyo-e.org/) so I feel like that explains the cover adequately. Also, he's a really smart guy and knows javascript well.

qntm
Jun 17, 2009

Peanut and the Gang posted:

The moral of the story is: Don't judge a book by its cover.

Well, sure, it would be difficult for the interior of this book to be dumber than its exterior.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

necrotic posted:

The main difference between Javascript's arguments and other languages is that arguments a) contains all of the passed arguments and b) is not actually an array. Any other language I can think of that supports variable argument definitions has both an explicit way of defining access to them (*args in ruby) and the list of variable arguments is not some special "object".
The overflow part being wacky and different from everything else in the language isn't that unusual. Lua's ... is mostly sane but it a data structure you don't encounter anywhere else in the language, and of course C's varargs are incredibly weird and different.

Dr Monkeysee
Oct 11, 2002

just a fox like a hundred thousand others
Nap Ghost

necrotic posted:

The main difference between Javascript's arguments and other languages is that arguments a) contains all of the passed arguments and b) is not actually an array. Any other language I can think of that supports variable argument definitions has both an explicit way of defining access to them (*args in ruby) and the list of variable arguments is not some special "object".

arguments is definitely quirky. I just wanted to stress there's nothing particularly OOP or prototype-y about it. It's just a thing that has similar parallels in other, unrelated, languages.

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.
Finally resorting to learning from the ground up, I'm reading through Mozilla's Working With Objects tutorial. I'm confused by the following snippet:

JavaScript code:
function showProps(obj, objName) {
  var result = "";
  for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
        result += objName + "." + i + " = " + obj[i] + "\n";
    }
  }
  return result;
}
Is the if(obj.hasOwnProperty(i)) call here redundant? Doesn't the foreach loop construct enumerate the properties that would pass this test?

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Newf posted:

Finally resorting to learning from the ground up, I'm reading through Mozilla's Working With Objects tutorial. I'm confused by the following snippet:

JavaScript code:
function showProps(obj, objName) {
  var result = "";
  for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
        result += objName + "." + i + " = " + obj[i] + "\n";
    }
  }
  return result;
}
Is the if(obj.hasOwnProperty(i)) call here redundant? Doesn't the foreach loop construct enumerate the properties that would pass this test?

for (var i in obj) iterates obj's own and inherited properties.
obj.hasOwnProperty returns true only for non-inherited properties.

JavaScript code:
var obj1 = {
	prop1: 'hello', 
	prop2: 'hello2'
};

var Example = function () { 
	this.prop3='hello3'; // set own property
}
Example.prototype = obj1;

var obj2 = new Example();

console.log('without hasOwnProperty:');
for (var prop in obj2) { 
	console.log(prop + ':' + obj2[prop]); 
}

console.log('with hasOwnProperty:');
for (var prop in obj2) { 
	if (obj2.hasOwnProperty(prop)) {
		console.log(prop + ':' + obj2[prop]); 
	}
}
output:
code:
without hasOwnProperty:
prop3:hello3
prop1:hello
prop2:hello2
with hasOwnProperty:
prop3:hello3

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Newf posted:

Finally resorting to learning from the ground up, I'm reading through Mozilla's Working With Objects tutorial. I'm confused by the following snippet:

JavaScript code:
function showProps(obj, objName) {
  var result = "";
  for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
        result += objName + "." + i + " = " + obj[i] + "\n";
    }
  }
  return result;
}
Is the if(obj.hasOwnProperty(i)) call here redundant? Doesn't the foreach loop construct enumerate the properties that would pass this test?

I don't see a forEach loop?

If you don't use hasOwnProperty you will get properties from further up the prototype chain. The in operator iterates over all properties.

Raskolnikov2089
Nov 3, 2006

Schizzy to the matic
Haven't been able to find this in google, but if I set a for loop like so:

code:
function doSomething(){
	for(i=0; i< length; i++){}
}
Aren't I making i a global variable since I'm not declaring it as

code:
for(var i=0; i< length; i++){}
I'm a bit confused since I see examples both ways, without an indication of which is best.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Raskolnikov2089 posted:

I'm a bit confused since I see examples both ways, without an indication of which is best.

Use more functions.

It's the only scope Javascript has

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Raskolnikov2089 posted:

code:

function doSomething(){
	for(i=0; i< length; i++){}
}

Aren't I making i a global variable since I'm not declaring it as

Yes, you are. Congrats, you're well on your way to creating benchmarks that don't test what they think they're testing!

Chenghiz
Feb 14, 2007

WHITE WHALE
HOLY GRAIL

Newf posted:

Finally resorting to learning from the ground up, I'm reading through Mozilla's Working With Objects tutorial. I'm confused by the following snippet:

JavaScript code:
function showProps(obj, objName) {
  var result = "";
  for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
        result += objName + "." + i + " = " + obj[i] + "\n";
    }
  }
  return result;
}
Is the if(obj.hasOwnProperty(i)) call here redundant? Doesn't the foreach loop construct enumerate the properties that would pass this test?

I'm just gonna throw this out there since I learned it recently and felt like a dolt for doing things the hard way, but Object.keys is a much better (and faster) way to iterate over an object's keys, like so:
JavaScript code:
Object.keys(obj).forEach(function (key) {
  console.log('obj.'+key+' is '+obj[key]);
});

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
Be aware that Object.keys() is not supported in < IE9, which can be a bitch if, like me, you're forced to support IE8.

Instead take a look at lo-dash for a whole ton of javascript short cuts.

JavaScript code:
_.each(obj, function(value, key) {
    console.log('obj.'+key+' is '+value);
});

Chenghiz
Feb 14, 2007

WHITE WHALE
HOLY GRAIL

v1nce posted:

Be aware that Object.keys() is not supported in < IE9, which can be a bitch if, like me, you're forced to support IE8.

Instead take a look at lo-dash for a whole ton of javascript short cuts.

JavaScript code:
_.each(obj, function(value, key) {
    console.log('obj.'+key+' is '+value);
});

That's what the es5 shim and sham libraries are for, though. lodash is nice but I think including it just for backwards compatibility is kinda rear end-backwards if you don't need anything else in it and just bloats your modern-browser targeted code.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Chenghiz posted:

I'm just gonna throw this out there since I learned it recently and felt like a dolt for doing things the hard way, but Object.keys is a much better (and faster) way to iterate over an object's keys, like so:
JavaScript code:

Object.keys(obj).forEach(function (key) {
  console.log('obj.'+key+' is '+obj[key]);
});

Is that faster? I guess if forEach and keys are self-hosted, and the function call is inlined? I'm surprised that it can beat for-in, even in those cases, without really aggressive optimizations that I don't think any engines do. (Tracing JITs would have the best odds, I'd think, but no major engine traces these days. :smith:)

Edit: built-in forEach is often slower than a JS version of the same, because of native/script transition costs. That was a bit frustrating to realize after adding the "Array extras", but modern JITs get pretty close when self-hosting those cases.

Subjunctive fucked around with this message at 03:21 on Aug 20, 2014

Chenghiz
Feb 14, 2007

WHITE WHALE
HOLY GRAIL

Subjunctive posted:

Is that faster? I guess if forEach and keys are self-hosted, and the function call is inlined? I'm surprised that it can beat for-in, even in those cases, without really aggressive optimizations that I don't think any engines do. (Tracing JITs would have the best odds, I'd think, but no major engine traces these days. :smith:)

Edit: built-in forEach is often slower than a JS version of the same, because of native/script transition costs. That was a bit frustrating to realize after adding the "Array extras", but modern JITs get pretty close when self-hosting those cases.

IIRC for-in is pretty much the slowest native for-loop in JS. Citing speed is probably unfair of me though because at the end of the day they're all quite fast enough for 99% of applications. I just think Object.keys().forEach is more clear and it avoids the problem that Object.hasOwnProperty() is trying to solve at the same time.

DholmbladRU
May 4, 2006
Building a mobile(ipad) based web app. I am using the jQuery to perform autocomplete. The autocomplete is working however I am unable to scroll through the items. I have attempted to accomplish this via CSS however it does not seem to work. I would like to use javascript to add scroll to the autocomplete, however it seems to not work.

Was attempting to use something similar to below to add scroll, but was unsuccessful.


code:
      document.getElementById(id).addEventListener("touchstart", function(event) {
                    scrollStartPos=this.scrollTop+event.touches[0].pageY;
                    event.preventDefault();
                  
                },false);
                document.getElementById(id).addEventListener("touchmove", function(event) {
                    this.scrollTop=scrollStartPos-event.touches[0].pageY;
                    event.preventDefault();
    
                },false);
Does anyone have experience doing this?

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

Raskolnikov2089 posted:

Haven't been able to find this in google, but if I set a for loop like so:

code:
function doSomething(){
	for(i=0; i< length; i++){}
}
Aren't I making i a global variable since I'm not declaring it as

code:
for(var i=0; i< length; i++){}
I'm a bit confused since I see examples both ways, without an indication of which is best.

I recommend using strict mode whenever possible (generally all new scripts). It forces you to declare all globals explicitly, with var. Attempting to assign to any undeclared variable will cause an error.

DholmbladRU
May 4, 2006

DholmbladRU posted:

Building a mobile(ipad) based web app. I am using the jQuery to perform autocomplete. The autocomplete is working however I am unable to scroll through the items. I have attempted to accomplish this via CSS however it does not seem to work. I would like to use javascript to add scroll to the autocomplete, however it seems to not work.

Was attempting to use something similar to below to add scroll, but was unsuccessful.


code:
      document.getElementById(id).addEventListener("touchstart", function(event) {
                    scrollStartPos=this.scrollTop+event.touches[0].pageY;
                    event.preventDefault();
                  
                },false);
                document.getElementById(id).addEventListener("touchmove", function(event) {
                    this.scrollTop=scrollStartPos-event.touches[0].pageY;
                    event.preventDefault();
    
                },false);
Does anyone have experience doing this?


I was finally able to figure this out.

code:
//get active autocomplete
function getAutoCompleteWithChild(){
   var tmp =  $('.ui-autocomplete');
    for(var i=0; i<tmp.length; i++){
         if ( $(tmp[i]).children().length > 0 ) {
            return $(tmp[i]).attr('id');
        }
    }
}


//allow it to scroll
function touchScroll(id) {
    try {
        var el = document.getElementById(id);
        var scrollStartPos = 0;

        document.getElementById(id).addEventListener("touchstart", function (event) {
            scrollStartPos = this.scrollTop + event.touches[0].pageY;
            event.preventDefault();

        }, false);

        document.getElementById(id).addEventListener("touchmove", function (event) {
            this.scrollTop = scrollStartPos - event.touches[0].pageY;
            event.preventDefault();
        }, false);
    } catch (err) {
        //throw some errors
    }
}

fuf
Sep 12, 2004

haha
Reading some documentation (for Sequelize) and it has this:
code:
   if (!!err) {
what's up with the two nots? Is that a thing?

Peanut and the Gang
Aug 24, 2009

by exmarx

fuf posted:

Reading some documentation (for Sequelize) and it has this:
code:
   if (!!err) {
what's up with the two nots? Is that a thing?

It's trying to convert it to a bool (null/undefined/0/"" would become false), but actually it's superfluous because if-statements already convert the condition to bools anyway.

fuf
Sep 12, 2004

haha
That makes sense, thanks.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Peanut and the Gang posted:

It's trying to convert it to a bool (null/undefined/0/"" would become false), but actually it's superfluous because if-statements already convert the condition to bools anyway.

Yeah that's bad js developer smell seeing the !!.

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.

Bruegels Fuckbooks posted:

Yeah that's bad js developer smell seeing the !!.

Is this necessarily true? I find myself going back and forth a lot on how snappy my judgements on cargo cult practices are.

!! seems at least potentially useful as a shorthand for to replace the comment 'this variable may or may not be a bool at the present moment, but moving forward we're only concerned with treating it as a bool'. Self-commenting code, etc.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
It's in an if statement. It will already be cast to a bool for the purposes of the if statement. It doesn't matter if you cast it yourself.

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.

Suspicious Dish posted:

It's in an if statement. It will already be cast to a bool for the purposes of the if statement. It doesn't matter if you cast it yourself.

Yeah, but the point is that the cast, y'know, casts it for future use, which may be what you want.

JavaScript code:
var hi = "Hello World";
if (hi){
  alert(hi); // "Hello World"
}

if (!!hi){
  alert(hi);  // "true"
}
fake edit: Jesus, having actually run this it turns out that this isn't right. Does the parser remove the !!?

JavaScript code:
var hi = "Hello World";
if (hi){
  alert(hi); // "Hello World"
}

if (!!hi){
  alert(hi);  // "Hello World" ?
}

hi = !!hi;
alert(hi); // "true"
fake edit2: Jesus Christ I'm an idiot. For some reason I had it in my mind that !! should be redefining the variable ala ++. This is not something I actually believe. Please disregard everything I ever say. Probably put me on ignore.

Peanut and the Gang
Aug 24, 2009

by exmarx

Newf posted:

Please disregard everything I ever say. Probably put me on ignore.

Okay. :)

nexus6
Sep 2, 2011

If only you could see what I've seen with your eyes
I'm having an issue in Drupal which I'm pretty sure is JS related but I'm getting no errors or warning in the console at all so I have no idea where to look for a solution.

I have created a content type with a file field that allows unlimited values. When I upload a file I am expecting to be able to immediately upload another file.


but what actually happens is the upload box disappears, meaning I have to save the node and re-edit it in order to upload another file


both these examples have exactly the same content type settings, both running the same version of Drupal. I'm not getting any JS errors or anything. Any ideas on why this is happening?

mmm11105
Apr 27, 2010
Does anyone know of a node libary similar to rail's public_activity, for creating activity feeds for users (similar to your facebook news feed).

peepsalot
Apr 24, 2007

        PEEP THIS...
           BITCH!

Chrome dev tools lets you edit js source of a remote website from within the browser, is there any way to just reload the page with those local modifications applied? Otherwise what is the loving point of letting you edit any of this in browser.

foxy boxing babe
Jan 17, 2010


In the project I'm working on right now, I very often need to loop until a certain condition is met or an amount of time has passed. Since I do it so often, I want to move the code into a generic function to avoid rewriting the same thing again and again. The condition is arbitrary and varies widely depending on the function. The most succinct way I can think of doing this is passing the condition to the function in a string and eval'ing it. I'm wondering if anyone else has any ideas?

code:
function when(condition, callback, invokeTime) {
  var now = new Date().getTime(),
      delta = now - invokeTIme;
  if (delta > maxTime) {
    handleTimeout();
  } else if (eval('(' + condition + ')')) {
    callback();
  } else {
    setTimeout( function () {
      wait(condition, callback, invokeTime ? invokeTime : now);
    }, 100);
  }
}

when('x === y', function () {
  doTheNeedful();
});

foxy boxing babe fucked around with this message at 05:11 on Aug 24, 2014

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
Don't do that. Use condition as a function, it'll be a little more verbose but it's more flexible, reliable, and secure. You also properly maintain variable scope.

code:
when(function() { return x == y }, function () {
  doTheNeedful();
});
Relying on eval is just asking for trouble.

Adbot
ADBOT LOVES YOU

foxy boxing babe
Jan 17, 2010


Yeah, you're right. I didn't like the verbosity of condition as a function, and using eval looked prettier and easier to read, but this is the better choice.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply