Your SlideShare is downloading. ×
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
this
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

this

478

Published on

Explain this of JavaScript

Explain this of JavaScript

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
478
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
9
Comments
0
Likes
6
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. thisothree@JSDC
  • 2. this• ‘the object’ it belongs in OOP
  • 3. 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;};
  • 4. 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.94cout << Box2.Volume() << endl; // 8.5*6.0*2.0 = 102return 0;}
  • 5. this• Context in JavaScript• Can mean the object also
  • 6. JavaScriptvar 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();};
  • 7. this in Function• Context• Depends on how you call the function
  • 8. 3 Way to Call Functionvar big = function () {/*...*/};var foo = {small: function () {/*...*/}};big(); // 1. this: window objectfoo.small(); // 2. this: foovar small = foo.small;small();
  • 9. 3 Way to Call Functionvar big = function () {/*...*/};var foo = {small: function () {/*...*/}};big(); // 1. this: window objectfoo.small(); // 2. this: foovar small = foo.small;small(); // 3. this: window object
  • 10. Borrowing Methodvar foo = {small: function () {this;}};var bar = {};foo.small(); // this: foobar.borrowedSmall = foo.small;bar.borrowedSmall(); // this: bar
  • 11. this in Global Scope• Root object
  • 12. Root Object• `window` in browsers• Root object in other environment
  • 13. to Support Both(function () {root = this;//blah....}());
  • 14. Strict Mode• No more global context
  • 15. Don’t Forget `new`function Foobar() {"use strict";this.a = foo;this.b = bar;}var foobar1 = Foobar();// Cannot set property a of undefinedvar foobar2 = new Foobar();// this: new empty object
  • 16. One More Way to CallFunction
  • 17. apply/callvar foo = {};function foobar(v1, v2) {this.bar1 = v1;this.bar2 = v2;}foobar.call(foo, v1, v2); // this: foofoobar.apply(foo, [v1, v2]); // this: foo
  • 18. bindvar foo = {};var otherFoo = {};function setBar(v1, v2) {this.bar1 = v1;this.bar2 = v2;}var fooSetBar = setBar.bind(foo);fooSetBar(1, 2); // this: foootherFoo.foobar = fooSetBar;otherFoo.foobar(3, 4); // this: foo
  • 19. ProtectYour Method• Bind context and function together
  • 20. $.proxy/_.bind• Use apply to implement bind
  • 21. Implement Bindvar bind = function (func, context) {return function () {func.apply(context, arguments);};};
  • 22. Solve Event Handler• Use apply to assign context• JavaScript Libraries did it for you
  • 23. this in Event Handler// W3C DomaElement.addEventListener(click, function () {this; // aElement}, false);// old IEaElement.attachEvent(onclick, function () {this; // window});
  • 24. Callback Functionfunction Foobar (input) {this.prefix = input;}Foobar.prototype.echo = function (result) {return this.prefix + result;};fb = new Foobar();$.get(/info, function (result) {fb.echo(result);});
  • 25. Reduce One Stackfunction 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
  • 26. Use bindfunction 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);
  • 27. Cons• Performance is bad• Old browser don’t support
  • 28. Performancehttp://jsperf.com/bind-vs-closure-setup/10
  • 29. Pros• Clearer code
  • 30. Use _.bindfunction 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
  • 31. Use $.proxyfunction 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/
  • 32. Bind by Needfb = new Foobar();$.get(/info, $.proxy(fb, echo));$.get(/info, $.proxy(fb.echo, fb));$.get(/info, $.bind(fb.echo, fb));
  • 33. http://www.flickr.com/photos/othree/8544069132/
  • 34. Avoid Using this
  • 35. Closurevar isIE = true;function foobar() {if (!isIE) {// access isIE is possible because of closurereturn;}// blah...};
  • 36. that/selffunction Foobar(input) {var that = this; // that or selfthis.prefix = input;this.echo = function (result) {return that.prefix + result;// that is accessible because of closure};}fb = new Foobar(res: );$.get(/info, fb.echo);
  • 37. CoffeeScript Fat ArrowFoobar = (input) ->@prefix = input@echo = (result) => @prefix + resultfb = new Foobar(res: )$.get(/info, fb.echo)
  • 38. CoffeeScript Fat ArrowFoobar = (input) ->@prefix = input@echo = (result) => @prefix + resultfb = new Foobar(res: )$.get(/info, fb.echo)
  • 39. Compile to JSvar 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);
  • 40. Compile to JSvar 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);
  • 41. Compile to JSvar 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);
  • 42. LiveScript use ~>
  • 43. Pros• No more this issue, context free• Reduce one call stack• No call/apply, no impact on performance• Encapsulation
  • 44. Cons• Can’t use this tip on normal constructor
  • 45. How about AMD• Define modules can return constructor,function, array, primitive data• Define a singleton module on most cases• Always have data on module
  • 46. AMD Singleton Moduledefine(foobar, function () {return {init: function (prefix) {this.prefix = prefix;}echo: function (input) {return this.prefix + input;}};});
  • 47. Cons• Function can be borrowed• Not doing on right `this` you expect
  • 48. Avoid Use thisdefine(foobar, function () {var self = {};return {init: function (prefix) {self.prefix = prefix;}echo: function (input) {return self.prefix + input;}};});
  • 49. Constructors?• Use bind to protect methods if necessary
  • 50. Constructor Withoutthisfunction Person(birth, gender) {var person = {birth: (birth || 1970/01/01),gender: (gender || M)};return {getBirth: function () {return person.birth;},getGender: function () {return person.gender;}};}
  • 51. to new or not to newvar 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"
  • 52. Cons• No prototype inheritance• More memory usage for methods
  • 53. Backbone Modeldefine(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)};});});
  • 54. Who Use this Tip• jQuery.Deferred• jQuery.Callbacks
  • 55. Deferred Chainingvar firstDfd = $.Deferred(),secondDfd = $.Deferred(),thirdDfd = $.Deferred();firstDfd.done(secondDfd.resolve);secondDfd.done(thirdDfd.resolve);firstDfd.resolve(); // All Deferred object resolved here
  • 56. Callbackshttps://github.com/jquery/jquery/blob/master/src/deferred.js// promise[ done | fail | progress ] = list.addpromise[ 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;
  • 57. Callbackshttps://github.com/jquery/jquery/blob/master/src/deferred.js// promise[ done | fail | progress ] = list.addpromise[ 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;
  • 58. Actually Arepromise[done] = resolveCallbacks.add;promise[fail] = rejectCallbacks.add;promise[progress] = notifyCallbacks.add;// skip...deferred["resolveWith"] = resolveCallbacks.fireWith;deferred["rejectWith"] = rejectCallbacks.fireWith;deferred["notifyWith"] = notifyCallbacks.fireWith;
  • 59. Summary• Understand `this`• Understand how not to use `this`• Use `this` carefully if necessary
  • 60. Trade-Off• ‘Not use this’ requires more memory onmethods definition and not easy toinheritance object• Benefit is you can write more clear, simplecode
  • 61. References
  • 62. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this
  • 63. Questions?http://www.flickr.com/photos/roman/5610736/

×