Skip to content

Instantly share code, notes, and snippets.

@legomushroom legomushroom/JS surprises
Last active Dec 8, 2016

Embed
What would you like to do?
// ---------------------------------------------------------------------------------------------------------------------------
```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
You can’t perform that action at this time.