(This one twisted my head in circles even after I read the explanation twice, so I’m writing it all out.)

In JavaScript, you can write this:

1
2
3
["a"].map(function(str) {
return str.trim();
});
["a"].map(function(str) {
return str.trim();
});

But can you do this?

1
["a"].map(String.prototype.trim);
["a"].map(String.prototype.trim);

The answer is no. This would run trim(“a”), instead of “a”.trim(). String.prototype.trim doesn’t take the string as the first argument; it takes it as the context (You can see the context in a debugger by looking at the value of this).

JavaScript has a way of changing this though, .call():

1
2
3
4
5
function a() {
return this.name;
}
var b = { "name": "x" };
a.call(b); //returns b.name
function a() {
return this.name;
}
var b = { "name": "x" };
a.call(b); //returns b.name

So can you do this?

1
["a"].map(String.prototype.trim.call);
["a"].map(String.prototype.trim.call);

The answer is no. The confusing way to explain this: this is wrong, but a different this.

To explain more clearly, let’s ask: How does .call() work?

Let’s make up a fake variant of JavaScript, that’s almost the same as regular JS. In our version though, we write out this as the first argument (exactly like Python):

1
2
3
function a(this) {
return this.name;
}
function a(this) {
return this.name;
}

What’s the difference between these three?

1
2
3
4
5
6
7
8
9
10
//Way 1
a();
 
//Way 2
var b = {};
b.getName = a;
b.getName();
 
//Way 3
a.call(b);
//Way 1
a();

//Way 2
var b = {};
b.getName = a;
b.getName();

//Way 3
a.call(b);
  • Way 1: If we execute a() without specifying this, this is the global context (window if you’re in a browser).
    Result: a(this = window)
  • Way 2: If we run the function as a dot function under b, this will be set to b. b.getName() will return b.name;
    Result: a(this = b)
  • Way 3 is exactly the same as Way 2. By using call(), this will be set to b. a.call(b) will return b.name.
    Result: a(this = b)

So far, so good.

Now, how about [“a”].map(String.prototype.trim.call)?

On the surface, if we follow our rules, map will run String.prototype.trim.call() on “a”. This ought to be String.prototype.trim(this = “a”).

It’s not, though, and therein lies the trick. Remember the difference between Way 1 and Way 2; a function’s context changes based on how we call it. Calling a() on its own gives us a different this from calling a() as b.getName(). In this case, this matters because call() itself is a function.

If we use our variant of JavaScript where we explicitly write this as the first argument (here we’ll call it func), call() would look like:

1
2
3
Function.prototype.call = function(func, newContext, moreArguments) {
//func(moreArguments), where the "this" inside func is set to newContext
};
Function.prototype.call = function(func, newContext, moreArguments) {
//func(moreArguments), where the "this" inside func is set to newContext
};

call() only works if that implicit argument — the context — is correct. If I write:

1
2
3
4
5
6
//Version 1
String.prototype.trim.call("a")
 
//Version 2
var calltrim = String.prototype.trim.call;
calltrim("a");
//Version 1
String.prototype.trim.call("a")

//Version 2
var calltrim = String.prototype.trim.call;
calltrim("a");
  • Version 1 will return a trimmed version of “a”.
    Result: Function.prototype.call(func = String.prototype.trim, “a”)
  • Version 2: Here, calltrim’s “func” is no longer String.prototype.trim. Instead, it’s the global context.
    Result: Function.prototype.call(func = window, “a”)

That’s probably the best I can explain it for now. Leave a note if you found this helpful.

The EFF has a great guide on protecting your privacy. One of the things they go over is Threat Modeling. A lot of people are thinking about the NSA lately, but frankly the NSA doing NSA things can get into your phone if they really want to.

I made a quick list of the sorts of things you might feel digitally threatened by:

  • Mossad doing Mossad things (a large government actor)
  • Leaving your phone in a car and someone taking it (theft)
  • The local police trying to tap your phone to catch you selling drugs (small government actors)
  • A rival corporation wants your secrets (corp)
  • Stalkers and paparazzi (individuals)
  • A corporation building a database about you so they can sell you dog food (corporation)

There’s an almost infinite list of hypothetical people who want to get into your phone and see the pictures of the chocolate cake you ate for lunch #skipday. How do we narrow it down? Well, it seems to boil down to a few things.

  1. Is it a government that has legal options (wiretaps, search warrants) for looking into your data?
  2. Is it one person or a corporation/organization, aka, how much money do they have?
  3. Are they spying on you specifically or are they just casting a wide net?

Between those 3 options, you can pretty much identify every actor that might want to look at you.

It’s well known that index funds often perform better than more, ahem, actively managed investments. But which index fund is the most index-y of all? SPY only covers the S&P 500, which is only the 500 largest common stock companies in the US. In addition, possibly because it’s the most well known, its expense ratio is slightly higher than IVV and VOO.

The iShares Russell 3000 ETF (IWV) covers 3000 stocks with an expense ratio of 0.20%, and the Vanguard Total Stock Market ETF (VTI) covers 3796 stocks with an expense ratio of 0.05%. If you’re looking for the largest number with the smallest ratio, you could do far worse than the VTI.

Chart of all three

Like jQuery, the interface is method chaining, except when it isn’t. You can do this, for example:

1
d3.selectAll('p').style('color', 'blue').data('i-am-a-blue-paragraph').append('a');
d3.selectAll('p').style('color', 'blue').data('i-am-a-blue-paragraph').append('a');

but this will give you a different result:

1
d3.selectAll('p').append('a').style('color', 'blue').data('i-am-a-blue-paragraph');
d3.selectAll('p').append('a').style('color', 'blue').data('i-am-a-blue-paragraph');

Some methods return the original selection, but others change it. data() and style() don’t change your selection, but append() and enter() do. This wouldn’t be a problem if each method in the chain didn’t visually look exactly the same, but since they do, you just have to use your instinct to determine what a method returns (which should usually be right), and look it up when you’re not sure.

You might prefer the explicitness of something like:

1
2
var allP = d3.selectAll('p').style('color', 'blue').data('i-am-a-blue-paragraph');
var a = allP.append('a');
var allP = d3.selectAll('p').style('color', 'blue').data('i-am-a-blue-paragraph');
var a = allP.append('a');