1 00:00:00,480 --> 00:00:03,480 foreign 2 00:00:09,500 --> 00:00:13,740 who will be speaking to us about 3 00:00:11,639 --> 00:00:15,840 JavaScript classes for the python 4 00:00:13,740 --> 00:00:21,180 programmer over to you 5 00:00:15,840 --> 00:00:23,100 [Applause] 6 00:00:21,180 --> 00:00:24,600 good afternoon I'm going to be spending 7 00:00:23,100 --> 00:00:27,840 a lot of time standing this way because 8 00:00:24,600 --> 00:00:29,460 those lights are quite aggressive 9 00:00:27,840 --> 00:00:31,500 um thank you 10 00:00:29,460 --> 00:00:34,079 just a quick introduction of who I am 11 00:00:31,500 --> 00:00:36,300 I've been working with python for about 12 00:00:34,079 --> 00:00:38,399 25 odd years I've been working with 13 00:00:36,300 --> 00:00:40,620 Django for about 16 years long enough 14 00:00:38,399 --> 00:00:43,140 that they um they actually invited me 15 00:00:40,620 --> 00:00:45,719 onto the core team at some point and I'm 16 00:00:43,140 --> 00:00:48,239 here with many thanks to my employer who 17 00:00:45,719 --> 00:00:49,800 is the reason I've had to do the 18 00:00:48,239 --> 00:00:52,320 investigations that led to me coming to 19 00:00:49,800 --> 00:00:53,579 the realization this content needed to 20 00:00:52,320 --> 00:00:55,199 be shared 21 00:00:53,579 --> 00:00:57,059 I'm going to cover a lot of the 22 00:00:55,199 --> 00:00:59,160 differences and similarities between how 23 00:00:57,059 --> 00:01:01,440 classes and objects work in JavaScript 24 00:00:59,160 --> 00:01:03,000 versus python because that helps us all 25 00:01:01,440 --> 00:01:04,080 especially those of us who work in the 26 00:01:03,000 --> 00:01:06,060 web space 27 00:01:04,080 --> 00:01:07,979 let's start off with some very basic 28 00:01:06,060 --> 00:01:10,740 fundamentals 29 00:01:07,979 --> 00:01:13,380 in Python 30 00:01:10,740 --> 00:01:15,119 we have explicit classes you say class 31 00:01:13,380 --> 00:01:17,520 you create name you define your class in 32 00:01:15,119 --> 00:01:20,460 there it is in JavaScript it's a little 33 00:01:17,520 --> 00:01:22,560 more subtle every object can be thought 34 00:01:20,460 --> 00:01:28,560 of as a class 35 00:01:22,560 --> 00:01:28,560 pretty much when it comes to scoping 36 00:01:28,860 --> 00:01:34,380 in Python we have self and that is 37 00:01:32,220 --> 00:01:36,659 explicitly passed in to your methods 38 00:01:34,380 --> 00:01:38,820 it's injected for you you don't have to 39 00:01:36,659 --> 00:01:41,159 remember it's just attached and this is 40 00:01:38,820 --> 00:01:43,140 done I discovered a couple of years ago 41 00:01:41,159 --> 00:01:45,659 using the descriptor protocol so anyone 42 00:01:43,140 --> 00:01:47,520 who's familiar with at property the same 43 00:01:45,659 --> 00:01:50,520 functionality in classes that lets that 44 00:01:47,520 --> 00:01:52,799 work is how functions 45 00:01:50,520 --> 00:01:56,939 know to inject self when they're called 46 00:01:52,799 --> 00:01:58,759 as part of a class in JavaScript 47 00:01:56,939 --> 00:02:01,259 it's a little different 48 00:01:58,759 --> 00:02:03,000 what happens is you have it this object 49 00:02:01,259 --> 00:02:05,240 which is the scope from which you were 50 00:02:03,000 --> 00:02:05,240 called 51 00:02:05,340 --> 00:02:11,940 if you are called via looking up another 52 00:02:08,340 --> 00:02:12,900 object then that object is your this you 53 00:02:11,940 --> 00:02:13,739 can actually 54 00:02:12,900 --> 00:02:15,599 um 55 00:02:13,739 --> 00:02:17,340 play with that and lose that if you're 56 00:02:15,599 --> 00:02:19,520 not careful when passing functions 57 00:02:17,340 --> 00:02:23,280 around 58 00:02:19,520 --> 00:02:25,319 in Python we can actually trick python 59 00:02:23,280 --> 00:02:27,780 into injecting a different this or a 60 00:02:25,319 --> 00:02:29,940 different class as around and we can 61 00:02:27,780 --> 00:02:32,360 call a method on another class without 62 00:02:29,940 --> 00:02:35,760 this 63 00:02:32,360 --> 00:02:38,160 by actually calling the cost method not 64 00:02:35,760 --> 00:02:40,260 the instance method 65 00:02:38,160 --> 00:02:42,599 on JavaScript they have this thing 66 00:02:40,260 --> 00:02:45,420 called bind which is a method on every 67 00:02:42,599 --> 00:02:46,620 function so you can say when this gets 68 00:02:45,420 --> 00:02:49,260 called 69 00:02:46,620 --> 00:02:53,420 I want this object that I'm passing to 70 00:02:49,260 --> 00:02:53,420 you now to be my scope to be my this 71 00:02:53,760 --> 00:02:57,540 next is Properties or attributes on our 72 00:02:56,099 --> 00:03:00,120 objects 73 00:02:57,540 --> 00:03:02,280 in Python every instance has a type 74 00:03:00,120 --> 00:03:04,500 which is its class and when you look up 75 00:03:02,280 --> 00:03:06,180 a property that doesn't exist on your 76 00:03:04,500 --> 00:03:07,560 instance python will then go look it up 77 00:03:06,180 --> 00:03:09,780 on your class 78 00:03:07,560 --> 00:03:12,300 and then its parent clause 79 00:03:09,780 --> 00:03:13,980 and so on and so on until we reach 80 00:03:12,300 --> 00:03:15,540 object at which point we say oh you 81 00:03:13,980 --> 00:03:18,560 haven't got one 82 00:03:15,540 --> 00:03:18,560 in JavaScript 83 00:03:19,340 --> 00:03:24,000 okay I've got my fragments out of order 84 00:03:22,080 --> 00:03:27,180 here 85 00:03:24,000 --> 00:03:29,519 we do we can in Python actually test if 86 00:03:27,180 --> 00:03:32,099 there is a direct attribute on our class 87 00:03:29,519 --> 00:03:34,379 by looking at the dunder dict of the 88 00:03:32,099 --> 00:03:37,140 class to say if this name is in there 89 00:03:34,379 --> 00:03:39,920 then it has that on itself it's not 90 00:03:37,140 --> 00:03:39,920 inheriting it 91 00:03:42,360 --> 00:03:46,799 oh 92 00:03:44,280 --> 00:03:50,040 in JavaScript every object has a 93 00:03:46,799 --> 00:03:51,780 prototype just one when you look up the 94 00:03:50,040 --> 00:03:55,640 property it doesn't exist on your 95 00:03:51,780 --> 00:03:55,640 current instance or your current object 96 00:03:56,819 --> 00:04:00,540 JavaScript will go and look at the 97 00:03:58,680 --> 00:04:03,599 Prototype and then they'll prototypes 98 00:04:00,540 --> 00:04:04,500 prototype and so on and so on until you 99 00:04:03,599 --> 00:04:06,239 reach 100 00:04:04,500 --> 00:04:08,700 the null object or there's no more 101 00:04:06,239 --> 00:04:10,799 prototypes to go up to so it's very 102 00:04:08,700 --> 00:04:12,659 similar in way to the pythons climbing 103 00:04:10,799 --> 00:04:14,220 up the tree except it's directly on your 104 00:04:12,659 --> 00:04:16,459 object rather than the type of your 105 00:04:14,220 --> 00:04:16,459 object 106 00:04:17,120 --> 00:04:24,300 additionally in similar allergy we can 107 00:04:19,979 --> 00:04:26,040 ask the object class itself and they 108 00:04:24,300 --> 00:04:28,259 provide us a static method to say hey 109 00:04:26,040 --> 00:04:30,360 does this object actually have its own 110 00:04:28,259 --> 00:04:32,639 instance its own attribute 111 00:04:30,360 --> 00:04:35,360 or is it inheriting it of from its 112 00:04:32,639 --> 00:04:35,360 prototype tree 113 00:04:35,520 --> 00:04:39,680 next we'll step on to Constructors 114 00:04:40,320 --> 00:04:45,900 now in Python we're all familiar with 115 00:04:42,780 --> 00:04:47,759 the dunder init method which is we can 116 00:04:45,900 --> 00:04:49,860 Define on our class to say hey let's get 117 00:04:47,759 --> 00:04:51,960 set up and let's get ready to go 118 00:04:49,860 --> 00:04:54,540 in JavaScript you 119 00:04:51,960 --> 00:04:56,940 you actually write a function that is 120 00:04:54,540 --> 00:05:00,560 not directly part of your class which 121 00:04:56,940 --> 00:05:00,560 constructs your object instance 122 00:05:01,020 --> 00:05:05,280 pretty much the same way very similar as 123 00:05:03,720 --> 00:05:08,600 we can see you can do the same things 124 00:05:05,280 --> 00:05:08,600 you assign values to this 125 00:05:09,419 --> 00:05:16,020 in Python we can create our object using 126 00:05:12,960 --> 00:05:18,840 the Constructor by calling the class in 127 00:05:16,020 --> 00:05:20,699 that gets called implicitly 128 00:05:18,840 --> 00:05:23,280 when we do this 129 00:05:20,699 --> 00:05:25,800 in JavaScript you invoke the Constructor 130 00:05:23,280 --> 00:05:28,639 function and it returns you the newly 131 00:05:25,800 --> 00:05:28,639 constructed object 132 00:05:30,139 --> 00:05:36,539 inheritance again it's a little 133 00:05:32,759 --> 00:05:40,340 different in basic objects in Python 134 00:05:36,539 --> 00:05:40,340 we actually say that my new 135 00:05:42,120 --> 00:05:46,440 sorry every 136 00:05:44,940 --> 00:05:49,020 I've got the wrong glasses on I'm not 137 00:05:46,440 --> 00:05:51,479 having trouble reading any uh 138 00:05:49,020 --> 00:05:54,919 any attributes on our class are 139 00:05:51,479 --> 00:05:54,919 inherited by the instance 140 00:05:55,759 --> 00:05:59,580 this way that when we've put a method 141 00:05:58,080 --> 00:06:03,780 there which is an attribute on a class 142 00:05:59,580 --> 00:06:06,360 we can access it that way in JavaScript 143 00:06:03,780 --> 00:06:07,919 objects inherit via their prototype of 144 00:06:06,360 --> 00:06:11,039 their Constructor 145 00:06:07,919 --> 00:06:13,020 so my class instance on the left has 146 00:06:11,039 --> 00:06:13,919 inherited the Greet function from its 147 00:06:13,020 --> 00:06:18,419 class 148 00:06:13,919 --> 00:06:20,520 on the right the JavaScript function 149 00:06:18,419 --> 00:06:22,800 is inheriting the Greek function from 150 00:06:20,520 --> 00:06:24,539 the Prototype of the function we've had 151 00:06:22,800 --> 00:06:27,300 actually 152 00:06:24,539 --> 00:06:29,699 added it that way and so instead of when 153 00:06:27,300 --> 00:06:32,160 it's constructed it inherits the object 154 00:06:29,699 --> 00:06:34,319 prototype of the object it inherited it 155 00:06:32,160 --> 00:06:38,960 inherits the Prototype 156 00:06:34,319 --> 00:06:38,960 of the function that constructed it 157 00:06:40,080 --> 00:06:44,580 static methods methods on the class 158 00:06:42,120 --> 00:06:46,800 itself or on the Constructor 159 00:06:44,580 --> 00:06:48,419 very similar patterns in Python we 160 00:06:46,800 --> 00:06:51,000 actually have a decorator to say this is 161 00:06:48,419 --> 00:06:52,800 a static method so it won't be passed a 162 00:06:51,000 --> 00:06:55,020 class or an instance 163 00:06:52,800 --> 00:06:58,380 and we can often use that as Factory 164 00:06:55,020 --> 00:06:59,580 functions to produce new instances in 165 00:06:58,380 --> 00:07:01,380 JavaScript 166 00:06:59,580 --> 00:07:03,720 because it's inherited from the 167 00:07:01,380 --> 00:07:06,780 Prototype of the parent or with the 168 00:07:03,720 --> 00:07:08,819 Prototype itself we can attach objects 169 00:07:06,780 --> 00:07:10,380 and methods and attributes directly to 170 00:07:08,819 --> 00:07:13,460 the function which is an object very 171 00:07:10,380 --> 00:07:13,460 much like in Python 172 00:07:13,620 --> 00:07:19,680 so invoking this here we would get a 173 00:07:15,960 --> 00:07:22,940 mock object from a python class 174 00:07:19,680 --> 00:07:22,940 and here in JavaScript 175 00:07:23,819 --> 00:07:28,020 we call it the same way it looks very 176 00:07:25,800 --> 00:07:30,720 much the same we get an object back it's 177 00:07:28,020 --> 00:07:33,780 just a method a function attached to the 178 00:07:30,720 --> 00:07:36,000 function object which is our Constructor 179 00:07:33,780 --> 00:07:38,400 a subclassing 180 00:07:36,000 --> 00:07:40,199 in Python is a very explicit thing 181 00:07:38,400 --> 00:07:42,360 because python explicitly supports 182 00:07:40,199 --> 00:07:45,240 classes so if we just say them in my 183 00:07:42,360 --> 00:07:47,400 definition of my class well it's one of 184 00:07:45,240 --> 00:07:48,960 these with these changes and when I 185 00:07:47,400 --> 00:07:51,900 wanted to go and say well do what the 186 00:07:48,960 --> 00:07:54,720 parent class would do I call Super 187 00:07:51,900 --> 00:07:56,759 in JavaScript it requires a little bit 188 00:07:54,720 --> 00:07:58,860 more effort because it's a constructed 189 00:07:56,759 --> 00:08:01,800 concept rather than a native part of the 190 00:07:58,860 --> 00:08:05,460 language so we have to tell 191 00:08:01,800 --> 00:08:07,800 our Constructor that we're creating now 192 00:08:05,460 --> 00:08:11,160 that its prototype 193 00:08:07,800 --> 00:08:13,740 has a prototype of the Prototype of the 194 00:08:11,160 --> 00:08:15,240 parent classes Constructor and that 195 00:08:13,740 --> 00:08:17,280 sounds a little bit roundabout and 196 00:08:15,240 --> 00:08:19,199 actually doing that is also a little bit 197 00:08:17,280 --> 00:08:21,360 roundabout so here we've defined our new 198 00:08:19,199 --> 00:08:22,680 Constructor and it calls the parent 199 00:08:21,360 --> 00:08:25,319 classes 200 00:08:22,680 --> 00:08:29,039 Constructor using call which is similar 201 00:08:25,319 --> 00:08:31,379 to to bind but it actually you pass it 202 00:08:29,039 --> 00:08:32,640 the scope and then the arguments as a 203 00:08:31,379 --> 00:08:35,640 list 204 00:08:32,640 --> 00:08:38,640 and then we have to say can we create a 205 00:08:35,640 --> 00:08:40,860 new copy of our parent classes prototype 206 00:08:38,640 --> 00:08:43,620 but add to it this Constructor which is 207 00:08:40,860 --> 00:08:45,420 this is a very explicit and detailed way 208 00:08:43,620 --> 00:08:46,500 of saying I want to put another property 209 00:08:45,420 --> 00:08:49,500 on there 210 00:08:46,500 --> 00:08:51,360 very tedious 211 00:08:49,500 --> 00:08:53,100 next we come to a very noticeable 212 00:08:51,360 --> 00:08:55,920 difference in terminology and 213 00:08:53,100 --> 00:08:58,620 functionality between Python 214 00:08:55,920 --> 00:09:00,899 and JavaScript 215 00:08:58,620 --> 00:09:03,360 Python's init function although we often 216 00:09:00,899 --> 00:09:05,100 refer to it as a Constructor is not a 217 00:09:03,360 --> 00:09:07,080 Constructor 218 00:09:05,100 --> 00:09:09,660 it's the error in the name it's an 219 00:09:07,080 --> 00:09:12,300 initializer and this difference means 220 00:09:09,660 --> 00:09:14,880 that it's only invoked after the 221 00:09:12,300 --> 00:09:18,000 instance object is actually created and 222 00:09:14,880 --> 00:09:20,519 by the time that we get to the instance 223 00:09:18,000 --> 00:09:22,140 and we get to our initializer all the 224 00:09:20,519 --> 00:09:24,180 properties are declared on this instance 225 00:09:22,140 --> 00:09:26,399 all the properties have been inherited 226 00:09:24,180 --> 00:09:28,740 from the class the parent class the 227 00:09:26,399 --> 00:09:31,140 parent class all the way back 228 00:09:28,740 --> 00:09:33,959 and all of those attributes are visible 229 00:09:31,140 --> 00:09:37,580 to even the superclasses methods once 230 00:09:33,959 --> 00:09:37,580 they're called and invoked via super 231 00:09:38,220 --> 00:09:41,720 so here's an example 232 00:09:41,880 --> 00:09:46,320 if we have a python class called Unit 233 00:09:43,740 --> 00:09:48,480 and it has a static a property called 234 00:09:46,320 --> 00:09:50,640 Foo and they now initializer we get bar 235 00:09:48,480 --> 00:09:53,580 and we ask for the amount and multiply 236 00:09:50,640 --> 00:09:56,040 them when I create a chunk as a subclass 237 00:09:53,580 --> 00:09:58,200 of that if I create unit with a two 238 00:09:56,040 --> 00:10:01,800 value it's two times one we get two 239 00:09:58,200 --> 00:10:03,720 chunk two times five we get 10 pretty 240 00:10:01,800 --> 00:10:06,180 straightforward 241 00:10:03,720 --> 00:10:09,600 if we tried the same in JavaScript and 242 00:10:06,180 --> 00:10:11,880 we call new what we get what happens is 243 00:10:09,600 --> 00:10:13,920 we get a blank object created 244 00:10:11,880 --> 00:10:16,680 then its prototype is set to the 245 00:10:13,920 --> 00:10:19,800 Constructor function's prototype 246 00:10:16,680 --> 00:10:24,980 then the Constructor is called 247 00:10:19,800 --> 00:10:24,980 with this new object cast as it's this 248 00:10:26,100 --> 00:10:30,380 I've got my slides out of order I'm 249 00:10:27,660 --> 00:10:30,380 sorry about that 250 00:10:30,860 --> 00:10:37,200 next we enter 251 00:10:33,720 --> 00:10:39,240 es6 or es2015 JavaScript released in 252 00:10:37,200 --> 00:10:40,740 2015 which introduced a whole bunch of 253 00:10:39,240 --> 00:10:44,040 things but one of the nicest things it 254 00:10:40,740 --> 00:10:46,320 introduced was class syntax 255 00:10:44,040 --> 00:10:48,779 this allows us to redo all those things 256 00:10:46,320 --> 00:10:53,040 we've done before in a syntax that looks 257 00:10:48,779 --> 00:10:54,839 a lot more like other languages classes 258 00:10:53,040 --> 00:10:58,140 now we have an explicit Constructor 259 00:10:54,839 --> 00:11:00,000 function we can define static methods 260 00:10:58,140 --> 00:11:02,700 and static properties and inherited 261 00:11:00,000 --> 00:11:06,600 functions for everybody else to use now 262 00:11:02,700 --> 00:11:09,600 subclassing becomes a nice direct clean 263 00:11:06,600 --> 00:11:11,459 this class extends that class my 264 00:11:09,600 --> 00:11:13,620 Constructor calls the superclasses 265 00:11:11,459 --> 00:11:15,240 Constructor and then does whatever it's 266 00:11:13,620 --> 00:11:17,640 local Things Are 267 00:11:15,240 --> 00:11:20,100 unlike Python and very much like a lot 268 00:11:17,640 --> 00:11:21,959 of other languages JavaScript does not 269 00:11:20,100 --> 00:11:24,180 support multiple inheritance you can go 270 00:11:21,959 --> 00:11:26,100 up the chain one by one but you can't 271 00:11:24,180 --> 00:11:28,579 say that this class mixes in multiple 272 00:11:26,100 --> 00:11:28,579 classes 273 00:11:29,040 --> 00:11:32,880 another important difference and this is 274 00:11:31,380 --> 00:11:35,100 actually different from the Constructor 275 00:11:32,880 --> 00:11:37,079 functions we saw earlier is that you 276 00:11:35,100 --> 00:11:39,779 must con must call 277 00:11:37,079 --> 00:11:41,880 your superclass Constructor before you 278 00:11:39,779 --> 00:11:43,800 do any modification of your this object 279 00:11:41,880 --> 00:11:47,779 if you try to do it you'll get an error 280 00:11:43,800 --> 00:11:47,779 like this to say exactly that 281 00:11:48,660 --> 00:11:53,160 again static properties can be declared 282 00:11:51,180 --> 00:11:55,800 just like they were before very much 283 00:11:53,160 --> 00:11:58,860 like it in Python now we just put it 284 00:11:55,800 --> 00:12:01,440 inside the class declaration and InFocus 285 00:11:58,860 --> 00:12:04,920 directly from the object itself The 286 00:12:01,440 --> 00:12:07,200 Constructor rather than as a member 287 00:12:04,920 --> 00:12:08,579 and prior to es6 it would have looked 288 00:12:07,200 --> 00:12:10,380 very much like this so it actually 289 00:12:08,579 --> 00:12:11,779 hasn't changed a lot it's very very 290 00:12:10,380 --> 00:12:13,860 similar 291 00:12:11,779 --> 00:12:16,140 next I want to talk about what I'm 292 00:12:13,860 --> 00:12:18,779 calling subclass overrides 293 00:12:16,140 --> 00:12:20,940 so their example before 294 00:12:18,779 --> 00:12:24,320 where we have an object which takes a 295 00:12:20,940 --> 00:12:24,320 factor a scaling Factor 296 00:12:25,200 --> 00:12:29,459 and then we pass it an amount and it'll 297 00:12:27,660 --> 00:12:33,000 tell us an amount comes out 298 00:12:29,459 --> 00:12:34,560 and then we have a subclass of it 299 00:12:33,000 --> 00:12:36,600 and it gives us a different amount 300 00:12:34,560 --> 00:12:38,339 because the init function has gone off 301 00:12:36,600 --> 00:12:39,959 okay I'll put that number in I'll 302 00:12:38,339 --> 00:12:41,339 multiply them and out we come with our 303 00:12:39,959 --> 00:12:43,920 amount 304 00:12:41,339 --> 00:12:45,720 in JavaScript if we tried the same thing 305 00:12:43,920 --> 00:12:47,339 looks almost identical we have our 306 00:12:45,720 --> 00:12:49,440 Constructor and we have an amount it's 307 00:12:47,339 --> 00:12:53,240 time to factor and how we get is a two 308 00:12:49,440 --> 00:12:53,240 but if we try the subclass 309 00:12:53,279 --> 00:13:00,139 um why did we get five 310 00:12:56,820 --> 00:13:00,139 why did we get two 311 00:13:01,800 --> 00:13:07,579 the wrong number comes out 312 00:13:04,320 --> 00:13:10,079 why does the wrong number come out 313 00:13:07,579 --> 00:13:11,639 part of the problem and part of the big 314 00:13:10,079 --> 00:13:12,839 conceptual difference and what I was 315 00:13:11,639 --> 00:13:15,000 talking about with the Constructor 316 00:13:12,839 --> 00:13:16,680 versus initializer before is that 317 00:13:15,000 --> 00:13:18,899 JavaScript Constructors are called in 318 00:13:16,680 --> 00:13:20,579 order because you have to call your 319 00:13:18,899 --> 00:13:22,740 parent Constructor before you do any 320 00:13:20,579 --> 00:13:23,940 work that goes all the way back to the 321 00:13:22,740 --> 00:13:25,800 root object 322 00:13:23,940 --> 00:13:28,200 from the bottom all the way back up to 323 00:13:25,800 --> 00:13:30,420 the top there's this layered concept and 324 00:13:28,200 --> 00:13:33,839 each layer 325 00:13:30,420 --> 00:13:36,839 can only see what's being defined so far 326 00:13:33,839 --> 00:13:39,240 what it has attached to the construction 327 00:13:36,839 --> 00:13:41,339 which means that all the methods all the 328 00:13:39,240 --> 00:13:43,920 overrides all the shadowed attributes 329 00:13:41,339 --> 00:13:46,380 you've got on your subclasses aren't 330 00:13:43,920 --> 00:13:48,959 there yet 331 00:13:46,380 --> 00:13:51,000 additionally public fields which is like 332 00:13:48,959 --> 00:13:53,220 a factor one here 333 00:13:51,000 --> 00:13:55,019 are added just before calling the 334 00:13:53,220 --> 00:13:57,899 Constructor function 335 00:13:55,019 --> 00:14:00,899 so what has happened in our example 336 00:13:57,899 --> 00:14:04,200 is that factor was actually one when the 337 00:14:00,899 --> 00:14:06,779 scale Constructor was was called 338 00:14:04,200 --> 00:14:08,880 and therefore when it is set this dot 339 00:14:06,779 --> 00:14:09,899 amount it is gone and multiplied it by 340 00:14:08,880 --> 00:14:11,940 one 341 00:14:09,899 --> 00:14:14,399 then 342 00:14:11,940 --> 00:14:16,320 when the bigger class gets its static 343 00:14:14,399 --> 00:14:20,120 attributes or it's its class members set 344 00:14:16,320 --> 00:14:20,120 up before its Constructor is called 345 00:14:20,459 --> 00:14:25,200 then the factor is set to five this is a 346 00:14:23,579 --> 00:14:26,459 bit of a trick that catches you out 347 00:14:25,200 --> 00:14:28,680 sometimes 348 00:14:26,459 --> 00:14:30,240 so how can we fix this what patterns can 349 00:14:28,680 --> 00:14:32,480 we follow to avoid this problem in 350 00:14:30,240 --> 00:14:32,480 future 351 00:14:32,820 --> 00:14:40,019 first you can use it as a static member 352 00:14:35,940 --> 00:14:43,980 and then explicitly reference the 353 00:14:40,019 --> 00:14:45,240 Constructor that was used to trigger 354 00:14:43,980 --> 00:14:48,000 this Construction in the first place 355 00:14:45,240 --> 00:14:50,220 rather than your current version of the 356 00:14:48,000 --> 00:14:52,860 of the truth this way we stash the 357 00:14:50,220 --> 00:14:54,660 static property on the Constructor and 358 00:14:52,860 --> 00:14:56,519 then we go into reference whichever one 359 00:14:54,660 --> 00:14:58,199 was there first so here's the example of 360 00:14:56,519 --> 00:15:00,660 that code Rewritten we have a static 361 00:14:58,199 --> 00:15:03,540 Factor instead of factor 362 00:15:00,660 --> 00:15:05,820 and here in our code we see we say this 363 00:15:03,540 --> 00:15:08,220 dot constructor.factor we're referring 364 00:15:05,820 --> 00:15:09,899 to whichever Constructor was used during 365 00:15:08,220 --> 00:15:12,260 the construction initially of this 366 00:15:09,899 --> 00:15:12,260 object 367 00:15:12,540 --> 00:15:16,740 so it will always be the Constructor 368 00:15:14,459 --> 00:15:20,279 that was passed to new rather than the 369 00:15:16,740 --> 00:15:22,199 current Constructor that we're calling 370 00:15:20,279 --> 00:15:25,860 so we can actually use this layering 371 00:15:22,199 --> 00:15:28,160 effect to our advantage 372 00:15:25,860 --> 00:15:28,160 okay 373 00:15:28,980 --> 00:15:32,220 since we know that they're going to get 374 00:15:30,660 --> 00:15:33,600 called in that order and that the 375 00:15:32,220 --> 00:15:36,120 object's going to exist in the 376 00:15:33,600 --> 00:15:39,480 particular State as we get there 377 00:15:36,120 --> 00:15:40,320 we can use a static initialized fields 378 00:15:39,480 --> 00:15:44,300 um 379 00:15:40,320 --> 00:15:44,300 as they're evaluated during construction 380 00:15:46,260 --> 00:15:50,940 so as it's a layered thing 381 00:15:49,019 --> 00:15:53,160 we can use this to provide helper 382 00:15:50,940 --> 00:15:55,800 methods for next classes down to access 383 00:15:53,160 --> 00:15:57,240 this is a natural thing in Python 384 00:15:55,800 --> 00:15:59,339 because we already know that all those 385 00:15:57,240 --> 00:16:02,160 methods are put together already but we 386 00:15:59,339 --> 00:16:03,540 can do this as a deliberate effort in in 387 00:16:02,160 --> 00:16:04,980 JavaScript to make things a little 388 00:16:03,540 --> 00:16:07,320 easier to use 389 00:16:04,980 --> 00:16:10,079 so as an example we might on our Base 390 00:16:07,320 --> 00:16:13,620 Class have a setup things method 391 00:16:10,079 --> 00:16:16,740 and then as a static initializer during 392 00:16:13,620 --> 00:16:19,579 uh child class called that to say what 393 00:16:16,740 --> 00:16:19,579 this field should be 394 00:16:20,760 --> 00:16:25,380 now notably in this scope this is 395 00:16:24,060 --> 00:16:28,260 referring to the object that's under 396 00:16:25,380 --> 00:16:31,440 construction and super is our parent 397 00:16:28,260 --> 00:16:34,079 class or the Constructor just like when 398 00:16:31,440 --> 00:16:37,500 we're using Constructor function 399 00:16:34,079 --> 00:16:40,199 static initializers public Fields just 400 00:16:37,500 --> 00:16:43,560 like we saw with facta and the class can 401 00:16:40,199 --> 00:16:46,019 have its own static initializers as well 402 00:16:43,560 --> 00:16:47,940 so we've already seen a very basic case 403 00:16:46,019 --> 00:16:49,860 of this with static initializers being 404 00:16:47,940 --> 00:16:51,600 methods and properties that we Define on 405 00:16:49,860 --> 00:16:53,339 the Constructor object itself or the 406 00:16:51,600 --> 00:16:55,500 base class 407 00:16:53,339 --> 00:16:57,240 but they can also be methods that 408 00:16:55,500 --> 00:16:59,480 include whole code blocks with 409 00:16:57,240 --> 00:17:02,639 conditional work and so on to make it 410 00:16:59,480 --> 00:17:05,220 initialization of of things that do not 411 00:17:02,639 --> 00:17:07,140 depend on the arguments passed into your 412 00:17:05,220 --> 00:17:08,939 Constructor or may only depend on 413 00:17:07,140 --> 00:17:12,419 arguments that have already been handled 414 00:17:08,939 --> 00:17:14,780 by parent classes 415 00:17:12,419 --> 00:17:17,459 this is a nice way to make your your 416 00:17:14,780 --> 00:17:20,220 Constructor functions a little tighter a 417 00:17:17,459 --> 00:17:22,020 little smaller so that they are more 418 00:17:20,220 --> 00:17:23,699 focused on what the user has decided 419 00:17:22,020 --> 00:17:25,980 rather than what you've decided as a 420 00:17:23,699 --> 00:17:28,500 general practice 421 00:17:25,980 --> 00:17:30,780 came to include here a nice practical 422 00:17:28,500 --> 00:17:33,480 example 423 00:17:30,780 --> 00:17:35,340 um of by using the static initializers 424 00:17:33,480 --> 00:17:37,020 our Base Class can actually provide 425 00:17:35,340 --> 00:17:40,080 helper functions for the other class to 426 00:17:37,020 --> 00:17:43,260 set up its own static methods 427 00:17:40,080 --> 00:17:45,960 here is an example of an enum class 428 00:17:43,260 --> 00:17:48,900 and we say that we've got setup values 429 00:17:45,960 --> 00:17:51,240 as method and then our enumclass does in 430 00:17:48,900 --> 00:17:52,860 a static Constructor block that we're 431 00:17:51,240 --> 00:17:54,059 going to call that method with a bunch 432 00:17:52,860 --> 00:17:56,880 of values 433 00:17:54,059 --> 00:17:59,600 here we can see it's simply Maps over 434 00:17:56,880 --> 00:17:59,600 the values 435 00:18:00,840 --> 00:18:06,240 and tries to set on this 436 00:18:04,020 --> 00:18:08,700 the uppercase version of that name and 437 00:18:06,240 --> 00:18:10,799 then the index back to the value and the 438 00:18:08,700 --> 00:18:12,419 product of this output is that we now 439 00:18:10,799 --> 00:18:15,360 have an e num very much like python 440 00:18:12,419 --> 00:18:18,860 where I can look it up by name 441 00:18:15,360 --> 00:18:18,860 or I can look it up by index 442 00:18:20,460 --> 00:18:24,539 right and this has gone just a little 443 00:18:22,500 --> 00:18:27,780 bit faster than I was hoping but there 444 00:18:24,539 --> 00:18:33,600 we are undone any questions please 445 00:18:27,780 --> 00:18:35,940 [Applause] 446 00:18:33,600 --> 00:18:37,980 thank you 447 00:18:35,940 --> 00:18:41,600 thank you Curtis 448 00:18:37,980 --> 00:18:41,600 um yeah we have time for some questions 449 00:18:42,539 --> 00:18:45,559 oh we have on there 450 00:18:45,900 --> 00:18:51,380 oh it's a Russell 451 00:18:48,120 --> 00:18:51,380 of course it's a raffle 452 00:18:52,440 --> 00:18:56,580 thanks very much 453 00:18:53,940 --> 00:18:59,280 um a lot of the issues or the causes of 454 00:18:56,580 --> 00:19:03,660 confusion in the JavaScript class World 455 00:18:59,280 --> 00:19:06,380 seem to stem from which this is this and 456 00:19:03,660 --> 00:19:10,620 which one is that and so on 457 00:19:06,380 --> 00:19:14,100 any tips trip tricks suggestions hints 458 00:19:10,620 --> 00:19:15,780 for how to either diagnose or prevent 459 00:19:14,100 --> 00:19:16,799 error when you get into that kind of 460 00:19:15,780 --> 00:19:18,600 situation 461 00:19:16,799 --> 00:19:21,260 so the biggest one was actually 462 00:19:18,600 --> 00:19:24,780 mentioned early on 463 00:19:21,260 --> 00:19:26,940 uh here we're talking about how and I I 464 00:19:24,780 --> 00:19:28,320 did want to provide more detail on this 465 00:19:26,940 --> 00:19:28,980 this is good 466 00:19:28,320 --> 00:19:31,620 um 467 00:19:28,980 --> 00:19:33,660 this when you call a function is the 468 00:19:31,620 --> 00:19:36,059 scope you were called from and if you 469 00:19:33,660 --> 00:19:39,480 looked up via an object as I show here x 470 00:19:36,059 --> 00:19:40,740 dot Foo then in this case X 471 00:19:39,480 --> 00:19:43,620 is 472 00:19:40,740 --> 00:19:46,559 the scope of it is this once you're 473 00:19:43,620 --> 00:19:47,280 called so if you remember to always look 474 00:19:46,559 --> 00:19:49,980 up 475 00:19:47,280 --> 00:19:53,760 fire function then you can control your 476 00:19:49,980 --> 00:19:56,280 scope if you are passing a callback to 477 00:19:53,760 --> 00:19:58,559 which is very common in in JavaScript 478 00:19:56,280 --> 00:20:00,419 for a long time like we're doing down at 479 00:19:58,559 --> 00:20:01,919 set timeout you have two options either 480 00:20:00,419 --> 00:20:04,140 you can wrap it in a new function that 481 00:20:01,919 --> 00:20:06,059 deliberately looks up your object 482 00:20:04,140 --> 00:20:08,160 to get that function because if you pass 483 00:20:06,059 --> 00:20:11,880 the function on Excel on its own you've 484 00:20:08,160 --> 00:20:16,020 lost this the other is bind bind creates 485 00:20:11,880 --> 00:20:18,960 a new function which always has in this 486 00:20:16,020 --> 00:20:21,600 case X has its scope as it's this it's 487 00:20:18,960 --> 00:20:23,580 bound it's fixed it's done you cannot 488 00:20:21,600 --> 00:20:26,400 undo it except unless you call bind 489 00:20:23,580 --> 00:20:29,100 again or or a call as I showed later on 490 00:20:26,400 --> 00:20:31,260 is another option that way you can say 491 00:20:29,100 --> 00:20:33,840 always I want this and you'll see this a 492 00:20:31,260 --> 00:20:36,419 lot in older react code 493 00:20:33,840 --> 00:20:38,220 where the Constructor of the class will 494 00:20:36,419 --> 00:20:41,280 go through and grab all of its methods 495 00:20:38,220 --> 00:20:44,400 and say on the instance the same name 496 00:20:41,280 --> 00:20:46,799 equals that function dot bind this that 497 00:20:44,400 --> 00:20:48,600 way doesn't matter if you pass them as a 498 00:20:46,799 --> 00:20:50,400 callback or use them in any other way 499 00:20:48,600 --> 00:20:52,500 they're always bound to the current 500 00:20:50,400 --> 00:20:56,780 instance to make sure that that scope 501 00:20:52,500 --> 00:20:56,780 doesn't creep away on you and disappear 502 00:20:57,780 --> 00:21:01,460 do we have any other questions 503 00:21:02,940 --> 00:21:05,940 foreign 504 00:21:09,260 --> 00:21:14,520 struggle with context switching between 505 00:21:11,640 --> 00:21:17,280 Python on the server and JavaScript on 506 00:21:14,520 --> 00:21:19,080 the client does my head in 507 00:21:17,280 --> 00:21:22,559 can you talk through the pros and cons 508 00:21:19,080 --> 00:21:25,559 of doing that just suck it up versus 509 00:21:22,559 --> 00:21:28,799 node on the server versus a python to 510 00:21:25,559 --> 00:21:30,720 JavaScript transpiler oh that's an 511 00:21:28,799 --> 00:21:33,419 interesting one so my personal view is 512 00:21:30,720 --> 00:21:37,100 if I had the choice 513 00:21:33,419 --> 00:21:37,100 I would not use JavaScript 514 00:21:37,260 --> 00:21:40,980 but in the browser we currently don't 515 00:21:39,600 --> 00:21:42,299 really have the choice there have been 516 00:21:40,980 --> 00:21:44,760 some great examples shown at this 517 00:21:42,299 --> 00:21:46,860 conference that it's it's there I would 518 00:21:44,760 --> 00:21:49,020 much rather have a single language so I 519 00:21:46,860 --> 00:21:50,760 definitely understand why node happened 520 00:21:49,020 --> 00:21:52,380 as a thing because all the people who 521 00:21:50,760 --> 00:21:55,140 already had all the familiarity and 522 00:21:52,380 --> 00:21:56,880 expertise in JavaScript moved over to 523 00:21:55,140 --> 00:21:58,620 the server and went well I'm going to 524 00:21:56,880 --> 00:22:00,780 bring my language with me perfectly 525 00:21:58,620 --> 00:22:02,400 valid choice I like the idea of going 526 00:22:00,780 --> 00:22:03,539 the other direction which Russell has 527 00:22:02,400 --> 00:22:05,520 helped with and various other people 528 00:22:03,539 --> 00:22:08,700 have helped with in bringing python to 529 00:22:05,520 --> 00:22:10,980 the browser at the moment I find your 530 00:22:08,700 --> 00:22:13,080 best cleanest option is really to 531 00:22:10,980 --> 00:22:15,059 understand both languages and use each 532 00:22:13,080 --> 00:22:17,159 one in its field 533 00:22:15,059 --> 00:22:19,080 um I have not played with any of the 534 00:22:17,159 --> 00:22:20,159 transpilers but I understand that some 535 00:22:19,080 --> 00:22:21,500 of them have been around a couple of 536 00:22:20,159 --> 00:22:24,299 decades now 537 00:22:21,500 --> 00:22:26,820 I don't feel that you're really going to 538 00:22:24,299 --> 00:22:28,080 get the best performance results 539 00:22:26,820 --> 00:22:30,659 if 540 00:22:28,080 --> 00:22:33,059 you're just trying to shim one to look 541 00:22:30,659 --> 00:22:34,200 like the other and a lot of the times 542 00:22:33,059 --> 00:22:36,539 when we're working in the web the 543 00:22:34,200 --> 00:22:38,760 performance can really really matter 544 00:22:36,539 --> 00:22:40,500 so 545 00:22:38,760 --> 00:22:42,480 there's a lot of different takes on on 546 00:22:40,500 --> 00:22:44,640 how to do that 547 00:22:42,480 --> 00:22:46,440 JavaScript has definitely improved a lot 548 00:22:44,640 --> 00:22:48,960 over the last decade 549 00:22:46,440 --> 00:22:51,120 I now find it much much closer to python 550 00:22:48,960 --> 00:22:53,760 a much more cleanly defined and they are 551 00:22:51,120 --> 00:22:55,799 actually in some places dropping some of 552 00:22:53,760 --> 00:22:57,299 the um some of the old things that they 553 00:22:55,799 --> 00:22:59,039 found very painful to deal with there's 554 00:22:57,299 --> 00:23:01,200 actually a speaker's note on this slide 555 00:22:59,039 --> 00:23:03,720 to talk about with 556 00:23:01,200 --> 00:23:05,460 which is no longer in fact if you go to 557 00:23:03,720 --> 00:23:07,620 the Mozilla developer Network they say 558 00:23:05,460 --> 00:23:08,940 don't use this some browsers have even 559 00:23:07,620 --> 00:23:13,559 stopped supporting it where you could 560 00:23:08,940 --> 00:23:15,960 say with X call Foo and it would make X 561 00:23:13,559 --> 00:23:18,059 the current this 562 00:23:15,960 --> 00:23:20,039 so that's an option that is in 563 00:23:18,059 --> 00:23:22,080 JavaScript but no longer there so 564 00:23:20,039 --> 00:23:24,480 JavaScript is maturing and growing and 565 00:23:22,080 --> 00:23:26,220 involving python is 2 and I think 566 00:23:24,480 --> 00:23:28,140 JavaScript is a lot less 567 00:23:26,220 --> 00:23:30,900 painful than it used to be and a lot 568 00:23:28,140 --> 00:23:33,059 less scary than I used to find it 569 00:23:30,900 --> 00:23:34,500 but I was hoping with this talk to get 570 00:23:33,059 --> 00:23:35,820 people a little more familiar with what 571 00:23:34,500 --> 00:23:37,140 you're going to stumble across when you 572 00:23:35,820 --> 00:23:38,580 start trying to use it and why the 573 00:23:37,140 --> 00:23:40,740 things are constructed the way they are 574 00:23:38,580 --> 00:23:42,480 because it's important to recognize that 575 00:23:40,740 --> 00:23:45,780 the new class structure stuff that was 576 00:23:42,480 --> 00:23:48,120 there is really the old Constructors and 577 00:23:45,780 --> 00:23:51,380 functions and and prototypes with a new 578 00:23:48,120 --> 00:23:51,380 syntactic sugar on top 579 00:23:52,799 --> 00:23:56,120 do we have any other questions 580 00:24:01,919 --> 00:24:06,240 guess not 581 00:24:03,720 --> 00:24:09,679 um thank you so much Curtis 582 00:24:06,240 --> 00:24:09,679 um thank you 583 00:24:10,460 --> 00:24:13,559 [Applause]