What Firefox's Quantum Browser Means for a More Open Web
Apple's MacOS High Sierra Bug Fix Reintroduces "Root" Problem For Some Users
WIRED's Top Stories in November: Tesla's Electric Semi, FTW
Ryan Morrison takes us behind the scenes of Webflow's Design Team
The Tangled World of Custom Data in WordPress
Reducing Risk and Managing Your Custom Fields
source https://pixabay.comHave you ever wondered how to properly name keys of WordPress custom fields? Does it make any difference? Should you care? What are the potential risks?
Recently I wrote a tutorial about filtering WordPress admin views. In the code, I named custom fields key like kg_order_items. You could ask why? Why not name it just items? Well… read below!
If you try to google for naming custom fields there is not so much information about it. Even the Codex entry tells nothing about naming the field keys in a proper way. I found only one resource at ACF forums that contains proper information.
If there is no problem, what is the fuss about? You could ask.
Found on http://dilbert.comThe days when WordPress was a simple CMS supporting small blog websites with only posts and pages are gone. Today even the smallest website uses a plethora of plugins and complex themes. And all of them bring new custom fields into the game.
The situation gets even worse if you use any of the fancy “premium” themes. Unfortunately, many of these are not well written and combine 1001 functions in one. Final result? Slow, not performant, and tangled site which looks nice only on demo content and stock images. And they add a lot of custom fields too.
Danger!
Source unknownWordPress wp_postmeta table is very simple. It is a key-value pair attached to particular post_id. It means that all custom fields keys share a common namespace. That is especially true for the particular ID of the post.
First example
a) Imagine that your post has a “learn more” link. After you click the link it redirects you to a particular URL. The address is provided in a custom field. Let’s name the field key as redirect_to.
b) Now imagine that you install a plugin called for example “Redirect me, Honey”. The plugin is very, very simple. When the user enters the page it immediately redirects the user based on custom field setting attached to a post. Oh… and its field key is named redirect_to as well.
Result? After you activate the plugin, all of your posts with “learn more” button are redirecting users out of your website. And the reason why is not obvious at the first sight. It may even be unnoticed for quite a while.
This scenario is, of course, made up but the dangers are real. With thousands of plugins and thousands of themes available it’s just a matter of time to encounter such name collision.
Second example
WordPress can store multiple values for the same key name and post ID. (Unless you provide special parameter called $unique).
It means that if you save your data 5 times under the key location you will receive an array consisting of 5 elements when calling get_post_meta().
Let’s assume that you have a post about the cities you have visited. You have been to 5 cities and those locations are shown on the embedded map in the post. Simple, right?
Attention! Not useful code ahead. ;) !
//NY
add_post_meta($post_id, 'location', '40.7127753, 73.989308');
//LA
add_post_meta($post_id, 'location', '34.0522342, -118.2436849');
//Paris
add_post_meta($post_id, 'location', '48.856614, 2.3522219000000177');
//Vienna
add_post_meta($post_id, 'location', '48.2081743, 16.37381890000006');
//Rome
add_post_meta($post_id, 'location', '41.90278349999999, 12.496365500000024');
//Lets check what we have here
var_dump(get_post_meta($post_id, 'location');
array (size=5)
0 => string '40.7127753, 73.989308' (length=21)
1 => string '34.0522342, -118.2436849' (length=24)
2 => string '48.856614, 2.3522219000000177' (length=29)
3 => string '48.2081743,16.37381890000006' (length=28)
4 => string '41.90278349999999,12.496365500000024' (length=36)
What if after a while you use a new theme or plugin. It has a feature which can set the position of a post on a front page. You can pick between slider, sidebar or featured posts etc. This scenario may end up like this:
array (size=6)
0 => string ‘40.7127753, 73.989308’ (length=21)
1 => string ‘34.0522342, -118.2436849’ (length=24)
2 => string ‘48.856614, 2.3522219000000177’ (length=29)
3 => string ‘48.2081743,16.37381890000006’ (length=28)
4 => string ‘41.90278349999999,12.496365500000024’ (length=36)
5 => string ‘left_sidebar’ (length=12) // Yeah, right…
Or even worse:
array (size=5)
0 => string 'left_sidebar' (length=12)
1 => string 'left_sidebar' (length=12)
2 => string 'left_sidebar' (length=12)
3 => string 'left_sidebar' (length=12)
4 => string 'left_sidebar' (length=12)
Your pretty little map is broken now! And you lost all of your entered data. Not funny right?
B-b-b-b-roken?? ;( source https://pixabay.comSolution
You can never protect your custom fields data from being overwritten or deleted. This is how WordPress works and why it is so flexible. You can reduce that risk though.
How?
By avoiding common names and namespacing all your custom fields keys.
My proposed convention is:
- cpt-name_field-name
like books_author instead of author, order_items instead of items(solution for most lazy ones :) ). - purpose_field-name
like front_page_location instead of location, visited_cities_locationsinstead of location. - prefix_(cpt-name/purpose)_field-name
like kg_books_author, kg_visited_cities_locations (for the most strict ones).
That is not all. Additionally, you should always take care of optional parameters of built-in WordPress functions:
- add_post_meta() has $unique to not add the custom field if it already exists.
- get_post_meta() uses $single to retrieve only one record (if you expect only one record).
- update_post_meta() and delete_post_meta() leverage $previous_value to ensure that you update/delete the key you want.
Those parameters are helping in writing better, cleaner and more predictable code.
And that is not all. Use well tested, well written and extendable plugins like Pods Framework or Advanced Custom Fields. These will help manage your custom fields. They are great when it comes to managing the tangled world of your custom data.
Summary
In the ideal world, we should always be aware of what you are adding to the system. We should know what your plugins, themes, and custom functions are doing. That is unfortunately not always possible.
Therefore we should pay attention to the code we produce and tighten up all those loose ends.
That is all folks! I hope you liked it and have a great day!
This post was originally published on my private blog where I write about WordPress and development in general. You can follow me on Twitter or check my private photography project. Oh and you can hire me too
Wanna some more links? No? Okay ;(
The Tangled World of Custom Data in WordPress was originally published in freeCodeCamp on Medium, where people are continuing the conversation by highlighting and responding to this story.
Open Source Design 500
Five hundred open source projects in need of design help
Backstory
You’re a designer. You would like to get involved in open source but don’t know where to begin. You don’t want to work on any open source project. You want to make an impact. But how can you find open source projects that are looking for design help and are being used by many people?
I’ve been asking myself this question for at least a few months. I haven’t been able to find the answer on the web. So I decided to treat it as a design problem.
For more than a year, I explored my answers to the question “What would you like to do if money were no object?” “Building free software” was one of my answers.
I did my research. Most open source projects are on GitHub. GitHub has a feature where users can star projects. This is how GitHub describes stars:
You can star repositories to keep track of projects you find interesting and discover similar projects in your news feed.
Starring a repository makes it easy to find again later. […]
Starring a repository also shows appreciation to the repository maintainer for their work.
In the absence of better alternatives, I allowed myself to assume that the number of stars could serve to measure the impact of a project.
Things to do in projects are called “issues” on GitHub. GitHub has a search engine. Is it possible to do a GitHub search for current issues labeled “ux”, “ui” or “design” and sort them according to the number of stars awarded to the projects?
No.
Hmm.
I learned what I needed to learn and wrote a program that builds such a list. At the time of this writing, it returns 17,742 issues. 17,742 things to do in 2,942 projects. It took two hours to extract all this data from GitHub. And these are just the things from the last 12 months. It’s an excessive amount of data.
What can be done with all this data? A lot. The first thing I’m doing is making the following list of 500 open source projects in need of help from designers. I hope that this is an inspiration for you. It helped me and I believe that it will help you too.
Five hundred open source projects in need of design help1. freeCodeCamp/freeCodeCamp・291470 stars
2. atom/atom・42019 stars
3. Microsoft/vscode・39428 stars
4. jekyll/jekyll・32036 stars
5. getlantern/lantern・30073 stars
6. zurb/foundation-sites・26701 stars
7. neovim/neovim・25132 stars
8. TryGhost/Ghost・24453 stars
9. nylas/nylas-mail・23737 stars
10. ant-design/ant-design・20182 stars
11. Leaflet/Leaflet・20065 stars
12. apache/incubator-superset・16920 stars
13. storybooks/storybook・16143 stars
14. npm/npm・14633 stars
15. facebook/jest・13737 stars
16. angular-ui/ui-router・13671 stars
17. ipython/ipython・12177 stars
18. angular/material2・12073 stars
19. NativeScript/NativeScript・11807 stars
20. diaspora/diaspora・11493 stars
21. keystonejs/keystone・11433 stars
22. tootsuite/mastodon・11413 stars
23. source-foundry/Hack・10407 stars
24. LightTable/LightTable・9930 stars
25. JuliaLang/julia・9577 stars
26. Automattic/wp-calypso・9463 stars
27. fabric/fabric・9298 stars
28. pockethub/PocketHub・9087 stars
29. chmln/flatpickr・9055 stars
30. spree/spree・8870 stars
31. WhisperSystems/Signal-Android・8475 stars
32. elastic/logstash・8302 stars
33. OpenEmu/OpenEmu・8187 stars
34. docker/kitematic・8057 stars
35. metabase/metabase・7605 stars
36. FineUploader/fine-uploader・7346 stars
37. Wox-launcher/Wox・7329 stars
38. CachetHQ/Cachet・7300 stars
39. mailpile/Mailpile・7141 stars
40. mozilla/metrics-graphics・6759 stars
41. ether/etherpad-lite・6621 stars
42. apex/apex・6386 stars
43. travis-ci/travis-ci・6263 stars
44. ory/editor・6232 stars
45. brave/browser-laptop・6227 stars
46. SFTtech/openage・6213 stars
47. telegramdesktop/tdesktop・6106 stars
48. ianstormtaylor/slate・6051 stars
49. insidegui/WWDC・6036 stars
50. reactioncommerce/reaction・6009 stars
51. joemccann/dillinger・5716 stars
52. keeweb/keeweb・5687 stars
53. owncloud/core・5656 stars
54. zulip/zulip・5582 stars
55. gravitational/teleport・5431 stars
56. the-control-group/voyager・4990 stars
57. MonoGame/MonoGame・4724 stars
58. OpenRA/OpenRA・4657 stars
59. ant-design/ant-design-pro・4527 stars
60. topcoat/topcoat・4276 stars
61. icsharpcode/ILSpy・4105 stars
62. Strider-CD/strider・4053 stars
63. spinnaker/spinnaker・3940 stars
64. rsms/inter・3917 stars
65. rtfd/readthedocs.org・3873 stars
66. prose/prose・3869 stars
67. apex/up・3835 stars
68. HospitalRun/hospitalrun-frontend・3772 stars
69. Sylius/Sylius・3723 stars
70. mattgodbolt/compiler-explorer・3584 stars
71. netlify/netlify-cms・3582 stars
72. askmike/gekko・3575 stars
73. scylladb/scylla・3539 stars
74. malcommac/SwiftDate・3435 stars
75. jaegertracing/jaeger・3391 stars
76. koreader/koreader・3382 stars
77. flarum/core・3380 stars
78. apache/couchdb・3338 stars
79. nextcloud/server・3221 stars
80. wallabag/wallabag・3172 stars
81. vmware/harbor・3146 stars
82. HearthSim/Hearthstone-Deck-Tracker・3133 stars
83. hashicorp/nomad・3040 stars
84. mawww/kakoune・2995 stars
85. transloadit/uppy・2995 stars
86. twitter/heron・2990 stars
87. jupyter/jupyter・2941 stars
88. googlearchive/chromedeveditor・2901 stars
89. eventbrite/britecharts・2890 stars
90. postmanlabs/postman-app-support・2854 stars
91. ricochet-im/ricochet・2812 stars
92. HubPress/hubpress.io・2773 stars
93. benvanik/xenia・2753 stars
94. NVIDIA/DIGITS・2712 stars
95. phpmyadmin/phpmyadmin・2708 stars
96. martanne/vis・2700 stars
97. pyrocms/pyrocms・2672 stars
98. sitespeedio/sitespeed.io・2659 stars
99. lektor/lektor・2567 stars
100. TykTechnologies/tyk・2558 stars
101. mozilla-services/react-jsonschema-form・2504 stars
102. lesspass/lesspass・2481 stars
103. kangax/compat-table・2443 stars
104. statsmodels/statsmodels・2424 stars
105. Microsoft/sqlopsstudio・2402 stars
106. gitextensions/gitextensions・2374 stars
107. redox-os/tfs・2372 stars
108. gephi/gephi・2353 stars
109. owncloud/android・2335 stars
110. duplicati/duplicati・2322 stars
111. freedomofpress/securedrop・2210 stars
112. MovingBlocks/Terasology・2203 stars
113. rundeck/rundeck・2189 stars
114. thoughtbot/shoulda-matchers・2155 stars
115. wordpress-mobile/WordPress-iOS・2104 stars
116. aseprite/aseprite・2081 stars
117. nteract/nteract・2059 stars
118. iron-meteor/iron-router・2057 stars
119. cssmagic/blog・2023 stars
120. tomahawk-player/tomahawk・2004 stars
121. wireapp/wire-android・1976 stars
122. EFForg/https-everywhere・1960 stars
123. bigbluebutton/bigbluebutton・1944 stars
124. opentoonz/opentoonz・1928 stars
125. prikhi/pencil・1919 stars
126. ktorio/ktor・1913 stars
127. iron-io/functions・1861 stars
128. getguesstimate/guesstimate-app・1854 stars
129. howtographql/howtographql・1852 stars
130. CMB2/CMB2・1838 stars
131. Netflix/security_monkey・1833 stars
132. OpenZeppelin/zeppelin-solidity・1812 stars
133. punkave/apostrophe・1807 stars
134. mumble-voip/mumble・1794 stars
135. OpenGrok/OpenGrok・1764 stars
136. fnproject/fn・1747 stars
137. ckan/ckan・1744 stars
138. ampache/ampache・1734 stars
139. fontforge/fontforge・1714 stars
140. trailsjs/trails・1693 stars
141. CartoDB/cartodb・1647 stars
142. alexrj/Slic3r・1643 stars
143. asciidoctor/asciidoctor・1641 stars
144. onyx-platform/onyx・1633 stars
145. solidusio/solidus・1608 stars
146. SUSE/Portus・1606 stars
147. rubygems/rubygems.org・1600 stars
148. divmain/GitSavvy・1597 stars
149. atom/teletype・1587 stars
150. wordpress-mobile/WordPress-Android・1585 stars
151. goldendict/goldendict・1574 stars
152. LMMS/lmms・1572 stars
153. frontendbr/forum・1568 stars
154. verdaccio/verdaccio・1566 stars
155. Radarr/Radarr・1565 stars
156. canjs/canjs・1547 stars
157. status-im/status-react・1546 stars
158. snipe/snipe-it・1525 stars
159. git/git-scm.com・1522 stars
160. montagejs/montage・1519 stars
161. sagalbot/vue-select・1508 stars
162. SSilence/selfoss・1493 stars
163. NixOS/nix・1488 stars
164. SpiderOak/Encryptr・1460 stars
165. vector-im/riot-web・1432 stars
166. swimlane/ngx-charts・1432 stars
167. kimchi-project/kimchi・1410 stars
168. django-admin-bootstrapped/django-admin-bootstrapped・1405 stars
169. seven332/EhViewer・1401 stars
170. Teradata/covalent・1376 stars
171. WordPress/gutenberg・1347 stars
172. jnunemaker/flipper・1322 stars
173. duckduckgo/duckduckgo・1316 stars
174. pypa/warehouse・1285 stars
175. wesnoth/wesnoth・1264 stars
176. bitovi/jquerypp・1256 stars
177. 720kb/ndm・1238 stars
178. ASKBOT/askbot-devel・1231 stars
179. nyaadevs/nyaa・1224 stars
180. mustache/mustache.github.com・1220 stars
181. icefox/git-achievements・1213 stars
182. corda/corda・1207 stars
183. donejs/donejs・1202 stars
184. blockstack/blockstack・1188 stars
185. firebug/firebug・1169 stars
186. nunit/nunit・1150 stars
187. osTicket/osTicket・1141 stars
188. mozilla/thimble.mozilla.org・1129 stars
189. isaacs/github・1118 stars
190. GSA/data.gov・1114 stars
191. Elgg/Elgg・1097 stars
192. Automattic/simplenote-android・1045 stars
193. Schmavery/facebook-chat-api・1034 stars
194. ankidroid/Anki-Android・1028 stars
195. bpmn-io/bpmn-js・1028 stars
196. boostorg/beast・1016 stars
197. jxtech/wechatpy・1012 stars
198. 24pullrequests/24pullrequests・1003 stars
199. composer/packagist・1002 stars
200. iRareMedia/iCloudDocumentSync・997 stars
201. justwatchcom/gopass・987 stars
202. smartstoreag/SmartStoreNET・974 stars
203. purpleidea/mgmt・970 stars
204. dotnet/corefxlab・965 stars
205. translate/pootle・929 stars
206. modoboa/modoboa・910 stars
207. devsnd/cherrymusic・909 stars
208. craftcms/cms・896 stars
209. lightningnetwork/lnd・891 stars
210. fritzing/fritzing-app・889 stars
211. pantsbuild/pants・883 stars
212. stampery/mongoaudit・883 stars
213. EFForg/privacybadger・881 stars
214. jfurrow/flood・872 stars
215. mypaint/mypaint・864 stars
216. mixxxdj/mixxx・858 stars
217. thredded/thredded・844 stars
218. Yoast/wordpress-seo・816 stars
219. trailofbits/manticore・812 stars
220. atom/autocomplete-plus・810 stars
221. blockstack/blockstack-browser・809 stars
222. mirage/irmin・806 stars
223. 4pr0n/ripme・779 stars
224. frappe/frappe・776 stars
225. boostorg/compute・772 stars
226. yeoman/yeoman.github.io・762 stars
227. guyzmo/git-repo・741 stars
228. securitywithoutborders/hardentools・739 stars
229. python/pythondotorg・737 stars
230. allegro/ralph・737 stars
231. material-foundation/material-remixer-android・734 stars
232. ThemeFuse/Unyson・730 stars
233. brave/browser-ios・730 stars
234. duckduckgo/zeroclickinfo-goodies・725 stars
235. akira/exq・712 stars
236. patternfly/patternfly・711 stars
237. JabRef/jabref・704 stars
238. securitytxt/security-txt・702 stars
239. mozilla-mobile/focus-ios・697 stars
240. owtf/owtf・688 stars
241. eslint/espree・687 stars
242. potree/potree・681 stars
243. mavlink/qgroundcontrol・672 stars
244. insidegui/PodcastMenu・667 stars
245. funretro/distributed・655 stars
246. projecthamster/hamster・654 stars
247. pods-framework/pods・653 stars
248. firasdib/Regex101・652 stars
249. FreshRSS/FreshRSS・649 stars
250. opentx/opentx・641 stars
251. LLK/scratch-blocks・640 stars
252. solvespace/solvespace・640 stars
253. HTBox/allReady・629 stars
254. factor/factor・628 stars
255. wavebox/waveboxapp・619 stars
256. nodejs/nodejs.org・612 stars
257. NativeScript/nativescript-cli・605 stars
258. glowing-bear/glowing-bear・605 stars
259. erengy/taiga・595 stars
260. bitovi/funcunit・585 stars
261. sulu/sulu-standard・585 stars
262. webrecorder/webrecorder・583 stars
263. hsz/idea-gitignore・582 stars
264. mulesoft/api-console・579 stars
265. eclipse/smarthome・579 stars
266. emberjs/website・576 stars
267. emoncms/emoncms・572 stars
268. vickychijwani/quill・563 stars
269. ManageIQ/manageiq・562 stars
270. simonmichael/hledger・554 stars
271. wroscoe/donkey・537 stars
272. rwengine/openrw・528 stars
273. alephdata/aleph・518 stars
274. hootsuite/atlantis・513 stars
275. nextcloud/android・511 stars
276. DynamoDS/Dynamo・511 stars
277. consul/consul・509 stars
278. GoldenCheetah/GoldenCheetah・503 stars
279. flosell/lambdacd・503 stars
280. friendica/friendica・500 stars
281. noflo/noflo-ui・498 stars
282. KeitIG/museeks・497 stars
283. mozilla-mobile/focus-android・489 stars
284. exercism/cli・488 stars
285. scout-app/scout-app・487 stars
286. coreinfrastructure/best-practices-badge・486 stars
287. h2non/gentleman・478 stars
288. owncloud/ios・473 stars
289. hyperledger/composer・472 stars
290. vifm/vifm・470 stars
291. prusa3d/Slic3r・467 stars
292. agrafix/Spock・463 stars
293. vector-im/riot-android・462 stars
294. log2timeline/plaso・457 stars
295. GhostText/GhostText・446 stars
296. ushahidi/platform・443 stars
297. EFForg/privacybadgerfirefox-legacy・442 stars
298. influxdata/chronograf・435 stars
299. istresearch/scrapy-cluster・433 stars
300. tgstation/tgstation・432 stars
301. quodlibet/quodlibet・429 stars
302. wallabyjs/public・422 stars
303. colobot/colobot・421 stars
304. chronotope/chrono・418 stars
305. ParabolInc/action・417 stars
306. atom/tree-view・415 stars
307. spack/spack・413 stars
308. HabitRPG/habitica-android・410 stars
309. osresearch/heads・410 stars
310. gdg-x/hoverboard・404 stars
311. fossasia/open-event-webapp・404 stars
312. owncloud/apps・402 stars
313. julianguyen/ifme・402 stars
314. google/blockly-android・402 stars
315. hashview/hashview・401 stars
316. Icinga/icingaweb2・395 stars
317. mikeboers/PyAV・394 stars
318. pencil2d/pencil・390 stars
319. bit-team/backintime・389 stars
320. ethereum/browser-solidity・381 stars
321. OpenXRay/xray-16・377 stars
322. atom/github・375 stars
323. Storj/core・374 stars
324. partkeepr/PartKeepr・372 stars
325. awesome-jobs/vietnam・371 stars
326. kubernetes-helm/monocular・370 stars
327. symfony-cmf/cmf-sandbox・366 stars
328. magefile/mage・364 stars
329. monero-project/kovri・360 stars
330. grena/gruik・358 stars
331. fossasia/loklak_search・357 stars
332. paragonie/airship・357 stars
333. openSUSE/osem・353 stars
334. redmatrix/hubzilla・348 stars
335. OpenPTT/OpenPTT・347 stars
336. kotcrab/vis-editor・342 stars
337. RocketChat/Rocket.Chat.iOS・336 stars
338. jsxc/jsxc・336 stars
339. threema-ch/threema-web・335 stars
340. mysociety/fixmystreet・333 stars
341. NUKnightLab/juxtapose・331 stars
342. codeforscience/sciencefair・329 stars
343. Etar-Group/Etar-Calendar・329 stars
344. Microsoft/pxt・326 stars
345. LLK/scratch-www・325 stars
346. theia-ide/theia・323 stars
347. byte-foundry/prototypo・322 stars
348. internetarchive/openlibrary・319 stars
349. aurelia/cli・317 stars
350. ZenHubIO/support・311 stars
351. haskell-foundation/foundation・308 stars
352. Storj/storjshare-gui・304 stars
353. OpenUserJS/OpenUserJS.org・304 stars
354. cla-assistant/cla-assistant・302 stars
355. roadiz/roadiz・301 stars
356. kbenoit/quanteda・300 stars
357. Spomky-Labs/jose・300 stars
358. nguillaumin/osmtracker-android・299 stars
359. vaadin/vaadin-grid・294 stars
360. ppy/osu-web・291 stars
361. humanmade/WordPress-Importer・288 stars
362. hotosm/osm-tasking-manager2・287 stars
363. Bionus/imgbrd-grabber・286 stars
364. lbryio/lbry-app・284 stars
365. AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet・282 stars
366. Glucosio/glucosio-android・276 stars
367. vinszent/gnome-twitch・276 stars
368. streetmix/streetmix・270 stars
369. CGCookie/retopoflow・265 stars
370. EasyRPG/Player・265 stars
371. coyim/coyim・264 stars
372. tylergaw/colorme・263 stars
373. nuttyartist/notes・261 stars
374. aframevr/aframe-inspector・259 stars
375. autolab/Autolab・256 stars
376. 500tech/mimic・253 stars
377. Kotlin/kotlinx.html・252 stars
378. php-censor/php-censor・249 stars
379. opencollective/opencollective・247 stars
380. ludumdare/ludumdare・245 stars
381. brave/browser-android-tabs・240 stars
382. refreshoxford/django-cbv-inspector・236 stars
383. steemit/condenser・235 stars
384. linkeddata/dokieli・234 stars
385. Microsoft/vscode-arduino・234 stars
386. sulu/sulu・234 stars
387. LLK/scratch-gui・234 stars
388. RocketChat/Rocket.Chat.Android・233 stars
389. Alanaktion/phproject・232 stars
390. nilmtk/nilmtk・232 stars
391. rambler-digital-solutions/rambler-it-ios・226 stars
392. Camelcade/Perl5-IDEA・225 stars
393. openopps/openopps-platform・222 stars
394. benbernard/RecordStream・222 stars
395. mysociety/alaveteli・219 stars
396. Sprytile/Sprytile・217 stars
397. enjalot/blockbuilder・216 stars
398. nunit/docs・215 stars
399. apex/static・215 stars
400. owncloud/music・211 stars
401. bardsoftware/ganttproject・211 stars
402. Automattic/sensei・210 stars
403. mysociety/mapit・208 stars
404. xibosignage/xibo・208 stars
405. Syonix/monolog-viewer・207 stars
406. OpenLiberty/open-liberty・207 stars
407. stelligent/mu・206 stars
408. hacktoberfest17/programming・205 stars
409. astroidmail/astroid・205 stars
410. 18F/18f.gsa.gov・204 stars
411. Philip-Scott/Notes-up・200 stars
412. caskdata/cdap・199 stars
413. nextcloud/calendar・199 stars
414. liberapay/liberapay.com・198 stars
415. atom/one-dark-ui・198 stars
416. Reedyn/Saga・197 stars
417. vector-im/riot-ios・196 stars
418. getgrav/grav-plugin-admin・195 stars
419. rsjaffe/MIDI2LR・195 stars
420. hakaru-dev/hakaru・193 stars
421. chromium/hstspreload.org・193 stars
422. GetDKAN/dkan・193 stars
423. Runalyze/Runalyze・192 stars
424. joakimskoog/AnApiOfIceAndFire・190 stars
425. monero-project/monero-gui・190 stars
426. RemoteTechnologiesGroup/RemoteTech・189 stars
427. ipfs-shipyard/peerpad・189 stars
428. snowleopard/alga・188 stars
429. atom/find-and-replace・187 stars
430. DMOJ/judge・185 stars
431. archimatetool/archi・184 stars
432. Storj/storjshare-daemon・184 stars
433. onury/accesscontrol・183 stars
434. propensive/rapture・183 stars
435. dtolnay/syn・182 stars
436. Vector35/binaryninja-api・182 stars
437. Automattic/wp-super-cache・180 stars
438. TrustWallet/trust-wallet-ios・180 stars
439. mroth/scmpuff・179 stars
440. wallabag/android-app・179 stars
441. decrypto-org/rupture・178 stars
442. trufont/trufont・177 stars
443. algorithmic-music-exploration/amen・175 stars
444. matrix-org/dendrite・175 stars
445. libratbag/libratbag・175 stars
446. Spreads/Spreads・174 stars
447. semperfiwebdesign/all-in-one-seo-pack・174 stars
448. nextcloud/bookmarks・172 stars
449. nightingale-media-player/nightingale-hacking・172 stars
450. vmware/docker-volume-vsphere・171 stars
451. lidarr/Lidarr・171 stars
452. uxbox/uxbox・168 stars
453. OpenRA/ra2・168 stars
454. Spacelog/Spacelog・167 stars
455. AdguardTeam/AdguardForiOS・167 stars
456. RestComm/Restcomm-Connect・165 stars
457. pychess/pychess・165 stars
458. camunda/camunda-modeler・164 stars
459. nextcloud/news・162 stars
460. nextcloud/ios・161 stars
461. codeforamerica/click_that_hood・160 stars
462. ejgallego/jscoq・159 stars
463. Trustroots/trustroots・157 stars
464. QubesOS/qubes-issues・157 stars
465. Microsoft/workbooks・157 stars
466. podlove/podlove-web-player・157 stars
467. publiclab/plots2・156 stars
468. magarena/magarena・156 stars
469. amilajack/popcorn-time-desktop・155 stars
470. quicwg/base-drafts・155 stars
471. balancemymoney/balance-open・154 stars
472. pixelated/pixelated-user-agent・152 stars
473. gap-system/gap・152 stars
474. inaturalist/inaturalist・152 stars
475. HabitRPG/habitica-ios・150 stars
476. lightninglabs/lightning-app・150 stars
477. yetibot/yetibot・149 stars
478. go-restruct/restruct・148 stars
479. nextcloud/nextcloudpi・142 stars
480. nextcloud/mail・140 stars
481. AdguardTeam/AdguardForAndroid・139 stars
482. smartchicago/chicago-atlas・139 stars
483. aaronpk/IndieAuth.com・138 stars
484. cloudflare/doca・138 stars
485. CaliOpen/Caliopen・138 stars
486. googlefonts/fontbakery・137 stars
487. juju/juju-gui・132 stars
488. ekylibre/ekylibre・131 stars
489. atom/settings-view・131 stars
490. rosedu/wouso・130 stars
491. vgstation-coders/vgstation13・129 stars
492. stefan-niedermann/nextcloud-notes・129 stars
493. AppleWin/AppleWin・129 stars
494. httpwg/http-extensions・129 stars
495. mozilla/fxa-content-server・128 stars
496. ZeroK-RTS/Zero-K・128 stars
497. clojure/clojure-site・127 stars
498. lewissbaker/cppcoro・126 stars
499. JohnCoatesOSS/Limitless・126 stars
500. OpenChemistry/tomviz・126 stars
PS: Don’t forget to read How to Contribute to Open Source.
PPS: Yes, I’m going to open-source my code. Give me a dozen days. I need to clean it and write a decent README file.
Open Source Design 500 was originally published in freeCodeCamp on Medium, where people are continuing the conversation by highlighting and responding to this story.
Here's the NSA Agent Who Inexplicably Exposed Critical Secrets
How I built a robot that can beat the Mario Odyssey Jump-Rope Challenge for you
Super Mario Odyssey is quite possibly my favorite Mario game. So much so that I went out of my way to complete every last challenge. But one of them gave me more trouble than all the others combined: Jump-Rope Genius in the Metro Kingdom.
You don’t even need to move. You just need to successfully jump 100 times in succession. But the trick is every five jumps it speeds up until 50, until you’re jumping almost twice a second. Press jump too early and you fail. Press jump too late and you fail. Press jump for too long and… you guessed it, you fail.
After a few dozen or so failed attempts I started joking that I’d just build something to beat it for me… and as the days went by and I still hadn’t finished the challenge my joking turned more serious and I started wondering how to do it.
My first thought was to simply program an Arduino to bridge the connectors for the jump button on a Switch controller, but thankfully I checked the iFixit teardown first because Nintendo controllers since the Wii use dome switches instead of the conductive rubber pads, which makes that impossible (for some fun reading see the evolution of Nintendo controllers over the years).
Switch Joy-Con controllerI was mentally tossing up between buying an older GameCube controller (with adapter) which would be easy to hack, or using a solenoid to physically press a button on a Switch controller, both seemed like viable solutions, but after getting outbid on the first few GameCube controllers selling on eBay I settled on the solenoid route.
After completing 835 of the 836 unique challenges in Mario, I turned all my attention back to the final moon. In order to program something to beat it, first I’d need to measure the timing, so my intention was to record the screen and then count the frames. Before setting up a camera I put a few practice rounds in, and much to my horror, I actually beat the thing legitimately.
Having spent two weeks telling everyone I knew that I was going to program something to beat it (and having most of them scoff) losing the excuse to do so was pretty disappointing.
However being an adult, I realized that I didn’t really need an excuse to waste my time and money (that’s pretty much all we do), so express ordered an Arduino and the necessary components to start my project.
The first step was to figure out how to use an Arduino, which… was pretty straight forward actually, the online editor and tutorials are super easy, and after programming a few flashing LEDs I felt ready to go. The biggest hurdle was actually finding a USB-B cable because honestly who still uses those?
The second step was to figure out the timing, and I made it impressively difficult for myself. I thought I was being clever by recording from the overhead view, and could use the woman’s foot to align frames, when her hand touched her foot I’d call that a revolution, and I painstakingly went through QuickTime pressing the arrow keys to step a frame at a time and counting one, two, three… sixty-eight, sixty-nine, seventy.
The middle frame shows her hand aligned with footThe second and a half step was to realize the jump count was a more reliable measure, and that Final Cut Pro would show me the time and frame count, allowing me to really quickly scrub through the video.
Final Cut ProDo this 50 times… and put all the results into a spreadsheet and you have the secret to Jump-Rope success. Those last 50 jumps? You need to do one every 0.58 seconds.
Measured timings for Mario Jump-Rope challengeWith timings completed I turned my attention to the electronic half of the problem, and fortunately someone who understands electronics (I definitely do not) had already shared how to control a solenoid with an Arduino.
For those who don’t know, a solenoid is really just a cylindrical coil of wire which when you run a current through produces a magnetic field. The name is interchangeable with a few things that use solenoids (the coil part) to do something more complex, in this case push a small metal rod. Turn on the power and the rod pushes out, turn it off and the spring moves it back.
Completed circuitI wired up a circuit with a simple switch and solenoid, and wrote a program that would loop through and trigger it, progressively shortening the timing as it progressed. Flipping the switch would start the loop, turning it off would reset.
This would enable me to manually run Mario into position and flip the switch to start, and also give me an easy way to retry if I messed up (which I anticipated would be often). After a few hours (and some tips from my brother) I had a working circuit!
At this point I’d basically assumed success, and then reality kicked in (or rather, kicked me). In my naiveté I’d assumed the solenoid would be able to trivially depress a Switch button, the one I bought was a 5V solenoid able to move 3mm and apply 80 grams of force, that seemed like a lot (it’s actually less than a single newton).
I held it against the controller and… nothing. No movement, the button refused the budge. Googling for how much force is needed to press a Switch controller yielded no results, and around my house I had no good tools to measure it with.
So, with no good tools, I went looking for some bad ones.
What about cooking measures? I filled 1/3 of a cup with water and balanced that above a button, no movement. I filled 1/2 of a cup with water and it depressed. So there’s your answer, a Joy-Con button needs somewhere between a third and half a cup of water.
Turning those back into real units, 1 cup = 250 ml and the easy thing about the metric system is that weight is derived from the volume of water. 250 ml is 250 grams, so my Joy-Con needed somewhere between 83 grams and 125 grams to depress.
Suddenly my 80 gram solenoid didn’t seem so underpowered, what if I… overpowered it? I was giving it the 5 volts it asked for, but I had a 9 volt power supply. The magnetic force of a solenoid increases with the voltage (actually it goes up with the square of the voltage) so at 9 volts my solenoid should be applying closer to 250 grams, or as I like to think about it, 1 cup of water!
Step four involved attaching the solenoid to the controller. Given how little thought I had put into planning this part, it was no surprise how inelegant the solution turned out. A few pieces of wood raised it over the other buttons, a few pieces of electrical tape held the wood in place, and a rubber band kept the solenoid in position.
I was finally ready to put it all to the test, I warped to the Metro Kingdom, ran up to the challenge, and prepared myself to bask in the sweet glory of my smug success.
And almost immediately failed… My timing was wrong. I manually tweaked a few of the timings in my code and got Mario closer, closer again, and closer still, until he could pretty reliably get to 86.
At that point instead of randomly tweaking things I recorded it playing and returned to Final Cut Pro to recount frames (this time focusing on how many frames nearer/further the rope was getting per 5 jump segment), and while I was a little off in a few places, as Mario was always getting to 50 the only thing requiring changing was the 50+ timing. I reduced it to a jump every 35.2 frames and tried again.
Success! 261 jumps. This felt like a huge victory, you can see in the video it easily trounced my meagre human effort of 102 jumps. I immediately went and woke my wife and tried to explain how cool it was, and when that failed to get me much adulation, resorted to telling my brother who was much more suitably impressed.
However, it’s a robot, why should 261 be a limit? Why can’t it be perfect? I analyzed the frames again and noticed the rope was catching up to Mario ever so slowly, he needed to go faster!
Jump timings, average was measured, actual is what is in codeReducing the timing from a jump every 35.2 frames to one every 35.15 frames (a change of just 0.14%) resulted in a much more successful Mario.
So successful that it was able to play the infuriating Mario Jump-Rope challenge for 35 minutes and 21 seconds before failing… setting a new high score (for me) of 3613.
At first I assumed it failed because my timing was still imperceptibly out, but upon closer inspection of the video it stayed perfectly in sync until it… long pressed! What a human mistake for a computer to make, instead of doing a short quick jump it held the button too long and sent Mario too high, he jumped at the right time but landed late.
In actuality I think it was that the poor solenoid was overheating, earlier in the night while I was playing with timings it had stopped running as well, I think driving it at almost twice the voltage was problematic. In the video you can even see that it pressed a second time during the jump at the correct timing.
As for the code? That was the simplest part. A mere 76 lines of code can play Mario better than me
For simplicities sake I measured all timings in how many frames between jumps, I could count the frames easily in the video, and then just divide by 60 to turn that into seconds.
The code calculates everything using dead reckoning from the time the challenge started, I assumed imprecisions in triggering any single jump would average out. Every loop the code calculates how many milliseconds should have elapsed before the next jump and if that threshold is met turns on the solenoid; there is a short duration that it keeps the solenoid on before resetting (maybe it needed to be shorter to avoid the long-press).
And that’s it… almost stupidly simple, fittingly so, given the nature of the jumping challenge.
I could try again but at almost 40 minutes per attempt I’m just not interested enough. Also, I’ve since discovered that someone went one step better than me, although in a slightly different direction.
Instead of physically pressing a button on their controller they use a library to simulate being a controller enabling them to trivially send signals. When they ran into the same timing challenge as me (only getting a few hundred jumps before failing — they were using the constant 35.18 for their final jumps) they solved that by programmatically monitoring to the video signal, checking the score region and when it changes do another jump. With this method they can reach the max score of 99,999!
You’d think with all of this that I’d have one of the highest scores in the game… you’d be wrong! Only a week ago I’d probably be in the top 100, but a bug has been discovered in the game that enables anyone to glitch this challenge, for almost no effort you can get unlimited jumps and over 10,000 people have now done so. Maybe if Nintendo patch this and reset the score board I’ll dust my solenoid off again, I feel if you can build something to play the game using only the controller itself then that’s kinda legitimate.
How I built a robot that can beat the Mario Odyssey Jump-Rope Challenge for you was originally published in freeCodeCamp on Medium, where people are continuing the conversation by highlighting and responding to this story.
24 Ways
24 Ways, the advent calendar for web geeks, started up again this week. Throughout December they’ll be publishing a wide range of posts all about web design, CSS and front-end development.
Chen Hui Jing has already written a great post about feature queries and Stephanie Drescher published a post today about a tool called sonarwhal
which identifies accessibility, performance and security issues, just to name a few.
Direct Link to Article — Permalink
24 Ways is a post from CSS-Tricks
7 Useful Smartphone Apps For Students
Smartphones have eased the lives of many, and students are no exception. Check out the 7 best smartphone apps for students to help them learn and organize themselves.
This post was first published on eLearning Industry.
File Storage Faces a Perfect Storm, But There’s a Way Out
Cascading Web Design with Feature Queries
Trifacta Expands Data Wrangling on the Cloud with Additional Support of Amazon Web Services and Availability on AWS Marketplace
Inside IBM Design: The era of fetishizing the process of design is finally ending
Top 5 Mobile Interaction Designs of November 2017
How Slack hooks users through artificial urgency
23 Ways To Map An Informal Learning Strategy To Your Online Learning Solution
Here are 23 ways to implement and support informal learning within an online learning environment.
This post was first published on eLearning Industry.
A New Bill Wants Jail Time for Execs Who Hide Data Breaches
Strategic Storytelling for Designers
The Definitive JavaScript Handbook for a developer interview
JavaScript is the most popular programming language and has been since 2014, according to Stack Overflow Survey. It is no wonder that over 1/3rd of all developer jobs require some JavaScript knowledge. So, if you plan to work as a developer in the near future, you should be familiar with this extremely popular language.
The post’s purpose is to bring together all JavaScript concepts that are frequently brought up in developer interviews. It was written so you can review everything you need to know about JavaScript in a single place.
Types & Coercion
There are 7 built-in types: null, undefined , boolean, number, string, object and symbol (ES6).
All of these are types are called primitives, except for object.
- Null vs. Undefined
Undefined is the absence of a definition. It is used as the default value for uninitialized variables, function arguments that were not provided and missing properties of objects. Functions return undefined when nothing has been explicitly returned.
Null is the absence of a value. It is an assignment value that can be assigned to a variable as a representation of ‘no-value’.
- Implicit coercion
Take a look at the following example:
In this case, the string variable name is coerced to true and you have ‘Joey doesn’t share food!’ printed in our console. But how do you know what will be coerced to true and what will be coerced to false?
Falsy values are values that will be coerced to false when forced a boolean coercion on it.
Falsy values: "", 0, null, undefined, NaN, false.
Anything not explicitly on the falsy list is truthy — boolean coerced to true.
Yes. You read it right. Empty arrays, objects and functions are boolean coerced to true!
- String & Number coercion
The first thing you need to be aware of is the + operator. This is a tricky operator because it works for both number addition and string concatenation.
But, the *, / , and -operators are exclusive for numeric operations. When these operators are used with a string, it forces the string to be coerced to a number.
- == vs. ===
It is widely spread that == checks for equality and === checks for equality and type. Well, that is a misconception.
In fact, == checks for equality with coercion and === checks for equality without coercion — strict equality.
Coercion can be tricky. Take a look at the following code:
What would you expect for the following comparison?
console.log(a == b); (1)
This comparison actually returns True. Why?
What really happens under the hood is that if you are comparing a boolean with something other than a boolean, JavaScript coerces that boolean to a number and compares. (2)
This comparison is now between a number and a string. JavaScript now coerces that string to a number and compares both numbers. (3)
In this case, the final comparison 0 == 0 is True.
'0' == false (1)
'0' == 0 (2)
0 == 0 (3)
For a fully comprehension on how such comparisons are performed, you can check ES5 documentation here.
For a cheat sheet, you can click here.
Some tricky comparisons to look out for:
Value vs. Reference
Simple values (also known as primitives) are always assigned by value-copy: null, undefined , boolean, number, string and ES6 symbol.
Compound values always create a copy of the reference on assignment: objects, which includes arrays, and functions.
To copy a compound value by value, you need to make a copy of it. The reference does not point to the original value.
Scope
Scope refers to the execution context. It defines the accessibility of variables and functions in the code.
Global Scope is the outermost scope. Variables declared outside a function are in the global scope and can be accessed in any other scope. In a browser, the window object is the global scope.
Local Scope is a scope nested inside another function scope. Variables declared in a local scope are accessible within this scope as well as in any inner scopes.
You may think of Scopes as a series of doors decreasing in size (from biggest to smallest). A short person that fits through the smallest door — innermost scope — also fits through any bigger doors — outer scopes.
A tall person that gets stuck on the third door, for example, will have access to all previous doors — outer scopes — but not any further doors — inner scopes.
Hoisting
The behavior of “moving” var and function declarations to the top of their respective scopes during the compilation phase is called hoisting.
Function declarations are completely hoisted. This means that a declared function can be called before it is defined.
Variables are partially hoisted. var declarations are hoisted but not its assignments.
let and const are not hoisted.
Function Expression vs. Function Declaration
- Function Expression
A Function Expression is created when the execution reaches it and is usable from then on — it is not hoisted.
- Function Declaration
A Function Declaration can be called both before and after it was defined — it is hoisted.
Variables: var, let and const
Before ES6, it was only possible to declare a variable using var. Variables and functions declared inside another function cannot be accessed by any of the enclosing scopes — they are function-scoped.
Variables declared inside a block-scope, such as if statements and for loops, can be accessed from outside of the opening and closing curly braces of the block.
Note: An undeclared variable — assignment without var, let or const — creates a var variable in global scope.
ES6 let and const are new. They are not hoisted and block-scoped alternatives for variable declaration. This means that a pair of curly braces define a scope in which variables declared with either let or const are confined in.
A common misconception is that const is immutable. It cannot be reassigned, but its properties can be changed!
Closure
A closure is the combination of a function and the lexical environment from which it was declared. Closure allows a function to access variables from an enclosing scope — environment — even after it leaves the scope in which it was declared.
The above example covers the two things you need to know about closures:
- Refers to variables in outer scope.
The returned function access themessage variable from the enclosing scope. - It can refer to outer scope variables even after the outer function has returned.
sayHiToJon is a reference to the greeting function, created when sayHi was run. The greeting function maintains a reference to its outer scope — environment — in which message exists.
One of the main benefits of closures is that it allows data encapsulation. This refers to the idea that some data should not be directly exposed. The following example illustrates that.
By the time elementary is created, the outer function has already returned. This means that the staff variable only exists inside the closure and it cannot be accessed otherwise.
Let’s go deeper into closures by solving one of the most common interview problems on this subject:
What is wrong with the following code and how would you fix it?
Considering the above code, the console will display four identical messages "The value undefined is at index: 4". This happens because each function executed within the loop will be executed after the whole loop has completed, referencing to the last value stored in i, which was 4.
This problem can be solved by using IIFE, which creates a unique scope for each iteration and storing each value within its scope.
Another solution would be declaring the i variable with let, which creates the same result.
Immediate Invoked Function Expression (IIFE)
An IIFE is a function expression that is called immediately after you define it. It is usually used when you want to create a new variable scope.
The (surrounding parenthesis) prevents from treating it as a function declaration.
The final parenthesis() are executing the function expression.
On IIFE you are calling the function exactly when you are defining it.
Using IIFE:
- Enables you to attach private data to a function.
- Creates fresh environments.
- Avoids polluting the global namespace.
Context
Context is often confused as the same thing as Scope. To clear things up, lets keep the following in mind:
Context is most often determined by how a function is invoked. It always refers to the value of this in a particular part of your code.
Scope refers to the visibility of variables.
Function calls: call, apply and bind
All of these three methods are used to attach this into function and the difference is in the function invocation.
.call() invokes the function immediately and requires you to pass in arguments as a list (one by one).
.apply() invokes the function immediately and allows you to pass in arguments as an array.
.call() and .apply() are mostly equivalent and are used to borrow a method from an object. Choosing which one to use depends on which one is easier to pass the arguments in. Just decide whether it’s easier to pass in an array or a comma separated list of arguments.
Quick tip: Apply for Array — Call for Comma.
Note: If you pass in an array as one of the arguments on a call function, it will treat that entire array as a single element.
ES6 allows us to spread an array as arguments with the call function.
char.knows.call(Snow, ...["nothing", "Jon"]); // You know nothing, Jon Snow
.bind() returns a new function, with a certain context and parameters. It is usually used when you want a function to be called later with a certain context.
That is possible thanks to its ability to maintain a given context for calling the original function. This is useful for asynchronous callbacks and events.
.bind() works like the call function. It requires you to pass in the arguments one by one separated by a comma.
'this' keyword
Understanding the keyword this in JavaScript, and what it is referring to, can be quite complicated at times.
The value of this is usually determined by a functions execution context. Execution context simply means how a function is called.
The keyword this acts as a placeholder, and will refer to whichever object called that method when the method is actually used.
The following list is the ordered rules for determining this. Stop at the first one that applies:
- new binding — When using the new keyword to call a function, this is the newly constructed object.
- Explicit binding — When call or apply are used to call a function, this is the object that is passed in as the argument.
Note: .bind() works a little bit differently. It creates a new function that will call the original one with the object that was bound to it.
- Implicit binding — When a function is called with a context (the containing object), this is the object that the function is a property of.
This means that a function is being called as a method.
- Default binding — If none of the above rules applies, this is the global object (in a browser, it’s the window object).
This happens when a function is called as a standalone function.
A function that is not declared as a method automatically becomes a property of the global object.
Note: This also happens when a standalone function is called from within an outer function scope.
- Lexical this — When a function is called with an arrow function =>, this receives the this value of its surrounding scope at the time it’s created.
this keeps the value from its original context.
Strict Mode
JavaScript is executed in strict mode by using the “use strict” directive. Strict mode tightens the rules for parsing and error handling on your code.
Some of its benefits are:
- Makes debugging easier — Code errors that would otherwise have been ignored will now generate errors, such as assigning to non-writable global or property.
- Prevents accidental global variables — Assigning a value to an undeclared variable will now throw an error.
- Prevents invalid use of delete — Attempts to delete variables, functions and undeletable properties will now throw an error.
- Prevents duplicate property names or parameter values — Duplicated named property in an object or argument in a function will now throw an error.
- Makes eval() safer — Variables and functions declared inside an eval() statement are not created in the surrounding scope.
- “Secures” JavaScript eliminating this coercion — Referencing a this value of null or undefined is not coerced to the global object. This means that in browsers it’s no longer possible to reference the window object using this inside a function.
`new` keyword
The new keyword invokes a function in a special way. Functions invoked using the new keyword are called constructor functions.
So what does the new keyword actually do?
- Creates a new object.
- Sets the object’s prototype to be the prototype of the constructor function.
- Executes the constructor function with this as the newly created object.
- Returns the created object. If the constructor returns an object, this object is returned.
What is the difference between invoking a function with the new keyword and without it?
Prototype and Inheritance
Prototype is one of the most confusing concepts in JavaScript and one of the reason for that is because there are two different contexts in which the word prototype is used.
- Prototype relationship
Each object has a prototype object, from which it inherits all of its prototype’s properties.
.__proto__ is a non-standard mechanism (available in ES6) for retrieving the prototype of an object (*). It points to the object’s “parent” — the object’s prototype.
All normal objects also inherit a .constructor property that points to the constructor of the object. Whenever an object is created from a constructor function, the .__proto__ property links that object to the .prototype property of the constructor function used to create it.
(*) Object.getPrototypeOf()is the standard ES5 function for retrieving the prototype of an object. - Prototype property
Every function has a .prototype property.
It references to an object used to attach properties that will be inherited by objects further down the prototype chain. This object contains, by default, a .constructor property that points to the original constructor function.
Every object created with a constructor function inherits a constructor property that points back to that function.
Prototype Chain
The prototype chain is a series of links between objects that reference one another.
When looking for a property in an object, JavaScript engine will first try to access that property on the object itself.
If it is not found, the JavaScript engine will look for that property on the object it inherited its properties from — the object’s prototype.
The engine will traverse up the chain looking for that property and return the first one it finds.
The last object in the chain is the built-in Object.prototype, which has null as its prototype. Once the engine reaches this object, it returns undefined.
Own vs Inherited Properties
Objects have own properties and inherited properties.
Own properties are properties that were defined on the object.
Inherited properties were inherited through prototype chain. Inherited properties are not enumerable (not accessible in a for/in loop).
Object.create(obj) — Creates a new object with the specified prototype object and properties.
Inheritance by reference
An inherited property is a copy by reference of the prototype object’s property from which it inherited that property.
If an object’s property is mutated on the prototype, objects which inherited that property will share the same mutation. But if the property is replaced, the change will not be shared.
Classical Inheritance vs. Prototypal Inheritance
In classical inheritance, objects inherit from classes — like a blueprint or a description of the object to be created — and create sub-class relationships. These objects are created via constructor functions using the new keyword.
The downside of classical inheritance is that it causes:
inflexible hierarchy
tight coupling problems
fragile base class problems
duplication problems
And the so famous gorilla/banana problem — “What you wanted was a banana, what you got was a gorilla holding the banana, and the entire jungle.”
In prototypal inheritance, objects inherit directly from other objects. Objects are typically created via Object.create(), object literals or factory functions.
There are three different kinds of prototypal inheritance:
- Prototype delegation — A delegate prototype is an object which is used as a model for another object. When you inherit from a delegate prototype, the new object gets a reference to the prototype and its properties.
This process is usually accomplished by using Object.create(). - Concatenative inheritance — The process of inheriting properties from one object to another by copying the object’s prototype properties, without retaining a reference between them.
This process is usually accomplished by using Object.assign(). - Functional inheritance — This process makes use of a factory function(*) to create an object, and then adds new properties directly to the created object.
This process has the benefit of allowing data encapsulation via closure.
(*)Factory function is a function that is not a class or constructor that returns an object without using the new keyword.
You can find a complete article on this topic by Eric Elliott here.
Favor composition over class inheritance
Many developers agree that class inheritance should be avoided in most cases. In this pattern you design your types regarding what they are, which makes it a very strict pattern.
Composition, on the other hand, you design your types regarding what they do, which makes it more flexible and reusable.
Here is a nice video on this topic by Mattias Petter Johansson
Asynchronous JavaScript
JavaScript is a single-threaded programming language. This means that the JavaScript engine can only process a piece of code at a time. One of its main consequences is that when JavaScript encounters a piece of code that takes a long time to process, it will block all code after that from running.
JavaScript uses a data structure that stores information about active functions named Call Stack. A Call Stack is like a pile of books. Every book that goes into that pile sits on top of the previous book. The last book to go into the pile will be the first one removed from it, and the first book added to the pile will be the last one removed.
The solution to executing heavy pieces of code without blocking anything is asynchronous callback functions. These functions are executed later — asynchronously.
The asynchronous process begins with an asynchronous callback functions placed into a Heap or region of memory. You can think of the Heap as an Event Manager. The Call Stack asks the Event Manager to execute a specific function only when a certain event happens. Once that event happens, the Event Manager moves the function to the Callback Queue. Note: When the Event Manager handles a function, the code after that is not blocked and JavaScript continues its execution.
The Event Loop handles the execution of multiple pieces of your code over time. The Event Loop monitors the Call Stack and the Callback Queue.
The Call Stack is constantly checked whether it is empty or not. When it is empty, the Callback Queue is checked if there is a function waiting to be invoked. When there is a function waiting, the first function in the queue is pushed into the Call Stack, which will run it. This checking process is called a ‘tick’ in the Event Loop.
Let’s break down the execution of the following code to understand how this process works:
- Initially the Browser console is clear and the Call Stack and Event Manager are empty.
- first() is added to the Call Stack.
- console.log("First message") is added to the Call Stack.
- console.log("First message") is executed and the Browser console displays “First message”.
- console.log("First message") is removed from the Call Stack.
- first() is remove from the Call Stack.
- setTimeout(second, 0) is added to the Call Stack.
- setTimeout(second, 0) is executed and handled by the Event Manager. And after 0ms the Event Manager moves second() to the Callback Queue.
- setTimeout(second, 0) is now completed and removed from the Call Stack.
- third() is added to the Call Stack.
- console.log("Third message") is added to the Call Stack.
- console.log("Third message") is executed and the Browser console displays “Third message”.
- console.log("Third message") is removed from the Call Stack.
- Call Stack is now empty and the second() function is waiting to be invoked in the Callback Queue.
- The Event Loop moves second() from the Callback Queue to the Call Stack.
- console.log("Second message") is added to the Call Stack.
- console.log("Second message") is executed and the Browser console displays “Second message”.
- console.log("Second message") is removed from the Call Stack.
- second() is removed from the Call Stack.
Note: The second() function is not executed after 0ms. The time you pass in to setTimeout function does not relate to the delay of its execution. The Event Manager will wait the given time before moving that function into the Callback Queue. Its execution will only take place on a future ‘tick’ in the Event Loop.
Thanks and congratulations for reading up to this point! If you have any thoughts on this, feel free to leave a comment.
You can follow me on Twitter.
The Definitive JavaScript Handbook for a developer interview was originally published in freeCodeCamp on Medium, where people are continuing the conversation by highlighting and responding to this story.