javascript secrets by aleksandr motsjonov
DESCRIPTION
TRANSCRIPT
JavaScriptПодзаголовок
Александр Мочёнов
Вопросы
•Кто считает, что он знает JavaScript?
•Кто считает, что JavaScript - какашко?
1
Я не буду говорить о
•DOM
•Истории JS и его будущем
•Регулярных выражениях, Таймерах
•Подробно о Массивах
•Конвеншенах
•И многом другом ...
2
А лучше раскажу о
•О feature’ах
•О том, о чём кто-то может не знать
•О том почему JavaScript - клёвый
3
Факты и мысли
•JavaScript - is NOT Java!
•JavaScript has prototypal inheritance
•Популярность
•Один для веба
•The amazing thing about JS is …
4
Литералы
var obj = {object: "literal"}; // === new Object();var str = "string literal"; // === new String();var arr = [10, 20, 30]; // === new Array();var num = 10; // === new Number();var boo = true; // === new Boolean();var reg = /regexp literal/i; // === new RegExp();var fun = function(){return true;} // === new Function();var dat = new Date(2010, 11, 30); // no literal
Object()
String()
Number()
Boolean()
... etc 5
Объекты
cat["do"]("eat"); //do - is reserved wordassert(cat.status === "eating");
cat["do"]("clean_wc");>>> Uncaught #<an Object>
var cat = {actions:{
sleep: function(){ cat.status = "sleeping"; },eat: function(){ cat.status = "eating"; },clean_wc: function(){ cat.status = "cleaning wc"; }
},
loves: ["sleep", "eat"],
"do": function(action){if( this.loves.has(action) ){
this.actions[action]();}else{
throw {name:"Cat Exception", message:"Br-r-r!"}; }
}};
6
var budget = {beer : 1250,sandwich : 500,pizza: 670
};
var sum = 0;for(item in budget){
if(budget.hasOwnProperty(item)){sum += budget[item];
}}assert(sum === 2420);
for ... in
7
Функцииобычные объекты
function talk(buddy){return "I talk with " + buddy + " for " +
talk.long + " minutes";};
talk.long = 5;
assert(talk("John") === "I talk with John for 5 minutes");
8
Функции - создание
var twiceTen = getTwice(10); //Can use it before declaration// - Function as Expressionfunction getTwice(value){
return value * 2;};assert(twiceTen === 20);
// - Function as statementvar pub = function priv(param){
//param, and priv are visible only here.};pub(111); //Can use it after declaration.
9
var callme = function(func){return func(); //calling passed function
};
var res = callme(function(){ //I am anonymous functionreturn "Thank you";
});
assert(res == "Thank you");
Анонимная функц.
10
var argArr = function(args){return Array.prototype.slice.apply(args);
};
var argSum = function(){var sum = 0;var argArray = argArr(arguments);argArray.push(5);for(var i = 0; i < argArray.length; i++){
sum += argArray[i];}return sum;
};
assert(argSum(1,2,3,4) === 15);
arguments
11
Вызов функциипростой и метод
function simpleFunction(){//this => global objectreturn "simple value";
};assert(simpleFunction() === "simple value");
var obj = {value: "simple value",method: function(){
//this => parent objectreturn this.value;
}};assert(obj.method() === "simple value");
12
var juice = function(type){return {
make: function(){//this - parent objectthis.ready = true;
},drink: function(){
if(this.ready){return "Drinking "+type+" juice!";
}}
};};
var juice1 = juice("pineapple");juice1.make();assert(juice1.drink() === "Drinking pineapple juice!");
Вызов функциипсевдо-конструктор
13
Вызов функцииконструктор
var Jazz = function(artist){//this - is newly created object (if "new" was used)this.music = "on";this.play = function(){
if(this.music === "on"){return artist + " is playing";
}}return undefined; //for demo only
};
var jazz = new Jazz("Louis Armstrong");assert(jazz.play() === "Louis Armstrong is playing");
14
var DeathStar = function (){this.enemy = "Rebel Alliance";this.shoot = function(){
return "Shoot " + this.enemy + " with superlaser";};
};
var deathStar = new DeathStar();assert(deathStar.shoot() ===
"Shoot Rebel Alliance with superlaser");
//!!! Rebels captured the Death Star ... assert(
deathStar.shoot.apply({enemy:"Dark Side"}) ==="Shoot Dark Side with superlaser"
);
Вызов функции
15
Scope
//No C style block scopesvar outside = 10;for(;;){
var inside = 10;break;
}assert(outside === inside);
//Global Scope is Bad, but necessary
16
Scopevar globalVar = 10;function one(){
var innerVar = 10;function two(){
var innerInnerVar = 10;noVarVar = 10;assert(globalVar === innerVar &&
innerVar === innerInnerVar);}assert(globalVar === innerVar);//innerInnerVar - not in this scopetwo();
}one();//Only global variables is in this scopeassert(globalVar === noVarVar);
17
(function(){})();
var letters = ["D","E","V","C","L","U","B"];var sayArr = [];for(var i = 0; i < letters.length; i++){
sayArr.push(function(){return "Say " + letter[i] + "!";
});}
for(var j = 0; j < sayArr.length; j++){console.log(sayArr[j]());
}//Say undefined!//Say undefined!//Say undefined!//...
18
var letters = ["D","E","V","C","L","U","B"];var sayArr = [];for(var i = 0; i < letters.length; i++){
sayArr.push(function(){return "Say " + i + "!";
});}
for(var j = 0; j < sayArr.length; j++){console.log(sayArr[j]());
}//Say 7//Say 7//Say 7//...
(function(){})();
19
var letters = ["D","E","V","C","L","U","B"];var sayArr = [];for(var i = 0; i < letters.length; i++){
(function(k){sayArr.push(function(){
return "Say \"" + letters[k] + "\" !";});
})(i);}for(var j = 0; j < sayArr.length; j++){
console.log(sayArr[j]());}//Say "D" !//Say "E" !//Say "V" !//...
(function(){})();
20
(function(){})();
22
var letters = ["D","E","V","C","L","U","B"];var sayArr = [];for(var i = 0; i < letters.length; i++){
sayArr.push((function(i){
return function(){ return "Say \"" + letters[i] + "\" !";
};})(i)
);}for(var j = 0; j < sayArr.length; j++){
console.log(sayArr[j]());}
var yourLib = (function(){var i = 10;var b = 20;
//your scoped code here
function innerLib(c){return c + i + b;
};
return innerLib;})();//i, b not visible hereassert(yourLib(30) === 60);
(function(){})();
23
var RudeRobot = function(){ var beerCans = 0; //Private variable this.drinkBeer = function(){ beerCans++; return this; };};var bender = new RudeRobot();bender.drinkBeer().drinkBeer();//Can't find out how many beers Bender drunk
ClosureI’m gonna build my own amusement park. With ...
24
function makeGame(){ var theNumber = Math.round(Math.random() * 10); var numberOfGuesses = 0; return function(guess){ numberOfGuesses++; if(guess == theNumber){ return "You did it in " + numberOfGuesses + " tries"; }else{ return "No. My number is " +
(guess < theNumber ? "bigger" : "smaller"); } };};var tryToGuess = makeGame();tryToGuess(3); // --> No. My number is biggertryToGuess(7); // --> No. My number is smallertryToGuess(5); // --> You did it in 3 tries
Closure - guess number
25
Closure - fibonacci
var count = 0;var fibonacci = function fib(n){
count++;return n < 2 ? n : fib(n - 1) + fib(n - 2);
};
for(var i = 0; i <= 10; i += 1){console.log(i + " -> " + fibonacci(i));
}assert(count === 453); //453 calls
26
var count = 0;var fibonacci = (function(){
var memo = [0, 1];var fib = function (n){
count++;var result = memo[n];if (typeof result !== 'number'){
result = fib(n - 1) + fib(n - 2);memo[n] = result;
}return result;
};return fib;
})();
for(var i = 0; i <= 10; i++){console.log(i + " -> " + fibonacci(i));
}assert(count === 29);
Closure - fibonacci
27
Curry - friendsfunction friends(boy, girl){
return boy + " and " + girl + " are friends.";}var boysFriends = function(){
var thatArgs = argArr(arguments);return function(){
var thisArgs = argArr(arguments);return friends.apply(null, thatArgs.concat(thisArgs));
};};
var johnsFriends = boysFriends("John");assert(johnsFriends("Jully") === "John and Jully are friends.");assert(johnsFriends("Marta") === "John and Marta are friends.");
28
Наследование
•Наследование от объекта к объекту
•Prototype - ссылка на родителя
•Всё идёт от Object
29
function Monkey(){}; var codeMonkey = new Monkey();
Monkey.prototype.code = function(){ return "Code, code!"; };assert( codeMonkey.code() === "Code, code!");
function Vasja(){};Vasja.prototype = new Monkey();
var progerVasja = new Vasja();Vasja.prototype.decide = function(){
return "Shut-up lemons, I know what to do!"; };
assert( progerVasja.decide() === "Shut-up lemons, I know what to do!");assert( progerVasja.code() === "Code, code!");
Prototype
30
Наследование
•Прототипное наследование
•Классическое, типа Классы и всё такое
•Функциональное
•Подробнее расскажет Вася.
31
Дополнения к примитивам
Array.prototype.map = function(fn){for(var i = 0, size = this.length; i < size; i++){
this[i] = fn.call(this[i], i, this);}return this;
};
var arr = [1,2,3,4].map(function(i, array){if(this % 2 == 0){
return this * 3;}return this;
});assert(arr == "1,6,3,12"); // == using for casting
32
Кэширование метода
Function.prototype.cached = function(){var _cache = {};var fun = this;return function(){
var args = argArr(arguments);var result = _cache[args];if(!result){
result = fun.apply(null, args);_cache[args] = result;
}return result;
};};
33
Кэширование метода
Function.prototype.cached = function(){...
var count = 0;var fibo = function (n){
count++;return n < 2 ? n : fibo(n - 1) + fibo(n - 2);
}.cached();
for(var i = 0; i <= 10; i += 1){console.log(i + " -> " + fibo(i));
}assert(count === 12);
34
Вкусненькоеscope var
var APP = {constants: {
MAX_BUK: 10,MIN_BUK: 20
},messages: {
hello_world: "Hello World",cancel: "Cancel"
},sayHello: function(){
return this.messages.hello_world;}
};
35
Вкусненькоеиспользование && и || в выражениях
var action = function(){return work && work.doing && work.doing() || "stay home";
};assert(action() === "stay home");
var work = {doing: function(){ return "hard working"; }
};assert(action() === "hard working");
36
Вкусненькоеfalsy values
if(0 || NaN || '' || false || null || undefined){//All those values are falsyassert(false);
}else{//All other are truthyassert(true);
}
37
assertFalse('' == '0'); //falseassertTrue( 0 == '' ); //trueassertTrue( 0 == '0'); //true
assertFalse(false == 'false'); //falseassertTrue( false == 0); //true
assertFalse(false == undefined); //falseassertFalse(false == null); //falseassertTrue( null == undefined); //true
assertTrue(' \t\r\n' == 0); //true
Вкусненькоеevil twins == и ===
38
assertFalse('' === '0');assertFalse( 0 === '' );assertFalse( 0 === '0');
assertFalse(false === 'false');assertFalse(false === 0);
assertFalse(false === undefined);assertFalse(false === null);assertFalse( null === undefined);
assertFalse(' \t\r\n' === 0);
Вкусненькоеevil twins
39
Вкусненькоеnull, parseInt, IEEE 754, NaN
//nullvar nullable = null;assert(typeof nullable === 'object');assert(nullable === null);
//pasreIntassert(parseInt("08") === 0); //Octalassert(parseInt("08", 10) === 8); //Decimal
//IEEE 754assert(0.1 + 0.2 !== 0.3);
//NaNvar notANum = NaN;assert(typeof notANum === 'number');assert(notANum !== notANum);assert(isNaN(notANum)); 40
function iLikeCStyleBrackets(){
return{
word:"boo-gaga"}
}
var s = iLikeCStyleBrackets();//assert(s.word === "boo-gaga"); //Makes errorassert(s === undefined);
Вкусненькоеbrackets style
41
Вкусненькоеbrackets style
function iLikeCStyleBrackets(){
return;{
word:"boo-gaga"};
};
42
Вкусненькоеbrackets style
function iUseGoodBrackets(){return {
word:"good boy"};
};var s = iUseGoodBrackets();assert(s.word === "good boy");
43
Книги
JavaScript: The Good
Parts
JavaScript Ninja
JavaScript: The Definitive
Guide
Douglas Crockford John Resig David Flanagan
JavaScript – это клёва!
Спасибо!
Александр Мочёнов[email protected]