Self-Executing Anonymous Functions (자가 실행 익명 함수)

프론트앤드/JavaScript 2016. 6. 25. 01:25 by kira-master

When learning JavaScript, with all the attention given to variables, functions, 'if' statements, loops and event handlers, often little is done to educate you on how you might cleanly organise your code into a cohesive, structurally-sound whole.

자바 스크립트를 배우면서 변수, 함수, if , 반복 그리고 이벤트 핸들러에 관심을 갖다 보면, 아마도 당신은 깔끔하게 당신의 코드가 전체적으로 응집도가 있고 , 아주 구조적으로 구성해야 하는지에 대해서 교육을 받게 됩니다. ,

Let's take the following code for example:

다음과 같은 코드를 예로 들어 봅시다.

 

var foo = 'Hello';
var bar = 'World!';

function baz(){
return foo + ' ' + bar;
}

console.log(baz());

 

 

 

This style of code looks quite normal, works fine and doesn't cause any problems. At least for now.

코드 스타일은 아주 평범합니다, 작동도 아주 잘되고 어떤 문제를 일으키지는 않습니다. 적어도 지금은 말이죠.

This style of code, when implemented in a large application, can start to become an unwieldy mess. The global namespace becomes littered with functions and variables, all tenuously linked to each other through a combination of rudimentary comments and potentially unspoken developer knowledge.

코드의 스타일로 거대한 어플리케이션에 구현되면 거추장스러운 상태로 되기 시작합니다. 전역 네임스페이스는

The first step on the journey to beautiful, modular JavaScript is to learn the art of the self-executing anonymous function.


(function(){
console.log('Hello World!');
})();

 

 

Let's look at this carefully. This code is made up of two key parts.

주위 깊게 보세요, 코드는 2가지 핵심적인 부분이 있습니다.

First is the anonymous function:

첫째는 익명 함수 입니다.

 


(function(){
//Normal code goes here
})

 

 

 

The really interesting part is what happens when we add this right at the end:

정말로 흥미로운 것은 우리가 아래 코드를 끝에 추가할 어떤 일이 일어난다는 것이다.

 

 

();

 

 

 

Those two little brackets cause everything contained in the preceding parentheses to be executed immediately. What's useful here is that JavaScript has function level scoping. All variables and functions defined within the anonymous function aren't available to the code outside of it, effectively using closure to seal itself from the outside world.

두개의 소괄호는 이전 괄호에 포함된 모든 것을 즉시 실행되게 한다. 이것의 유용 함은 자바스크립트에서 함수 수준 범위를 가진다는 것에 있다.

익명 함수 이내의 모든 변수, 함수들은 익명 함수 밖에 코드에 접근할 없고, 이것은 효과적으로 외부 영역으로부터 익명 함수를 감싸서 막는 것이다.

Let's apply this design patten to our gloriously inane example code.

우리의 아주 화려하게 초라한 예제 코드에 디자인 패턴을 적용해보자.

 



(function(){
var foo = 'Hello';
var bar = 'World!'

function baz(){
return foo + ' ' + bar;
}
})();

//These all throw exceptions:
console.log(foo);
console.log(bar);
console.log(baz());

 

 

The last three lines throw exceptions because currently nothing is accessible outside the anonymous function. To allow access to a variable or function, we need to expose it to the global 'window' object.

현재 어떤 것도 익명 함수 내부에는 접근할 없기 때문에 밑에서 3번쨰 라인에서 에러가 난다. 변수 또는 함수를 접근을 허용하기 위해서는, 우리는 글로벌 window 객체에 익명 함수를 노출하는 것이 필요한다.

 



(function(){
var foo = 'Hello';
var bar = 'World!'

function baz(){
return foo + ' ' + bar;
}

window.baz = baz; //Assign 'baz' to the global variable 'baz'...
})();

console.log(baz()); //...and now this works.

//It's important to note that these still won't work:
console.log(foo);
console.log(bar);

 

One of the major benefits of this pattern, as seen on the last two lines of the previous example, is that you can limit access to variables and functions within your closure, essentially making them private and only choosing to expose an API of your choice to the global scope.

패턴의 주된 이점 중에 하나는 , 예제에서 밑에서 2번째 라인을 보면 , 당신의 클로져 내부의 변수, 함수들에 대한 접근을 제한시킬 있고 , 기본적으로 Private 하면서 , 오직 global 영역에 당신의 선택에 의한 API들을 노출시키는 것을 선택할 있다.

