L33t J4v45cr1pt H4x
seriously though, just some cool info. no h4x involved.
agenda
- a very brief history of jstime
- javascript in html
- syntax
- lesser-known things
- prototypal inheritance
- closures
- "this" and "that" and .bind();
- .. also call and apply
- modular design pattern
- events
very brief history
- developed by Brandon Eich at Netscape
- he designed the language in ten days
- built to be a lightweight complement to java applets that would appeal to amateur programmers
- massively uncertain beginnings, almost derailed completely by some terrible language decisions
- language likely saved by other, more excellent, decisions
- now arguably the most important language on the web.
javascript in html
<html>
<head>
<!-- typical way to load -->
<script src="js/lib0.js"></script>
<!-- new async attr -->
<script async src="js/lib1.js"></script>
<!-- new defer attr -->
<script defer src="js/lib2.js"></script>
</head>
<body>
<main class="main">
<!-- WEBSITE -->
</main>
<!-- browser-friendly way to load -->
<script src="js/lib3.js"></script>
</body>
</html>- content >>> javascript
- blocks downloading and parsing of html
- user-perceived latency
javascript in html
html parsing
script downloading
script execution
html parsing paused
normal <script>

<script async>

<script defer>

javascript in html
alternate method: use js to load js asynchronously
var head = document.getElementsByTagName('head')[0],
script = document.createElement('script');
script.src = url;
head.appendChild(script);problem: no way to dictate order, find dependencies.
solution: REQUIRE.js
// Start the main app logic.
requirejs(['jquery', 'canvas', 'app/sub'],
function ($, canvas, sub) {
//jQuery, canvas and the app/sub module are all
//loaded and can be used here now.
});javascript in html
further performance enhancements
syntax
simple things: EQUALITY
=== operator
syntax
simple things: EQUALITY
long story short, use the === operator. == opens up your code to unintended side-effects.
syntax
simple things
=== operator
function baz() {
var foo = "hello"
var bar = "world"
return
{
one: foo,
two: bar
}
}
baz(); // "undefined"javascript will allow you to omit semicolons. do not do this.
syntax
method signatures
=== operator
// initial definition of foo
function foo(one) {
console.log(one);
}
// this overrides foo. old foo no longer exists.
function foo(one, two) {
console.log(one + " " + two);
}
foo(); // "undefined undefined"
foo("hello"); // "hello undefined"
foo("hello", "world"); // "hello world"
foo("Goodbye", "cruel", "world"); // "Goodbye cruel"
// each function is passed an "arguments" object into its
// context, giving you access to each parameter that
// a function is called within other languages, varying parameters means different methods. not so in javascript.
syntax
logic h4x
=== operator
// logical operators can be used to set variables
function test(foo) {
// adding in false for example. foo will
// be foo or a brand new object.
foo = foo || false || {};
} syntax
constructor convention
=== operator
function Foo() {
this.bar = "Hello";
this.baz = "World!";
}this function is a constructor. you can tell because the first letter is capitalized. more on this later.
syntax
alternate for loop
var obj = {
foo: "Hello",
bar: "World",
baz: "Cheeseburgers"
};
for (var i in obj) {
console.log(obj[i]);
}
// "Hello"
// "World"
// "Cheeseburgers"
// interesting note: Arrays.
var arr = ["zero", "one", "two", "three", "four", "five"];
for(var i in arr) {
console.log(i);
}
// 0
// 1
// 2
// 3
// 4
// 5syntax
callbacks
function iterateOverBoard(fn) {
for(var i = 0;i < spec.size;i++) {
for(var j = 0; j < spec.size;j++) {
if (fn(board[j][i], j, i) === false) {
break;
}
}
}
}
// jsperf indicates Array.join is faster than + operator.
// so, some people do this.
iterateOverBoard(function (val, x, y) {
console.log(["element at (", x, ",", y, ") contains value", val].join());
});lesser-known things
function-level scope (vs block scope)
var x = 1;
console.log(x); // 1
if (true) {
var x = 2;
console.log(x); // 2
}
console.log(x); // 2
var foo = 1;
function bar() {
if (!foo) {
var foo = 10;
}
alert(foo);
}
bar(); // alerts 10
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a); // alerts 1lesser-known things
hoisting
var test = function () {
// instantiation of x. itself, a valid
// statement in js, but would cause x
// to become a global variable.
x = "Hello";
console.log(x);
// declaration of x gets hoisted
// to the top of the function,
// preventing x from becoming global.
var x;
};
var test2 = function () {
foo(); // "foo";
bar(); // TypeError: undefined is not a function
// function declaration is hoisted
function foo() {
console.log("foo");
}
// variable initialization does not get hoisted
var bar = function () {
console.log("bar");
};
};
test(); // "Hello"
console.log(x); // "undefined"lesser-known things
dom rendering potential issues
function expensiveOperation() {
// don't try this at home.
for(var i = 0;i < 10000000;i++) {
document.body.appendChild(document.createElement("div"));
}
}
function methodThatDependsOnOperationSuccess() {
return document.getElementsByTagName("div").length;
}
expensiveOperation();
methodThatDependsOnOperationSuccess(); // has a chance of failure
// alternative:
expensiveOperation();
setTimeout(methodThatDependsOnOperationSuccess, 0);most people are like "let's just give it some time", and set setTimeout's time to like half a second. this misses the point entirely.
prototypal inheritance
objects from objects, not from types
- objects are essentially just property bags
- each object has an internal 'prototype' property which is a reference to its parent object
- if you try to access a property on an object, it ask its prototype if it has it
- this process continues until Object.prototype is hit
prototypal inheritance
forms of object creation
// initial capital letter means this function is a prototype
function Foo () {
function bar() {
console.log(bar);
}
this.test = "Hello";
}
// invoke Function with the "new" keyword, and it runs the
// function in the context of a new object you're creating.
// otherwise, it runs globally.
new Foo();
// WARNING, DO NOT CALL FOO (EVEN THOUGH IT'S A FUNCTION)
// doing so will glom all instance methods/properties to the
// window (more on this later).
Foo();
console.log(test); //"Hello"prototypal inheritance
forms of object creation (part deux)
// Crockfordian abstraction
Object.prototype.begetObject = function () {
function F() {}
F.prototype = this;
return new F();
};
var a = [];
// new object b, whose properties inherit
// from object a, is an array.
var b = a.begetObject();
// Alternate syntax using the "New" keyword.
// note the first letter in "Foo" is capitalized.
function Foo () {
this.a = "hello";
this.b = "world";
}
new Foo(); // correct
Foo(); // oops, all of your variables now exist globally.
// newer form of object instantiation. IE9+
Object.create([prototype], [properties list]);
closures
the most popular interview question ever, simplified.
// not a closure
setInterval(function () {
console.log("Test", 500);
});
// almost a closure
function test (word) {
return function () {
return "Cheese.";
}
}
// yay closures
function test (word) {
return function () {
return word;
}
}
function test (word) {
return {
foo: word
};
}"this" and "that" and "bind"
perhaps the most confusing part of js
// in every function invocation, "this" is set
// to the object before the function.
// e.g., in a.test() below, "this" would be a.
// for foo(), this would be the window.
function foo() {
console.log(this.bar + " " + this.baz);
}
var a = {
bar: "Hello",
baz: "World",
test: function () {
return this.bar + " " + this.baz;
}
};
foo(); // "undefined undefined"
// bind returns a function with
// the passed-parameter set as the
// context. you have the option
// of immediately executing it.
foo.bind(a)(); // "Hello World"
// a common pattern is to store a reference
// to the current "this" for various method calls.
// this would seem very odd to a classical programmer.
var test = {
baz: function() {
var that = this;
function test() {
console.log(this);
console.log(that);
}
test();
}
};
test.baz();
/* window
test */"this" and "that" and "bind"
asynchronous method calls
var test = {
baz: function() {
var that = this;
setTimeout(function () {
// closure! outputs test object
console.log(that);
// outputs "window"
console.log(this);
}, 500);
}
};... also call() and apply()
more context switching
// call() and apply() are methods on function.
// call takes a series of parameters, apply takes an array.
// in both functions, the first parameter is the this
// of the function.
function test(foo, bar, baz) {
console.log(foo + " " + bar + " " + baz);
}
test.call(this, "hello", "world", "cheeseburgers");
test.apply(this, ["hello", "world", "cheeseburgers"]);
module design pattern
some structure to your code
// this pattern allows you to encapsulate logic,
// separate concerns across modules, split modules
// into separate files without wholesale overriding
// the module, use private methods, limit your global
// object footprint.
//
// all of these are good things
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// oh look, more closures!
privateVariable++;
privateMethod();
};
return my;
}());
(function ($, window) {
// now have access to globals jQuery (as $) and window in this code
}(jQuery, window));events
process

events
event bottlenecking
<html>
<head></head>
<body>
<table>
<tbody>
<tr>
<td>Column 1</td>
<td>Column 2</td>
</tr>
.
.
.
<!-- 100,000 rows later.. -->
<tr>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tbody>
</table>
</body>
</html>events
event delegation (with jquery)
// typical event handling
$("#myTable tr").on("click", function (ev) {
console.log("myTable row clicked!");
ev.preventDefault();
ev.stopPropagation();
});
// event delegation
$("#myTable").on("click", "tr", function (ev) {
console.log("myTable row clicked!");
ev.preventDefault();
ev.stopPropagation();
});
// event delegation on the body
// (otherwise known as .live(), which
// is a deprecated method now
$("body").on("click", "#myTable tr", function (ev) {
console.log("myTable row clicked!");
ev.preventDefault();
ev.stopPropagation();
});that's it
those are the things I wanted to cover
var x = ({a:function(c){this.b.push(c);return c?this.a(--c):this.b;},b:[]}.a(~+!"">>>+!""));bonus points: what is a?
JavaScript
By Ben Sterrett
JavaScript
- 571