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
Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Raskolnikov2089 posted:

Urgh. Long day


http://jsfiddle.net/tr6abac4/8/

I just don't understand why my first console.log reflects the changeStuff() updated values, when it hasn't even run yet.

*edit - got rid of the console.log workaround from http://jsfiddle.net/tr6abac4/5/

What Sedro said. Here's a visual confirmation: http://jsfiddle.net/tr6abac4/10/

You'll notice that, in at least chrome, you can get it to display DIFFERENT THINGS based on WHEN you inspect the object. If you load that link, then "open up" your object before pressing the button, you'll see the initial values. If you then press the button, you'll see a 2nd log with the updated values while the first log still shows the "old" ones.

If you reload and do not "drill down" into the array in the console and immediately press the button, the first log will show the updated "new" values as well! This is because it's lazily getting the state of the stuff in the array only when you ask for it.

That's why the console will give you the "correct" value when you specified myArray[0].amount: it went and looked up the value at that moment.

Adbot
ADBOT LOVES YOU

Raskolnikov2089
Nov 3, 2006

Schizzy to the matic

Lumpy posted:

What Sedro said. Here's a visual confirmation: http://jsfiddle.net/tr6abac4/10/

You'll notice that, in at least chrome, you can get it to display DIFFERENT THINGS based on WHEN you inspect the object. If you load that link, then "open up" your object before pressing the button, you'll see the initial values. If you then press the button, you'll see a 2nd log with the updated values while the first log still shows the "old" ones.

If you reload and do not "drill down" into the array in the console and immediately press the button, the first log will show the updated "new" values as well! This is because it's lazily getting the state of the stuff in the array only when you ask for it.

That's why the console will give you the "correct" value when you specified myArray[0].amount: it went and looked up the value at that moment.

That is so cool. Thank you guys.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

code:

console.log(JSON.stringify(v));

is frequently found in my scripts.

Sedro
Dec 31, 2008

Raskolnikov2089 posted:

That is so cool. Thank you guys.
There was probably a time when it would print [object Object] to the console.

An interesting side effect is that printing an object to the console will prevent it from being garbage collected (depending on the browser)

PleasureKevin
Jan 2, 2011

is this annoying

code:
// does work

getArticle()
	.spread( function( article, meta ) {
		replaceImages( article, meta )			   
	})
	
// does not work
	
getArticle()
	.spread( replaceImages( article, meta ) )
like there has to be an anonymous function in between?

PleasureKevin fucked around with this message at 20:09 on Feb 18, 2015

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

PleasureKevin posted:

is this annoying

code:
// does work

getArticle()
	.spread( function( article, meta ) {
		replaceImages( article, meta )			   
	})
	
// does not work
	
getArticle()
	.spread( replaceImages( article, meta ) )
like there has to be an anonymous function in between?

The first passes the (anonymous) function which calls replaceImages() to spread(). The second passes whatever is returned by replaceImages() to spread(). These are very different things.

e: That is, spread() here wants a function to be passed into it. replaceImages(article, meta) isn't a function - it's a function call, and it returns something else (possibly null) which is what gets passed into [fixed]spread()[fixed].

Newf fucked around with this message at 20:26 on Feb 18, 2015

Sedro
Dec 31, 2008
You probably meant to do this:
JavaScript code:
getArticle().spread(replaceImages);
Although that is not strictly equivalent to your original code

necrotic
Aug 2, 2005
I owe my brother big time for this!
JavaScript code:
getArticle().spread(replaceImages.bind(this, article, meta));
would be

PleasureKevin
Jan 2, 2011

Sedro posted:

You probably meant to do this:
JavaScript code:
getArticle().spread(replaceImages);
Although that is not strictly equivalent to your original code

oh, yeah

thanks

IAmKale
Jun 7, 2007

やらないか

