Your SlideShare is downloading. ×

JavaScript

1,248
views

Published on

Некоторые фичи и интересности со встречи ДевКлаба 30.03.2010

Некоторые фичи и интересности со встречи ДевКлаба 30.03.2010

Published in: Education

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,248
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • Представиться. Будут номера – вопросы в конце. Вас ждёт куча примеров =)
  • Моя задача сегодня сделать так, что бы и те и другие засамневались =)
  • JavaScript – это очень обширная тема и за 45 минут обо всём не расскажешь. По-этому вот об этом я говорить НЕ буду. (Перечислить) И о многом другом
  • вкусности
  • Прежде всего – не путайте ЖС с Жавой. Между ними совершенно ничего общего, кроме названия и чем-то схожево синтаксиса!! ЖаваСкрипт – скорее Лисп в одежде Си. ДжаваСкрипт - Это прототипно-ореентированный язык с динамической типизацией. Прототипное наследование является фишкой, которой нету во многих других языках. ЖС – один из самых популярных языков программирования на земле. В то же время это один из самых ненавистных и непонятых языков =) Часто на ЖС клевещат не по делу, путая ЖС с ДОМ-ом, который реализована просто ужасно. Т.е. ЖС – является деФакто языком программирования в вебе, то у людей, знающих другие языки попросту нет права выбора, а по-этому часто и желания изучать ЖС, что ведёт к непониманию и нелюбви. =) Удивительная особенность ЖС заключается в том, что можно написать что-то работающее и нужное на ЖС без особых знаний самого языка, или даже программирования в целом.
  • В языке есть несколько основных или примитивных типом. Все или почти все они приведены на экране. Все наследуются от прородителя Обжект, и все они могут быть созданы с помощью соответствующих конструкторов, но так делать НЕ НАДО! В каждом из случаев за исключением Даты необходимо использовать литералы.
  • В ЖС практически всё является объектом, а он представляет из себя простой МАП, с ключами и значениями. Ключами может быть ЧТО угодно и значениями тоже. (Описать что на экране) (сказать о зарезервированных словах)
  • Ключи можно итерировать вот таким образом. Как я скажу ещё раз позже объекты в ЖС могут наследовать свойства от других объектов. У любого объекта есть вот такой метод, который подтверждает что такой ключи есть у данного объекта.
  • Функция – это обычный объект. Т.е. к самой функции можно прицепить какое-то свойство.
  • Функцию можно создать несколькими способами. Обычный способ . Так называемый «выражение» при поможи литералов. При этом способе дикларации функция как бы всплывает в начало скоупа и её можно использовать до её появления в коде Второй способ. Так называемый «утверждение». Т.к. Это обычное присвоение к переменной, то использовать можно только после появления в коде. Можно назвать (прив) и присвоить к переменной (пуб), при этом (прив) будет видна только внутри метода.
  • Функцию не обязательно называть. Тогда она является анонимной. В данном случае мы посылаем анонимную функцию (показать) в качестве аргумента. А потом её вызываем (показать).
  • Внутри любой функции есть магическая переменная arguments, в которой .... Это Массиво-подобный объект, т.е. ... С помощью вот такой операции из него можно сделать обычный массиов. Этот метод делает сл. ...
  • Внутри каждого метода есть ещё одна магическая переменная this – в зависимости от того как вы вызываете функцию, this ссылается на разные вещи. Вызывать функции можно так же несколькими способами: – обычный вызов (показать). Тут this – ссылается на глобальный объетк. (об этом позже) - если функция является свойством объекта, то это вызов функции как метода. this - ссылка на объект от которого вызывается метод.
  • 3) Вызов как конструктор, но псевдо. Конструктор, потому что он на выходе выдает объект. Псевдо, потому-что это обычный объект.
  • 4) Вызов метода как конструктор. Для этого при вызове надо добавить ключевое слово new и тогда эта функция возвращает новый объект, который создаёт сама функция. Внутри таких функций this ссылается на новый объект, который создат сама функция. (показать) Если эту функцию вызвать без new то случиться страшное. ... Для того, что бы этого не случалось есть конвеншн, по которому методы конструктуры начинаются с большой буквы.
  • У каждой функции есть два метода apply и call. С помощью них можно вызвать сам метод послав им в качестве аргументов то, на что внутри самой функции будет ссылаться this , а так же можно заслать аргументы.
  • ЖС не Си. Тут операторский скобки и различные блоки не делают нового скоупа. В ЖС скоуп создаёт метод! В ЖС есть понятие глобального скоупа, мало того, для написания в ЖС кода его необходимо использовать. Но делать это надо как можно реже. Далее будут показаны пару способов как это сделать. (Объяснить код)
  • Для того, что бы задекларировать свойство внутри ближайшего скоупа надо использовать ключевое слово var (показать) . Если это опустить, то переменная уйдёт в глобальный скоуп.
  • Объяснить код. И что я хочу что бы случилось. Но что-то не так.
  • Заменим массив на индекс. И wtf – почему везде 7. Потому-что тут i является ссылкой на этот i . А к моменту вызова в этой переменной лежит 7. (т.к. Список пробежал) Как обойти?
  • Использовать вот такую конструкцию. Т.е. Мы делаем анонимную функцию, и тут же её вызываем. Теперь уже и ссылается на аргумент этой функции. И всё работает.
  • Эту конструкцию можно пихнуть даже в качестве аргумента в метод. В этом случае эта анонимная функция возвращает нашу функцию ,которая потом вернёт нужную нам фразу.
  • Многие либы используют эту конструкцию что бы не засорять глобальный скоуп разными переменными. Т.е. Мы делаем анонимную функцию, пихаем в неё всё что нам нужно. Всё то, что создаёт саму либу – и на выходе выдаём объект в котором всё есть. Таким образом в глобальном скоупе лежит только один объект – наша либа.
  • Кложеры. Когда функция имеет доступ к контексту в виде скоупа другой функции, в которой она была создана. В данном случае beerCons видна только внутри конструктора. Т.е. Метод drinkBeer находиться тоже внутри конструктора, он тоже видит эту переменную и может её использовать.
  • Более интересный пример. Описать что делает программа.
  • Классическая задача вычисления радов фибоначи. 453 вызова.
  • С помощью такой конструкции можно сделать функцию вычисляющий рады фибоначи, но при этом у неё есть доступ к массиву внутри кложера, в который при каждов вызове мы кладём вычесленное значение, и если оно уже было вычислено – то возвращаем его. 29 вызовов.
  • Карринг – популярная тема. Т.е. Мы может сделать функцию, которая является другой функцией, у которой уже определена часть аргументов.
  • 1) 2) У каждого есть свойство protoype, которая ссылается на прорадителя.
  • Описать код.
  • Можно дополнять примитивные типа. Например так.
  • Можно сделать вот такое вот переопределение. Которое я назвал кэшем. Эта конструкция делает нечто подобное, что я делал с фибоначи. Но! Это можно прицепить к любой функции. Например.
  • Если применить это к тому же фибоначи, то получается даже 12 вызовов.
  • Итак. А теперь на последок. Всякие вкусненькие мелочи. Тут мы видим некую переменную, в которой есть всё, что нам надо в нашей аппликации. Опять таки для того, что бы не засорять глобальный скоуп,
  • В ЖС существуют два дьявольских близнеца в виде двух операторов сравнения. С помощью дьявольского брата == можно получить такие вот чудеса.
  • С === всё так как надо. От сюда правило!!! Всегда используйте ===
  • Особый тип нул Использование parseInt Сложение двух чисел с плавающей точкой Особая штука NaN
  • Тут две проблемы – фугурные скобки и отсутствие точки с запятой. WTF – почему тут undefined.
  • ЖС сам проставляет точки с запятой. И тогда всё становиться понятно.
  • Ставте скобки ТАК! И ставте точку с запятой после определения функций
  • В ЖС есть очно много плохих мест, которые надо знать в лицо и стараться избегать их, но так же в нём есть много такого, чего нет вдругих языках, чето-то такого, что делает его очень клёвым! =)
  • Transcript

    • 1. JavaScript
      • Подзаголовок
      Александр Мочёнов
    • 2. Вопросы
      • Кто считает, что он знает JavaScript?
      • Кто считает, что JavaScript - какашко?
      1
    • 3. Я не буду говорить о
      • DOM
      • Истории JS и его будущем
      • Регулярных выражениях, Таймерах
      • Подробно о Массивах
      • Конвеншенах
      • И многом другом ...
      2
    • 4. А лучше раскажу о
      • О feature’а х
      • О том, о чём кто-то может не знать
      • О том почему JavaScript - клёвый
      3
    • 5. Факты и мысли
      • JavaScript - is NOT Java!
      • JavaScript has prototypal inheritance
      • Популярность
      • Один для веба
      • The amazing thing about JS is …
      4
    • 6. Литералы 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
    • 7. Объекты cat [ &quot;do&quot; ]( &quot;eat&quot; ); //do - is reserved word assert( cat .status === &quot;eating&quot; ); cat [ &quot;do&quot; ]( &quot;clean_wc&quot; ); >>> Uncaught #<an Object> var cat = { actions:{ sleep: function (){ cat .status = &quot;sleeping&quot; ; }, eat: function (){ cat .status = &quot;eating&quot; ; }, clean_wc: function (){ cat .status = &quot;cleaning wc&quot; ; } }, loves: [ &quot;sleep&quot; , &quot;eat&quot; ], &quot;do&quot; : function ( action ){ if ( this .loves.has( action ) ){ this .actions[ action ](); } else { throw {name: &quot;Cat Exception&quot; , message: &quot;Br-r-r!&quot; }; } } }; 6
    • 8. for ... in 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); 7
    • 9. Функции обычные объекты
      • function talk ( buddy ){
      • return &quot;I talk with &quot; + buddy + &quot; for &quot; +
              • talk.long + &quot; minutes&quot; ;
      • };
      • talk.long = 5;
      • assert(talk( &quot;John&quot; ) === &quot;I talk with John for 5 minutes&quot; );
      8
    • 10. Функции - создание var twiceTen = getTwice(10); //Can use it before declaration // - Function as Expression function getTwice ( value ){ return value * 2; }; assert( twiceTen === 20); // - Function as statement var pub = function priv ( param ){ //param, and priv are visible only here. }; pub(111); //Can use it after declaration. 9
    • 11. Анонимная функц. var callme = function ( func ){ return func(); //calling passed function }; var res = callme( function (){ //I am anonymous function return &quot;Thank you&quot; ; }); assert( res == &quot;Thank you&quot; ); 10
    • 12. arguments 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); 11
    • 13. Вызов функции простой и метод function simpleFunction (){ //this => global object return &quot;simple value&quot; ; }; assert(simpleFunction() === &quot;simple value&quot; ); var obj = { value: &quot;simple value&quot; , method: function (){ //this => parent object return this .value; } }; assert( obj .method() === &quot;simple value&quot; ); 12
    • 14. Вызов функции псевдо-конструктор var juice = function ( type ){ return { make: function (){ //this - parent object this .ready = true ; }, drink: function (){ if ( this .ready){ return &quot;Drinking &quot; + type + &quot; juice!&quot; ; } } }; }; var juice1 = juice( &quot;pineapple&quot; ); juice1 .make(); assert( juice1 .drink() === &quot;Drinking pineapple juice!&quot; ); 13
    • 15. Вызов функции конструктор var Jazz = function ( artist ){ //this - is newly created object (if &quot;new&quot; was used) this .music = &quot;on&quot; ; this .play = function (){ if ( this .music === &quot;on&quot; ){ return artist + &quot; is playing&quot; ; } } return undefined ; //for demo only }; var jazz = new Jazz ( &quot;Louis Armstrong&quot; ); assert( jazz .play() === &quot;Louis Armstrong is playing&quot; ); 14
    • 16. Вызов функции
      • var DeathStar = function (){
      • this .enemy = &quot;Rebel Alliance&quot; ;
      • this .shoot = function (){
      • return &quot;Shoot &quot; + this .enemy + &quot; with superlaser&quot; ;
      • };
      • };
      • var deathStar = new DeathStar ();
      • assert( deathStar .shoot() ===
            • &quot;Shoot Rebel Alliance with superlaser&quot; );
      • //!!! Rebels captured the Death Star ...
      • assert(
        • deathStar .shoot.apply({enemy: &quot;Dark Side&quot; }) ===
        • &quot;Shoot Dark Side with superlaser&quot;
      • );
      15
    • 17. Scope //No C style block scopes var outside = 10; for (;;){ var inside = 10; break ; } assert( outside === inside ); //Global Scope is Bad, but necessary 16
    • 18. Scope var 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 scope two(); } one(); //Only global variables is in this scope assert( globalVar === noVarVar); 17
    • 19. (function(){})(); var letters = [ &quot;D&quot; , &quot;E&quot; , &quot;V&quot; , &quot;C&quot; , &quot;L&quot; , &quot;U&quot; , &quot;B&quot; ]; var sayArr = []; for ( var i = 0; i < letters .length; i ++){ sayArr .push( function (){ return &quot;Say &quot; + letter[ i ] + &quot;!&quot; ; }); } for ( var j = 0; j < sayArr .length; j ++){ console.log( sayArr [ j ]()); } //Say undefined! //Say undefined! //Say undefined! //... 18
    • 20. (function(){})(); var letters = [ &quot;D&quot; , &quot;E&quot; , &quot;V&quot; , &quot;C&quot; , &quot;L&quot; , &quot;U&quot; , &quot;B&quot; ]; var sayArr = []; for ( var i = 0; i < letters .length; i ++){ sayArr .push( function (){ return &quot;Say &quot; + i + &quot;!&quot; ; }); } for ( var j = 0; j < sayArr .length; j ++){ console.log( sayArr [ j ]()); } //Say 7 //Say 7 //Say 7 //... 19
    • 21. (function(){})(); var letters = [ &quot;D&quot; , &quot;E&quot; , &quot;V&quot; , &quot;C&quot; , &quot;L&quot; , &quot;U&quot; , &quot;B&quot; ]; var sayArr = []; for ( var i = 0; i < letters .length; i ++){ ( function ( k ){ sayArr .push( function (){ return &quot;Say &quot;&quot; + letters [ k ] + &quot;&quot; !&quot; ; }); })( i ); } for ( var j = 0; j < sayArr .length; j ++){ console.log( sayArr [ j ]()); } //Say &quot;D&quot; ! //Say &quot;E&quot; ! //Say &quot;V&quot; ! //... 20
    • 22. (function(){})(); 22 var letters = [ &quot;D&quot; , &quot;E&quot; , &quot;V&quot; , &quot;C&quot; , &quot;L&quot; , &quot;U&quot; , &quot;B&quot; ]; var sayArr = []; for ( var i = 0; i < letters .length; i ++){ sayArr .push( ( function ( i ){ return &quot;Say &quot;&quot; + letters [ i ] + &quot;&quot; !&quot; ; })( i ) ); } for ( var j = 0; j < sayArr .length; j ++){ console.log( sayArr [ j ]()); }
    • 23. (function(){})(); 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 here assert(yourLib(30) === 60); 23
    • 24. Closure I’m gonna build my own amusement park. With ... 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 24
    • 25. Closure - guess number
      • function makeGame (){
      • var theNumber = Math.round(Math.random() * 10);
      • var numberOfGuesses = 0;
      • return function ( guess ){
      • numberOfGuesses ++;
      • if ( guess == theNumber ){
      • return &quot;You did it in &quot; + numberOfGuesses + &quot; tries&quot; ;
      • } else {
      • return &quot;No. My number is &quot; +
              • ( guess < theNumber ? &quot;bigger&quot; : &quot;smaller&quot; );
      • }
      • };
      • };
      • var tryToGuess = makeGame();
      • tryToGuess(3); // --> No. My number is bigger
      • tryToGuess(7); // --> No. My number is smaller
      • tryToGuess(5); // --> You did it in 3 tries
      25
    • 26. 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 + &quot; -> &quot; + fibonacci( i )); } assert( count === 453); //453 calls 26
    • 27. Closure - fibonacci 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 + &quot; -> &quot; + fibonacci( i )); } assert( count === 29); 27
    • 28. Curry - friends function friends ( boy , girl ){ return boy + &quot; and &quot; + girl + &quot; are friends.&quot; ; } var boysFriends = function (){ var thatArgs = argArr(arguments); return function (){ var thisArgs = argArr(arguments); return friends.apply( null , thatArgs .concat( thisArgs )); }; }; var johnsFriends = boysFriends( &quot;John&quot; ); assert(johnsFriends( &quot;Jully&quot; ) === &quot;John and Jully are friends.&quot; ); assert(johnsFriends( &quot;Marta&quot; ) === &quot;John and Marta are friends.&quot; ); 28
    • 29. Наследование
      • Наследование от объекта к объекту
      • Prototype - ссылка на родителя
      • Всё идёт от Object
      29
    • 30. Prototype
      • function Monkey (){};
      • var codeMonkey = new Monkey();
      • Monkey.prototype.code = function (){ return &quot;Code, code!&quot; ; };
      • assert( codeMonkey .code() === &quot;Code, code!&quot; );
      • function Vasja (){};
      • Vasja.prototype = new Monkey();
      • var progerVasja = new Vasja();
      • Vasja.prototype.decide = function (){
        • return &quot;Shut-up lemons, I know what to do!&quot; ; };
      • assert( progerVasja .decide() === &quot;Shut-up lemons, I know what to do!&quot; );
      • assert( progerVasja .code() === &quot;Code, code!&quot; );
      30
    • 31. Наследование
      • Прототипное наследование
      • Классическое, типа Классы и всё такое
      • Функциональное
      • Подробнее расскажет Вася.
      31
    • 32. Дополнения к примитивам 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 == &quot;1,6,3,12&quot; ); // == using for casting 32
    • 33. Кэширование метода 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
    • 34. Кэширование метода 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 + &quot; -> &quot; + fibo( i )); } assert( count === 12); 34
    • 35. Вкусненькое scope var var APP = { constants: { MAX_BUK: 10, MIN_BUK: 20 }, messages: { hello_world: &quot;Hello World&quot; , cancel: &quot;Cancel&quot; }, sayHello: function (){ return this .messages.hello_world; } }; 35
    • 36. Вкусненькое использование && и || в выр а жениях var action = function (){ return work && work .doing && work .doing() || &quot;stay home&quot; ; }; assert(action() === &quot;stay home&quot; ); var work = { doing: function (){ return &quot;hard working&quot; ; } }; assert(action() === &quot;hard working&quot; ); 36
    • 37. Вкусненькое falsy values if (0 || NaN || '' || false || null || undefined ){ //All those values are falsy assert( false ); } else { //All other are truthy assert( true ); } 37
    • 38. Вкусненькое evil twins == и === assertFalse( '' == '0' ); //false assertTrue( 0 == '' ); //true assertTrue( 0 == '0' ); //true assertFalse( false == 'false' ); //false assertTrue( false == 0); //true assertFalse( false == undefined ); //false assertFalse( false == null ); //false assertTrue( null == undefined ); //true assertTrue( ' ' == 0); //true 38
    • 39. Вкусненькое evil twins assertFalse( '' === '0' ); assertFalse( 0 === '' ); assertFalse( 0 === '0' ); assertFalse( false === 'false' ); assertFalse( false === 0); assertFalse( false === undefined ); assertFalse( false === null ); assertFalse( null === undefined ); assertFalse( ' ' === 0); 39
    • 40. Вкусненькое null, parseInt, IEEE 754, NaN //null var nullable = null ; assert( typeof nullable === 'object' ); assert(nullable === null ); //pasreInt assert(parseInt( &quot;08&quot; ) === 0); //Octal assert(parseInt( &quot;08&quot; , 10) === 8); //Decimal //IEEE 754 assert(0.1 + 0.2 !== 0.3); //NaN var notANum = NaN; assert( typeof notANum === 'number' ); assert( notANum !== notANum ); assert(isNaN( notANum )); 40
    • 41. Вкусненькое brackets style function iLikeCStyleBrackets () { return { word: &quot;boo-gaga&quot; } } var s = iLikeCStyleBrackets(); //assert(s.word === &quot;boo-gaga&quot;); //Makes error assert( s === undefined ); 41
    • 42. Вкусненькое brackets style function iLikeCStyleBrackets () { return ; { word: &quot;boo-gaga&quot; }; }; 42
    • 43. Вкусненькое brackets style function iUseGoodBrackets (){ return { word: &quot;good boy&quot; }; }; var s = iUseGoodBrackets(); assert( s .word === &quot;good boy&quot; ); 43
    • 44. Книги JavaScript: The Good Parts JavaScript Ninja JavaScript: The Definitive Guide Douglas Crockford John Resig David Flanagan
    • 45. JavaScript – это клёва!
    • 46. Спасибо! Александр Мочёнов [email_address]

    ×