One popular spin on this design pattern, which can be seen in the jQuery source, is to pass in some commonly used objects. In our code we reference 'window', so let's pass that in as a parameter to the anonymous function.

제이쿼리에서도 있었던 것처럼, 디자인 패턴의 하나의 일반적인 흐름은 공통적으로 공통적으로 객체를 사용하여 넘기는 것이다. 우리가 참조한 WINDOW 우리 코드에서 , 익명함수의 파라미터로 넘겨보자.

 

 



(function(window){
var foo = 'Hello';
var bar = 'World!'

function baz(){
return foo + ' ' + bar;
}

//In this context, 'window' refers to the parameter
window.baz = baz;
})(window); //Pass in a reference to the global window object

 

 

 

 

When minifying your code, this design pattern will yield great results. All references to 'window' in your code can be renamed to 'a', for example:

당신의 코드를 축소할 , 디자인 패턴은 아주 좋은 결과를 가져온다. 당신의 코드에서 Window 대한 모든 참조들은 아래 예처럼 a 새롭게 이름을 바꿀 있다..

 

(function(a){
console.log(a === window); //Returns 'true'
})(window);

 

 

Normally you'll want to pass in a few objects. A technique you can see used within jQuery itself is to reference an extra parameter that isn't defined when the anonymous function is executed, in effect creating an alias for 'undefined':

일반적으로 당신은 개의 객체를 넘기는 원한다. 제이쿼리 자체에서 사용한 기술을 보면, 익명 함수가 실행될 효과적으로 undefined alias 만들면서 여분의 파라미터를 참조하는 것이다.

 


(function(window, document, $, undefined){
var foo;
console.log(foo === undefined); //Returns 'true'
})(window, document, jQuery);

 

 

You may have noticed that the previous example also aliased 'jQuery' to '$', allowing it to play nicely with other frameworks without having to use jQuery in noConflict mode.

It's worth pointing out that the parameter names are purely for convention. The following code would work equally as well and serves as a great illustration of what's really going on in this design pattern:

충돌 모드를 사용하지 않고도 다른 프레임워크들과 문제 없이 동작하도록 해주는 이전 예시에서 jQuery 또는 $ rename 했다는 것을 알아차릴 있다.

It's worth pointing out that the parameter names are purely for convention. The following code would work equally as well and serves as a great illustration of what's really going on in this design pattern:

이것은


(function(mark, loves, drinking, coffee){
mark.open('http://www.google.com'); //window
loves.getElementById('menu'); //document
drinking('#menu').hide(); //jQuery
var foo;
console.log(foo === coffee); //undefined
})(window, document, jQuery);

 

 

 

Although, for obvious reasons, I advise against this ;)

The benefits of this design pattern will become even more apparent in later posts. Harnessing the power of self-executing anonymous functions will allow you to create more complex but ultimately more intuitive code structures that will make your larger projects much easier to manage.

'프론트앤드 > JavaScript' 카테고리의 다른 글

자바스크립트 함수  (0) 2016.02.21

Enum 분석

Programing/Java 2016. 4. 11. 01:09 by kira-master

1.       Enum 이란 

 

 

 

 

2.       Enum 코드

public enum Operation {


   
PLUS("+") {
       
@Override
       
double apply(double x, double y) {
           
return x-y;
       
}

    }
, MINUS("-") {
       
@Override
       
double apply(double x, double y) {
           
return x-y;
       
}

    }
, TIMES("*") {
       
@Override
       
double apply(double x, double y) {
           
return x*y;
       
}

    }
, DIVIDE("/") {
       
@Override
       
double apply(double x, double y) {
           
return x/y;
       
}

    }
;

    private final
String symbol;

   
Operation(String symbol) {
       
this.symbol = symbol;
   
}

   
abstract double apply(double x, double y);

}

 

3.       Enum 바이트 코드 분석

 

 

Enum 클래스를 생성하게 되면 bytecode 시점에서는

enum 추상 클래스로 생성되면서 Enum 클래스의 상속을 받는다.

Enum 자료형은 모두 public static final enum Enum자료명으로 된다.

Static enum 형태로 내부 클래스로 선언된 되는데 밑에 보면 PlUS , MINUS, TIMES, DIVICE 라고 선언한