Fun Shoe
I have a Sharepoint Javascript CSOM question: how can I view all of a ListItem's fields if I don't know any of the field names? I created a Discussion list in a site I'm working on and I'm not exactly sure what other fields I have access to beyond "Title". I've output a ListItem to the console but it's just so incredibly deep hierarchy-wise that it's almost impossible make heads or tails of it. I'm stuck using CSOM API calls like get_item("name") to retrieve the info I want.

Edit: The answer is ListItemCollection.itemAt(0).get_fieldValues();

IAmKale fucked around with this message at 22:01 on Feb 19, 2015

Vulture Culture
Jul 14, 2003

I was never enjoying it. I only eat it for the nutrients.

necrotic posted:

JavaScript code:
getArticle().spread(replaceImages.bind(this, article, meta));
would be
article and meta are undefined in this scope

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

Misogynist posted:

article and meta are undefined in this scope

Oh, of course.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Karthe posted:

get_fieldValues();

Oh wow, try choosing a naming convention.

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.
Lots of js libraries have methods / constructors that take (sometimes) large configuration objects as parameters. Eg, a circle drawing method might have a signature DrawingLib.drawCircle(options) where options is an object of the form { center_x : 12, center_y : 10, radius : 4, color : ... }, where all of the parametrization values are optional and have default values when not set.

Does this technique have a name or a set of best practices which I could research?

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

Wheany posted:

Oh wow, try choosing a naming convention.

verb_adjectiveNoun is a convention :)

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

Newf posted:

Lots of js libraries have methods / constructors that take (sometimes) large configuration objects as parameters. Eg, a circle drawing method might have a signature DrawingLib.drawCircle(options) where options is an object of the form { center_x : 12, center_y : 10, radius : 4, color : ... }, where all of the parametrization values are optional and have default values when not set.

Does this technique have a name or a set of best practices which I could research?

It's sort of like named parameters in other languages because you can use an object literal when calling the function.

Edit: In case that wasn't clear, you just call the function like DrawingLib.drawCircle({center_x : 12, center_y : 10, radius : 4, color : ... }) instead of making a new object.

HappyHippo fucked around with this message at 16:56 on Feb 24, 2015

EVGA Longoria
Dec 25, 2005

Let's go exploring!

Newf posted:

Lots of js libraries have methods / constructors that take (sometimes) large configuration objects as parameters. Eg, a circle drawing method might have a signature DrawingLib.drawCircle(options) where options is an object of the form { center_x : 12, center_y : 10, radius : 4, color : ... }, where all of the parametrization values are optional and have default values when not set.

Does this technique have a name or a set of best practices which I could research?

Ruby calls this hash args, but I'm not aware of any other names.

As far as best practices, don't require too many parameters, provide sane defaults, limit the number of required arguments, and put the required arguments before the options hash (i.e. DrawingLib.drawCircle(center_x, center_y, options) if you required both center_x and center_y.

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.
Does it seem like a good idea to throw the default values into an options property in the constructor? Or is there some way to punt it to the prototype (yadda yadda saving memory)?

JavaScript code:
function Circle (options) {
	this.options = { // defaults
		radius : 1,
		x : 0,
		y : 0
	};

	for (var key in options){
		this.options[key] = options[key]; // change what the user submits
	}
}

var circle = new Circle({radius : 2});
var circle2 = new Circle();

alert(circle.options.radius); // 2
alert(circle2.options.radius); // 1

Ranzear
Jul 25, 2013

Newf posted:

JavaScript code:
	[...]
		if (options.hasOwnProperty(key))
			this.options[key] = options[key]; // change what the user submits
	[...]
Otherwise errors, best I know.

You can also do it the other way around, because I have an irrational hatred for comments when it could be written more obviously:
JavaScript code:
function Circle (options) {
	var defaults = {
		radius : 1,
		x : 0,
		y : 0
	};

	for (var key in defaults){
		if (!options.hasOwnProperty(key))
			options[key] = defaults[key];
	}
}

Ranzear fucked around with this message at 03:09 on Feb 25, 2015

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

Ranzear posted:

JavaScript code:
if (Object.prototype.hasOwnProperty.call(options, key)) {
}

Guarantees no errors (as options.hasOwnProperty can be changed). I've started going with Object.keys to remove that dumb loving call. Downside is the scope change, but in most cases it's not that bad.

code:
Object.keys(options).forEach(function(key) {
});
Also, if you have jQuery or underscore you can do options = $.extend({}, options, defaults); or options = _.extend({}, options, defaults)

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

necrotic posted:

Guarantees no errors (as options.hasOwnProperty can be changed).

Object.prototype.hasOwnProperty = function () {alert('butts')}

For default values, I prefer the || operator:

JavaScript code:

function whatever(qqq, www, options) {
	options = options || {};

	var buns = options.buns || "large";
	// etc
}

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

Wheany posted:

Object.prototype.hasOwnProperty = function () {alert('butts')}

For default values, I prefer the || operator:

JavaScript code:

function whatever(qqq, www, options) {
	options = options || {};

	var buns = options.buns || "large";
	// etc
}

Ah, this is great, and not at all what I would have expected to happen with || (eg, I would have expected it return true/false). This more or less replaces the null coalescing operator and slots in nicely with what I'd like to do.

Thanks much all.

Sergeant Rock
Apr 28, 2002

"... call the expert at kissing and stuff..."
ES6 allows your defaults to appear in the function args:

function spud(blah = 'default')

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

necrotic posted:

Guarantees no errors (as options.hasOwnProperty can be changed).

At the limit, Object.prototype.hasOwnProperty can be changed as well, of course, but it's rarer and usually compatible when things like that happen.

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

Subjunctive posted:

At the limit, Object.prototype.hasOwnProperty can be changed as well, of course, but it's rarer and usually compatible when things like that happen.

Yeah, that's true, but if you use something like jQuery you would notice very quickly if the root Object.prototype.hasOwnProperty was overridden (unless you changed it after including, I guess). Most of the time its not a problem anyway, but its good to understand why it can be an issue.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
Does anything change hasOwnProperty anywhere?

Or are you defending against var butt = Object.create(null) when you use hasOwnProperty from the object prototype?

Does anything use that?

Ranzear
Jul 25, 2013

Wheany posted:

Does anything change hasOwnProperty anywhere?

Sounds like a good way to break a lot of poo poo needlessly.

Of course nothing guarantees no errors, but his old code would have just errored.

Because I'm super lazy, I proto 'hasOwnProperty' into just 'has'. If memory is an issue, you're probably missing hardware acceleration and other poo poo you'll need to run my code anyway.

Ranzear fucked around with this message at 22:22 on Feb 25, 2015

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

Wheany posted:

Does anything change hasOwnProperty anywhere?

Maybe like, evil.js. But nobody would seriously do it. Just use Object.keys, though. It ensures you get only the actual properties of the object, not crap from the prototype chain.

Ranzear
Jul 25, 2013

necrotic posted:

Just use Object.keys, though. It ensures you get only the actual properties of the object, not crap from the prototype chain.

hasOwnProperty ignores prototype chain. Thats what the 'own' part means. It's also crazy optimized in just about every setting.

If you're using Object.keys you're wasting time and lines to then have to iterate it.

It really doesn't matter performance wise, and you'll cut the iteration for a single hasOwnProp lookup which is redundant in that bench, so go with what's most obvious and readable.

If you've got proto chain problems, stop using crutch and kludge libraries. ES5+ES6 shim at worst.

Ranzear fucked around with this message at 18:29 on Feb 28, 2015

qntm
Jun 17, 2009

Ranzear posted:

JavaScript code:
function Circle (options) {
	var defaults = {
		radius : 1,
		x : 0,
		y : 0
	};

	for (var key in defaults){
		if (!options.hasOwnProperty(key))
			options[key] = defaults[key];
	}
}

