getify / You-Dont-Know-JS

A book series on JavaScript. @YDKJS on twitter.
Other
179.5k stars 33.5k forks source link

"this & object prototypes": cover strict mode `this` differences #208

Open getify opened 10 years ago

getify commented 10 years ago

Apparently in ES6 strict mode, this values of primitives are no longer boxed. News to me!

function foo() {
   "use strict";
   console.log(typeof this);
}

foo.call("hello"); // "string"

https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects

"...means that the this value is used exactly as provided by an invocation of the function"

(credit to @webreflection -- https://twitter.com/webreflection/status/522389313800400896)

WebReflection commented 10 years ago

thanks for the mention, probably worth mentioning that as soon as the outer scope runs in 'use strict' every callback is affected, included the this passed to Array extras.

(function(){
  'use strict';
  console.log([1, 2, 3].some(function(i) {
    return i === this;
  }, 2));
}());

Cheers

RReverser commented 10 years ago

Yes, the only place not affected is prototype (as methods still require boxing):

String.prototype.doThis = function () { console.log(typeof this) };
'abc'.doThis();
WebReflection commented 10 years ago

no @RReverser you forgot the 'use strict' directive, there's no exception to the rule.

String.prototype.doThis = function () { 'use strict'; console.log(typeof this) };
'abc'.doThis();

// string
anba commented 10 years ago

this binding for strict mode functions was already defined that way in ES5 (http://ecma-international.org/ecma-262/5.1/#sec-10.4.3 - step 1).

getify commented 10 years ago

facepalm

WebReflection commented 10 years ago

thanks @anba … I actually forgot it went in as part of ES5 spec but I am pretty sure some browser in between ( iOS5.1 or Android 2.2 ) didn't get that right.

Good to know that's a valid, modern, expectation for a context, it also makes sense since ES5 introduced this as undefined which is a different typeof too …. the takeaway: don't believe this is always an object, it can be anything ( so be aware … and use it when convenient )

Cheers to you all