// class version 52.0 (52)
// access flags 0x4421
// signature Ljava/lang/Enum<Lcom/study/enum01/Operation;>;
// declaration: com/study/enum01/Operation extends java.lang.Enum<com.study.enum01.Operation>
public abstract enum com/study/enum01/Operation extends java/lang/Enum  {

// compiled from: Operation.java
// access flags 0x4008
static enum INNERCLASS com/study/enum01/Operation$4 null null
// access flags 0x4008
static enum INNERCLASS com/study/enum01/Operation$3 null null
// access flags 0x4008
static enum INNERCLASS com/study/enum01/Operation$2 null null
// access flags 0x4008
static enum INNERCLASS com/study/enum01/Operation$1 null null

// access flags 0x4019
public final static enum Lcom/study/enum01/Operation; PLUS

// access flags 0x4019
public final static enum Lcom/study/enum01/Operation; MINUS

// access flags 0x4019
public final static enum Lcom/study/enum01/Operation; TIMES

// access flags 0x4019
public final static enum Lcom/study/enum01/Operation; DIVIDE

// access flags 0x12
private final Ljava/lang/String; symbol

// access flags 0x101A
private final static synthetic [Lcom/study/enum01/Operation; $VALUES

// access flags 0x9
public static values()[Lcom/study/enum01/Operation;
       
L0
        LINENUMBER
6 L0
        GETSTATIC com/study/enum01/Operation.$VALUES : [Lcom/study/enum01/Operation
;
       
INVOKEVIRTUAL [Lcom/study/enum01/Operation;.clone ()Ljava/lang/Object;
       
CHECKCAST [Lcom/study/enum01/Operation;
       
ARETURN
        MAXSTACK =
1
       
MAXLOCALS = 0

// access flags 0x9
public static valueOf(Ljava/lang/String;)Lcom/study/enum01/Operation;
       
L0
        LINENUMBER
6 L0
        LDC Lcom/study/enum01/Operation
;.class
ALOAD 0
       
INVOKESTATIC java/lang/Enum.valueOf (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
       
CHECKCAST com/study/enum01/Operation
        ARETURN
        L1
        LOCALVARIABLE name Ljava/lang/String
; L0 L1 0
       
MAXSTACK = 2
       
MAXLOCALS = 1

// access flags 0x2
// signature (Ljava/lang/String;)V
// declaration: void <init>(java.lang.String)
private <init>(Ljava/lang/String;ILjava/lang/String;)V
        L0
        LINENUMBER
37 L0
        ALOAD
0
       
ALOAD 1
       
ILOAD 2
       
INVOKESPECIAL java/lang/Enum.<init> (Ljava/lang/String;I)V
        L1
        LINENUMBER
38 L1
        ALOAD
0
       
ALOAD 3
       
PUTFIELD com/study/enum01/Operation.symbol : Ljava/lang/String;
       
L2
        LINENUMBER
39 L2
        RETURN
        L3
        LOCALVARIABLE
this Lcom/study/enum01/Operation; L0 L3 0
       
LOCALVARIABLE symbol Ljava/lang/String; L0 L3 3
       
MAXSTACK = 3
       
MAXLOCALS = 4

// access flags 0x400
abstract apply(DD)D

       
// access flags 0x1000
       
synthetic <init>(Ljava/lang/String;ILjava/lang/String;Lcom/study/enum01/Operation$1;)V
        L0
        LINENUMBER
6 L0
        ALOAD
0
       
ALOAD 1
       
ILOAD 2
       
ALOAD 3
       
INVOKESPECIAL com/study/enum01/Operation.<init> (Ljava/lang/String;ILjava/lang/String;)V
        RETURN
        L1
        LOCALVARIABLE
this Lcom/study/enum01/Operation; L0 L1 0
       
LOCALVARIABLE x0 Ljava/lang/String; L0 L1 1
       
LOCALVARIABLE x1 I L0 L1 2
       
LOCALVARIABLE x2 Ljava/lang/String; L0 L1 3
       
LOCALVARIABLE x3 Lcom/study/enum01/Operation$1; L0 L1 4
       
MAXSTACK = 4
       
MAXLOCALS = 5

// access flags 0x8
static <clinit>()V
        L0
        LINENUMBER
9 L0
        NEW com/study/enum01/Operation$1
        DUP
        LDC
"PLUS"
       
ICONST_0
        LDC
"+"
       
INVOKESPECIAL com/study/enum01/Operation$1.<init> (Ljava/lang/String;ILjava/lang/String;)V
        PUTSTATIC com/study/enum01/Operation.PLUS : Lcom/study/enum01/Operation
;
       
L1
        LINENUMBER
15 L1
        NEW com/study/enum01/Operation$2
        DUP
        LDC
"MINUS"
       
ICONST_1
        LDC
"-"
       
INVOKESPECIAL com/study/enum01/Operation$2.<init> (Ljava/lang/String;ILjava/lang/String;)V
        PUTSTATIC com/study/enum01/Operation.MINUS : Lcom/study/enum01/Operation
;
       
L2
        LINENUMBER
21 L2
        NEW com/study/enum01/Operation$3
        DUP
        LDC
"TIMES"
       
ICONST_2
        LDC
"*"
       
INVOKESPECIAL com/study/enum01/Operation$3.<init> (Ljava/lang/String;ILjava/lang/String;)V
        PUTSTATIC com/study/enum01/Operation.TIMES : Lcom/study/enum01/Operation
;
       
L3
        LINENUMBER
27 L3
        NEW com/study/enum01/Operation$4
        DUP
        LDC
"DIVIDE"
       
ICONST_3
        LDC
"/"
       
INVOKESPECIAL com/study/enum01/Operation$4.<init> (Ljava/lang/String;ILjava/lang/String;)V
        PUTSTATIC com/study/enum01/Operation.DIVIDE : Lcom/study/enum01/Operation
;
       
L4
        LINENUMBER
6 L4
        ICONST_4
        ANEWARRAY com/study/enum01/Operation
        DUP
        ICONST_0
        GETSTATIC com/study/enum01/Operation.PLUS : Lcom/study/enum01/Operation
;
       
AASTORE
        DUP
        ICONST_1
        GETSTATIC com/study/enum01/Operation.MINUS : Lcom/study/enum01/Operation
;
       
AASTORE
        DUP
        ICONST_2
        GETSTATIC com/study/enum01/Operation.TIMES : Lcom/study/enum01/Operation
;
       
AASTORE
        DUP
        ICONST_3
        GETSTATIC com/study/enum01/Operation.DIVIDE : Lcom/study/enum01/Operation
;
       
AASTORE
        PUTSTATIC com/study/enum01/Operation.$VALUES : [Lcom/study/enum01/Operation
;
       
RETURN
        MAXSTACK =
5
       
MAXLOCALS = 0
       
}

 

 

 

 

'Programing > Java' 카테고리의 다른 글

자바 8 로 오면서 Runnable API 보던중에  (0) 2016.01.23
Connection 객체 // Properties  (0) 2015.09.09
계산기 예제  (0) 2015.08.27
POJO 의 개념과 예시  (0) 2015.08.24
Singleton 정리  (0) 2015.08.23

자바스크립트 함수

프론트앤드/JavaScript 2016. 2. 21. 17:58 by kira-master

1. 자바 스크립트 함수

    1.1 자바스크립트 함수

        - function 이란 first-class object 이다.

        - first-class object 란?

first-class object는 변수에 저장할 수 있어야 합니다.

first-class object는 함수의 파라미터로 전달할 수 있어야 합니다.

first-class object는 함수의 반환값으로 사용할 수 있어야 합니다.

first-class object는 자료 구조에 저장할 수 있어야 합니다.

        

    

2. 함수의 선언과 표현식

2.1 Function Declaration

         - 함수 선언은 실행 가능한 코드 블록이 아니라 함수의 정의 하는 문장이다.

        - 함수 선언 코드 자체는 실행되지 않는다.

    2.2 Function Expression

- function Expression 은 함수 리터럴로 실행 가능한 코드로 해석되어 변수에 할당되어 있음을 의미한다.

        - 또는 ( )를 사용하여 함수를 감싸준다. 이를 Self invoking Function이라고 한다.

        - Self invoking Function은 해석과 동시에 실행되는 코드 블럭을 말한다.

3. 예제

    3.1

    Colored By Color Scripter

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

foo(); // success !

//Function Declarations

function foo() {

    alert('foo');

}

foo(); // foo is not defined.

// Function Expressions ,  anonymous function expression

var foo = function (){

    alert('foo');

};

//named function expression

var foo = function foo() {

    alert('hello');

};

// 자기호출함수는 해석과 동시에 실행되는 코드블럭을 말한다.

// self invoking function expression

(function foo() {

   console.log('hello');

})();

 

    3.2

Nav