I advise against modifying the content of an object passed into a function. This has side-effects which are visible to the caller. The most obvious time when this is a problem is if someone wants to use the same collection of options to create several different Circles objects.

Ranzear
Jul 25, 2013

qntm posted:

if someone wants to use the same collection of options to create several different Circles objects.

I'm not seeing the argument, because they'd be getting the same defaults, and those defaults filling in for sparse parameters were the only reason an options object was being passed and created in the first place.

You could also just not be lazy and pass everything as regular parameters.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

The real point is that you don't know what the caller is using the object for, and mutating it is likely to surprise them. (Or throw if they pass something immutable.)

huhu
Feb 24, 2006
First super basic question I'll ask but not the last!

code:
function Animal(name, numLegs) {
    this.name = name;
    this.numLegs = numLegs;
}
Animal.prototype.sayName = function() {
    console.log("Hi my name is " + this.name);
};
Why does the Animal.prototype.sayName function have to go outside of the Animal function? Why can't it be placed inside the Animal function? (Codecadamy.com told me so.)

Pollyanna
Mar 5, 2005

Milk's on them.


Because then that function will be created again every time you create an Animal object. Putting it on the Animal prototype means you just have to walk up the prototype chain to get to sayName() instead of using one of n different versions of sayName().

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
Is there a drawback to using setTimeout with a delay of 0 compared to requestAnimationFrame, when I want something to happen once, asynchronously, some time in the very near future?

I used the code from this page https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery to asyncronously load two css files. The problem browser in this case is Google's own Chrome, though.

I have a small index.html and a spinner graphic that take less than 2 seconds to load even on the slowest network emulation in Chrome (GPRS). The spinner is visible until the main javascript (and CSS) are loaded and initialized (they are several hundreds of kB, so on a slow connection it will take a while).

If I use the snippet in the above link, Chrome will take somewhere close to 15 seconds to show the spinner (from the network tab in the developer tools it seems that it waits for the CSS files to be done loading :downs:)

If I just replace the raf(cb) from the code with a setTimeout(cb, 0), Chrome will show my spinner just fine. Firefox and IE both work in either case. (Using Sloppy to simulate a slow connection)

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
If I have to guess, I'd say that Chrome runs the requestAnimationFrame, then notices that suddenly there are two new CSS files to be downloaded, so it can't draw on the screen now, it'll have to redraw the screen after the files have downloaded!!!

But with the 0-timeout it will probably actually call the code even tens of milliseconds later and has had time to draw the screen already.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
requestAnimationFrame will get you 16ms later, and only if your web page isn't switched away on another tab, the user hasn't minimized the window, etc.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
In this case the only benefit, as far as I can tell, is that you don't have to remember the order of the delay and the callback arguments.

The linked script uses window.addEventListener('load', cb) as the fallback, which makes me wonder if the head tag doesn't exist in some browsers until the page has been fully loaded. But then I feel like those browsers probably wouldn't support addEventListener anyways.

So it could be that google engineers just thought that
JavaScript code:
var raf = requestAnimationFrame || mozRequestAnimationFrame ||
          webkitRequestAnimationFrame || msRequestAnimationFrame;
      if (raf) raf(cb);
      else window.addEventListener('load', cb);
is better than
code:
setTimeout(cb, 0);

MrMoo
Sep 14, 2000

<head> doesn't execute scripts until fully loaded, hence the inlining of scripts for faster execution. The use of RAF is for at least one render, i.e. a pseudo-DOMReady() event handler.

setTimeout(0) is always useful as a yield function as Javascript is a co-operative environment in a single thread.

Adbot
ADBOT LOVES YOU

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Does Javascript have any image processing libraries similar to PIL/Pillow for Python? Or anything that will let me break an animated gif down into individual frame bitmaps. I want to do it client-side if I can, I know you can run something like ImageMagick on a server

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