Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
this
Search
othree
May 19, 2013
Programming
3.8k
15
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
this
A introduction about this in JavaScript
othree
May 19, 2013
More Decks by othree
See All by othree
How GitHub Supports Vim License Detection, The Five Years Journey
othree
1
2.3k
WAT JavaScript Date
othree
3
2.2k
Modern HTML Email Development
othree
3
2.8k
MRT & GIT
othree
1
2.5k
YAJS.vim and Vim Syntax Highlight
othree
1
3.1k
Web Trends to 2015
othree
4
360
Transducer
othree
9
3.2k
HITCON 11 Photographer
othree
4
550
fetch is the new XHR
othree
6
3.6k
Other Decks in Programming
See All in Programming
Snowflakeで業務アプリを作ろう。 Snowflakeのアプリ機能解説&実践ガイド
ayumu_yamaguchi
1
140
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
0
240
Discordを用いたラボオートメーション関連情報収集の自動化
noguhiro2002
0
500
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
220
バグを直したら useEffect が消えた
colorful12
3
840
AI時代に学ぶ 好きなルール 嫌いなルール Linter編
shorty5121
0
870
「AI時代、配布するPythonコードをどう守るか: 難読化の実験と判断軸」 #PyconJP2026
pkshadeck
PRO
2
170
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
130
新人はどこまで自力でやり、どこからAIに頼るべきか/エンジニア育成に向き合う_先輩たちの悩みと知見共有会
toppan_digital_dev
1
570
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
3
1.5k
Hello, Hiroshima Geospatial Data! — Exploring DoboX with Python
ra0kley
0
170
初心者DevRelとして参加者だった私が、DevRel Talks!#2に登壇するまでにしてきたこと
sokohirai
0
340
Featured
See All Featured
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Designing Powerful Visuals for Engaging Learning
tmiket
1
530
The browser strikes back
jonoalderson
0
1.6k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
Leo the Paperboy
mayatellez
8
2.2k
Music & Morning Musume
bryan
47
7.4k
Code Review Best Practice
trishagee
74
20k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
370
Crafting Experiences
bethany
1
300
Testing 201, or: Great Expectations
jmmastey
46
8.3k
Mobile First: as difficult as doing things right
swwweet
225
10k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.5k
Transcript
this othree@JSDC
None
this • ‘the object’ it belongs in OOP
C++ class Box { public: Box(double l=2.0, double b=2.0, double
h=2.0) { this->length = l; this->breadth = b; this->height = h; } double Volume() { return length * breadth * height; } int compare(Box box) { return this->Volume() > box.Volume(); } private: double length; double breadth; double height; };
Continued.. int main(void) { Box Box1(3.3, 1.2, 1.5); Box Box2(8.5,
6.0, 2.0); cout << Box1.Volume() << endl; // 3.3*1.2*1.5 = 5.94 cout << Box2.Volume() << endl; // 8.5*6.0*2.0 = 102 return 0; }
this • Context in JavaScript • Can mean the object
also
JavaScript var Box = function Box (l, b, h) {
this.length = l; this.breadth = b; this.height = h; }; Box.prototype.Volume = function () { return this.length * this.breadth * this.height; }; Box.prototype.compare = function (box) { return this.Volume() > box.Volume(); };
this in Function • Context • Depends on how you
call the function
3 Way to Call Function var big = function ()
{/*...*/}; var foo = { small: function () {/*...*/} }; big(); // 1. this: window object foo.small(); // 2. this: foo var small = foo.small; small();
3 Way to Call Function var big = function ()
{/*...*/}; var foo = { small: function () {/*...*/} }; big(); // 1. this: window object foo.small(); // 2. this: foo var small = foo.small; small(); // 3. this: window object
Borrowing Method var foo = { small: function () {
this; } }; var bar = {}; foo.small(); // this: foo bar.borrowedSmall = foo.small; bar.borrowedSmall(); // this: bar
this in Global Scope • Root object
Root Object • `window` in browsers • Root object in
other environment
to Support Both (function () { root = this; //blah....
}());
Strict Mode • No more global context
Don’t Forget `new` function Foobar() { "use strict"; this.a =
'foo'; this.b = 'bar'; } var foobar1 = Foobar(); // Cannot set property 'a' of undefined var foobar2 = new Foobar(); // this: new empty object
One More Way to Call Function
apply/call var foo = {}; function foobar(v1, v2) { this.bar1
= v1; this.bar2 = v2; } foobar.call(foo, v1, v2); // this: foo foobar.apply(foo, [v1, v2]); // this: foo
bind var foo = {}; var otherFoo = {}; function
setBar(v1, v2) { this.bar1 = v1; this.bar2 = v2; } var fooSetBar = setBar.bind(foo); fooSetBar(1, 2); // this: foo otherFoo.foobar = fooSetBar; otherFoo.foobar(3, 4); // this: foo
Protect Your Method • Bind context and function together
$.proxy/_.bind • Use apply to implement bind
Implement Bind var bind = function (func, context) { return
function () { func.apply(context, arguments); }; };
Solve Event Handler • Use apply to assign context •
JavaScript Libraries did it for you
this in Event Handler // W3C Dom aElement.addEventListener('click', function ()
{ this; // aElement }, false); // old IE aElement.attachEvent('onclick', function () { this; // window });
Callback Function function Foobar (input) { this.prefix = input; }
Foobar.prototype.echo = function (result) { return this.prefix + result; }; fb = new Foobar(); $.get('/info', function (result) { fb.echo(result); });
Reduce One Stack function Foobar (input) { this.prefix = input;
} Foobar.prototype.echo = function (result) { return this.prefix + result; }; fb = new Foobar(); $.get('/info', fb.echo); // this.prefix is 'undefined'
Use bind function Foobar (input) { this.prefix = input; this.echo
= this.echo.bind(this); // Protect method } Foobar.prototype.echo = function (result) { return this.prefix + result; }; fb = new Foobar(); $.get('/info', fb.echo);
Cons • Performance is bad • Old browser don’t support
Performance http://jsperf.com/bind-vs-closure-setup/10
Pros • Clearer code
Use _.bind function Foobar (input) { this.prefix = input; this.echo
= _.bind(this.echo, this); // function, context } function Foobar (input) { this.prefix = input; _.bindAll(this); // context } http://underscorejs.org/#bind
Use $.proxy function Foobar (input) { this.prefix = input; this.echo
= $.proxy(this.echo, this); // function, context } function Foobar (input) { this.prefix = input; this.echo = $.proxy(this, 'echo'); // context, method name } http://api.jquery.com/jQuery.proxy/
Bind by Need fb = new Foobar(); $.get('/info', $.proxy(fb, 'echo'));
$.get('/info', $.proxy(fb.echo, fb)); $.get('/info', $.bind(fb.echo, fb));
http://www.flickr.com/photos/othree/8544069132/
Avoid Using this
Closure var isIE = true; function foobar() { if (!isIE)
{ // access isIE is possible because of closure return; } // blah... };
that/self function Foobar(input) { var that = this; // that
or self this.prefix = input; this.echo = function (result) { return that.prefix + result; // that is accessible because of closure }; } fb = new Foobar('res: '); $.get('/info', fb.echo);
CoffeeScript Fat Arrow Foobar = (input) -> @prefix = input
@echo = (result) => @prefix + result fb = new Foobar('res: ') $.get('/info', fb.echo)
CoffeeScript Fat Arrow Foobar = (input) -> @prefix = input
@echo = (result) => @prefix + result fb = new Foobar('res: ') $.get('/info', fb.echo)
Compile to JS var Foobar, fb; Foobar = function(input) {
var _this = this; this.prefix = input; return this.echo = function(result) { return _this.prefix + result; }; }; fb = new Foobar('res: '); $.get('/info', fb.echo);
Compile to JS var Foobar, fb; Foobar = function(input) {
var _this = this; this.prefix = input; return this.echo = function(result) { return _this.prefix + result; }; }; fb = new Foobar('res: '); $.get('/info', fb.echo);
Compile to JS var Foobar, fb; Foobar = function(input) {
var _this = this; this.prefix = input; return this.echo = function(result) { return _this.prefix + result; }; }; fb = new Foobar('res: '); $.get('/info', fb.echo);
LiveScript use ~>
Pros • No more this issue, context free • Reduce
one call stack • No call/apply, no impact on performance • Encapsulation
Cons • Can’t use this tip on normal constructor
How about AMD • Define modules can return constructor, function,
array, primitive data • Define a singleton module on most cases • Always have data on module
AMD Singleton Module define('foobar', function () { return { init:
function (prefix) { this.prefix = prefix; } echo: function (input) { return this.prefix + input; } }; });
Cons • Function can be borrowed • Not doing on
right `this` you expect
Avoid Use this define('foobar', function () { var self =
{}; return { init: function (prefix) { self.prefix = prefix; } echo: function (input) { return self.prefix + input; } }; });
Constructors? • Use bind to protect methods if necessary
Constructor Without this function Person(birth, gender) { var person =
{ birth: (birth || '1970/01/01'), gender: (gender || 'M') }; return { getBirth: function () { return person.birth; }, getGender: function () { return person.gender; } }; }
to new or not to new var p1 = Person('2013/01/02');
p1.getBirth(); // "2013/01/02" var p2 = new Person('2000/01/02', 'F'); p2.getBirth(); // "2000/01/02" p1.getBirth(); // "2013/01/02"
Cons • No prototype inheritance • More memory usage for
methods
Backbone Model define(function (require) { return Backbone.Model.extend( initialize: function (attrs)
{ return _.bindAll(this); }, toITEM: function () { return this.toJSON(); }, toConfig: function () { return { name: this.get('name'), package_name: this.get('package_name') }; } ); });
Who Use this Tip • jQuery.Deferred • jQuery.Callbacks
Deferred Chaining var firstDfd = $.Deferred(), secondDfd = $.Deferred(), thirdDfd
= $.Deferred(); firstDfd.done(secondDfd.resolve); secondDfd.done(thirdDfd.resolve); firstDfd.resolve(); // All Deferred object resolved here
Callbacks https://github.com/jquery/jquery/blob/master/src/deferred.js // promise[ done | fail | progress ]
= list.add promise[ tuple[1] ] = list.add; // skip... // deferred[ resolve | reject | notify ] deferred[ tuple[0] ] = function() { deferred[ tuple[0] + "With" ] (this === deferred ? promise : this, arguments); return this; }; deferred[ tuple[0] + "With" ] = list.fireWith;
Callbacks https://github.com/jquery/jquery/blob/master/src/deferred.js // promise[ done | fail | progress ]
= list.add promise[ tuple[1] ] = list.add; // skip... // deferred[ resolve | reject | notify ] deferred[ tuple[0] ] = function() { deferred[ tuple[0] + "With" ] (this === deferred ? promise : this, arguments); return this; }; deferred[ tuple[0] + "With" ] = list.fireWith;
Actually Are promise['done'] = resolveCallbacks.add; promise['fail'] = rejectCallbacks.add; promise['progress'] =
notifyCallbacks.add; // skip... deferred["resolveWith"] = resolveCallbacks.fireWith; deferred["rejectWith"] = rejectCallbacks.fireWith; deferred["notifyWith"] = notifyCallbacks.fireWith;
Summary • Understand `this` • Understand how not to use
`this` • Use `this` carefully if necessary
Trade-Off • ‘Not use this’ requires more memory on methods
definition and not easy to inheritance object • Benefit is you can write more clear, simple code
References
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this
Questions? http://www.flickr.com/photos/roman/5610736/