javascripts internals #1
DESCRIPTION
Presentation from our internal company training, about some internal JS features.TRANSCRIPT
JavaScripts internals #1Martin Pernica | @martindeveloper
Primitive data types in JS How many are there?
JavaScript contains only 3 primitive types – string, number, boolean
These types arent objects. JS runtime wraps these types using objects wrappers String(), Number() a Boolean().
Primitive data types in JS Every primitive type is immutable.
Which means, if you work with variable, everytime will be created copy and original stay untouched – „copy by value“ vs „ copy by reference“.
Data types in JS•null
•undefined
•boolean
•number
•string
•object
•symbol (ES6)
Null is special, yeah thats mean – buggy.
typeof null === "object"; // true
Null magicThis null bug is in JS for 2 decades and maybe never will be fixed.
Because many code using this bug behavior.
How can I test value if it is null properly?
This works because null is “falsy like”.
var a = null;(!a && typeof a === "object"); // true
Undefined Undefined is value for variables which are defined (in valid scope) but doesn’t have value yet.
But I need check if is variable defined at all and can be accessed from current scope, what now?
If you use variable which is not defined or is not accessible from current scope, runtime will fire error ReferenceError.
var a;typeof a === “undefined"// true
Undefined If you use typeof function on non exist variable, it will return “undefined”.
But it will not trigger the error!
var a;typeof a; // undefinedtypeof b; // undefined
Note about Objects Objects are not primtive types. They are composite type.
Composite type holds primitive types and others composite types.
Objects are simple look-tables and compiler break them into primitive types.
Scopes Like in others programming language use variables for data storing and scopes for determining when and where can be variable accessed.
JavaScript is dynamic language and scoping process can be little bit different than in other languages.
Scopes JavaScript (simplified) have:
• Engineo Engine must ensure program compilation and execution
• Compilero Compiler will parse code and generate “native” code for Engine
• Scopeo Big table which collects declared variables and have strict rules for accessing
them.
Scopes
1. Compiler will break it down into tokens and parse them into token tree.
2. After lexing compiler will do code generation (for engine).
3. When compiler reach part “var a”, it asks scope if variable is exist and is accessible. If true, compiler will skip declaration. If false, compiler will ask scope to declare new variable called “a” in current scope.
4. After that compiler will produce code for engine, to handle part “a = 2”. Engine runs will first ask Scope if “a” is accessible from current scope collection. If true, engine will use this “a” variable. If false, engine will looks into nested scopes.
5. If Engine cant find variable “a” in nested scopes, it will raise error.
var a = 2;
ScopesWhen engine needs to look-up for variable “a”, it will use Left hand Side look-up.
There is also Right hand Side look-up.
LHS is trying to find variable container (simplified – area of memory).
RHS is trying to find variable value (simplified – content of memory area).
LHS or RHS is not only used when engine working with variable, it is used when working with functions, objects and other things also.
Nested scopesSometimes code is nested in more than one scope.
For example – one block is nested inside function and function is nested in object and etc.
Engine always trying to look-up every outer scope until found or until when reach last „global“ scope.
Nested scopes - errorsIf RHS look-up fails find variable anywhere, the Engine will throw ReferenceError.
But if LHS look-up fails (at global scope), then Scope will create variable in global scope with that name and it will return it to Engine.
*This “auto creating variable” behavior is not correct and it will fails when program will run in Strict Mode and it will throw ReferenceError too.
Scopes – last wordsSometimes you can “cheat” scoping behavior using eval() or with keyword (deprecated). Do not use them! It will cheat your program, you can make more mistakes and it will be much slower (because you are trying to create scope in runtime and without code optimalizations)!
Scope look-up stops once it finds the first match. You can have same variables in different scopes, but the „last win“. This behavior is called shadowing.
Every function have own scope.
Anonymous functionsMany JS libraries use anonymous function idiomatic style of code.
Anonymous function are easy to write but have some problems:
• They don’t have a name – bad debugging and you cant call them recursive
But you can write inline function expression, it is anonymous function with name.You don’t have declare them outside, but when you write anonymous function, prepend name and that’s it!
Fun fact
Result?
8
(new Date()).getMonth();
Questions?
Next?1. Scope closures
2. Dynamic scope
3. Hoisting
4. Garbage Collector
5. Objects (this)
6. Prototypes
7. ES6 features – let, const …
Thank you for your attention!
Martin Pernica | @martindeveloper
And thank you to authors of great book series „You Dont Know JS“!
http://shop.oreilly.com/product/0636920026327.do
http://shop.oreilly.com/product/0636920033738.do
https://github.com/getify/You-Dont-Know-JS