Last active
December 30, 2019 22:12
-
-
Save legomushroom/76dcc01952d15fb60e07 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// --------------------------------------------------------------------------------------------------------------------------- | |
```javascript | |
function foo () { | |
console.log(a); | |
} | |
var a = 2; | |
function bar () { | |
var a = 3; | |
foo(); | |
} | |
bar(); // 2 | |
``` | |
When foo is called it doesn’t find a inside itself, so steps one level up in scope nesting chain to find the a variable, | |
witch is result in global scope because the foo was declared inside the global scope. This is lexical scope. | |
If we had dynamic scope here, engine, for the RHS lookup of a, looked not where the function foo was declared | |
but rather where it was called from. So it’d find a declaration in bar function. this mechanism is kind of like dynamic scope. | |
// --------------------------------------------------------------------------------------------------------------------------- | |
```javascript | |
foo(); // else | |
if (true) { | |
function foo () { console.log('if'); } | |
} else { | |
function foo () { console.log('else'); } | |
} | |
``` | |
Funtion declaration happens on compile time so both function declarations are accounted. | |
The later *"else"* declaration overwrites the value of the precending one. | |
It can be changed in future versions of javascript and seems to have been changed. | |
// --------------------------------------------------------------------------------------------------------------------------- | |
```javascript | |
var a = {}; | |
Object.defineProperty(a, 'foo', { value: 'bar', writable: false }); | |
var b = Object.create(a); | |
b.foo; // "bar" | |
b.foo = '2'; | |
b.foo; // "bar" | |
Object.keys(b); // [] | |
``` | |
When you assign new value to object's property, the entire [[Prototype]] chain is traversed. | |
If property is found in the chain with `writable: false`, assignment is silently ignored or throws `TypeError` | |
when in `"use strict"` mode. | |
// --------------------------------------------------------------------------------------------------------------------------- | |
```javascript | |
var someObj = { a: 2 }; | |
var myObject = Object.create(someObj); | |
myObject.a++; // !implicit shadowing! | |
someObj.a; // 2 | |
myObject.a; // 3 | |
``` | |
// --------------------------------------------------------------------------------------------------------------------------- | |
```javascript | |
-1 > null; // false | |
0 > null; // false | |
1 > null; // true ! | |
``` | |
Seems like `null` gets coersed to `0` when make comparation. | |
// --------------------------------------------------------------------------------------------------------------------------- | |
```javascript | |
var y = 1; | |
if (function f() {}) { | |
y += typeof f; | |
} | |
console.log(y); // 1undefined | |
``` | |
If condition statement evaluated using `eval` which return `function f()` but `f` of course is not declared in outer scope of eval. | |
// --------------------------------------------------------------------------------------------------------------------------- | |
```javascript | |
console.log(foo); // function foo () {} | |
function foo () {}; | |
var bar = function baz () {}; | |
console.log(baz); // Reference Error: baz is not defined | |
``` | |
Named function expression is declared in current scope and avaliable everywhere in the scope (vs `variable` declaration whcih can be | |
`undefined`) but if you assign the named function expression to a variable, it will be avaliable by that name only inside the function | |
for self reference and will not be avaliable by the name in outer scope. | |
// --------------------------------------------------------------------------------------------------------------------------- | |
Type inference: | |
```javascript | |
var bar = true; | |
console.log(bar + 0); // 1 | |
console.log(bar + "xyz"); // "truexyz" | |
console.log(bar + true); // 2 | |
console.log(bar + false); // 1 | |
``` | |
`Number` + `Boolean` -> `Number`. Because `Boolean` coerced to number (`false` -> 0, `true` -> 1). | |
'String' + _ -> `String`. Because whatever is coerced to `string` and concatenation happens: | |
General rules for `+`: | |
- `Number` + `Number` -> Addition | |
- `Boolean` + `Number` -> Addition | |
- `Number` + `String` -> Concatenation | |
- `String` + `Boolean` -> Concatenation | |
- `String` + `String` -> Concatenation | |
// --------------------------------------------------------------------------------------------------------------------------- | |
```javascript | |
function foo() {}; | |
console.log(foo.name); // foo | |
foo.name = 'bar'; // silently fails or throws in `strict mode` | |
var bar = foo() {}; | |
console.log(bar.name); // foo | |
``` | |
Every function has `name` property that refers to name of `function expression`. This is `readonly` property so attempts to modify it | |
behave accordingly to behaviour of `readonly` properties - silently fail or throw if in `strict mode`. | |
The same property for `Object` is `length` which is always equal to `1`. | |
// --------------------------------------------------------------------------------------------------------------------------- | |
Object.prototype.x = 10 | |
console.log(x); // 10 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment