AngularJS에서의 핵심 개념인 $scope란 양방향 데이터 바인딩의 핵심이자, 뷰와 컨트롤러를 연결하는 개념이다. 

$scope 는 HTML과 Javascript 를 연결해주는 구조로, 이는 단순한 Javascript 객체에 불과하지만, AngularJS 엔진에 의해 이 객체는 연결된 DOM 요소에서 Data와 Function이 사용되는 공간이라고 할 수 있다.

$scope 는 Javascript Object 이며 view 와 controller 사이를 연결할 수 있도록 몇가지 attribute 들을 포함하고 있다.


모든 AngularJS 로 제작된 Application 은 $rootScope 를 갖고 있으며 이는 ng-app 태그가 포함된 HTML 문서 최상단에 위치하는 $scope 가 된다.

따라서 다른 모든 $scope 들은 글로벌하게 정의되는 $rootScope를 상속하는 계층적인 구조를 이루고 있다. 즉, $rootScope 는 많은 child scope 들을 갖고 있다.

$rootScope 만이 AngularJS App 전체에서 유일한 Global Scope 로 처리가 되기 때문에 다른 AngularJS 의 Feature 들, 가령 Service 나 Factory 등이 $rootScope 를 이용하는 경우가 종종 있다.




위의 그림과 같이 하나의 HTML 에서 여러개의 ng-controller 를 정의할 경우 계층적으로 $scope 를 갖게 되고 이는 자연스럽게 계층 구조를 갖게 된다.


$scope는 뷰와 컨트롤러를 이어주는 다리이면서 연결된 DOM에서 양방향 데이터 바인딩을 처리해준다. 또한 이벤트를 처리할 수도 있다.

이 때, AngularJS 의 각 Controller는 하나의 컨트롤러에 하나의 $scope만을 갖게 된다.

그렇기 때문에 만약 독립된 $scope간 참조가 필요하다면 컨트롤러 간 데이터를 공유해야할 경우에는 Service를 이용한다.


AngularJS 의 실 구현은 대부분 ng-controller 로 명시되는 Controller 에서 수행되는 경우가 많기 때문에, 현재 다루고 있는 $scope 를 이해하고 있는건 매우 중요하다.


다음은 Scope 의 라이프사이클을 설명한다.


$scope 의 LifeCycle


1. 브라우저가 Javascript 를 로딩할 때, AngularJS 의 $injector 를 통해 정의된 Application(ng-app) 에 scope 를 할당한다.


2. 링킹 과정에서 $scope 하위에 $watch 오브젝트들이 등록된다.


3. 연결된 model 의 변화가 감지되면 $scope.$apply() 메서드가 AngularJS 내부에서 호출된다. 작업은 $http, $timeout, $interval 모듈을 이용해서 비동기적으로 이루어진다.


4. 변화가 감지되면 AngularJs 는 $digest cycle 을 rootScope 에서 수행한다. 변경 내용은 모든 child Scope 로 전파되며 당연히 각 $scope 에 정의된 $watch 가 이벤트를 전달받는다.


5. $scope 혹은 child Scope 가 더이상 필요가 없어지면 scope.$destroy 가 이루어지며 root Scope 에 의한 전파가 중단된다. 중단된 $scope 는 향후 가비지 컬렉팅된다.



참조 : https://docs.angularjs.org/guide/scope




최근에 AngularJS 를 이용해서 작업을 하던 도중 알게된 작은 버그이다.

(참고로 버전은 AngularJS 1 버전이고, 크롬에서 발생한 버그이다.)


문제가 된 HTML 은 다음과 같다.



<button class="button btn-danger" ng-click="deleteElement($index)">
<span class="glyphicon glyphicon-remove" aria-hidden="true">Delete</span></button>


위의 코드는 단순히 버튼을 클릭하면 해당 Element 에 대한 정보를 이용해서 ng-click 이벤트를 발생시키는 HTML 코드이다.


이 코드는 아주 잘 작동하지만, HTML 에서 엔터키 입력 시, 아주 사소한 버그를 발견할 수 있었다.


위의 코드에서 같은 scope 로 묶인 Text Box 에서 엔터를 입력하자마자 맨 위 레코드가 삭제되는 버그를 발견하였다.


정확히는 Enter Key 를 입력받아 ng-click 이벤트가 작동한 것이다. 다만, 명시적으로 ng-click 이 호출되지 않은 탓에 Parameter인 $index 는 전달되지 않은듯 하다.


문제의 원인은 <button> 태그에 있었는데, 기본적으로 button 태그의 type 은 "submit" 형이기 때문에, 엔터키 입력에 반응할 수 있다.

(이는 브라우저 별로도 다소 다른 듯 하다.)


문제 해결을 위해서는 다음과 같이 명시적으로 타입을 지정해주면 간단히 해결된다.



<button type="button" class="button btn-danger" ng-click="deleteElement($index)">
<span class="glyphicon glyphicon-remove" aria-hidden="true">Delete</span></button>


혹은 어느정도 규모의 AngularJS 프로젝트를 운용중이라면 directive 로 묶어서 처리하는 것도 좋은 방법이다.



(참고자료 : http://www.jomendez.com/2015/02/16/prevent-ng-click-action-hitting-enter/)


자바의 클래스로더는 자바의  Class  들을 런타임에 JVM으로 로딩하는 역할을 한다.
클래스로더는 JRE(Java Runtime Environment)의 한 부분이다.


JVM은 클래스로더 덕분에 파일의 구조나 파일 시스템을 고려하지 않을 수 있으면서 자바 프로그램을 작동시킬 수 있다.

이는 C/C++언어의 결과처럼 자바 프로그램이 하나의 Single Executable 파일을 생성하는 것이 아니라 여러 개의 자바 클래스들이 JAR의 형태로 묶여서 관리되다가 JVM에 의해 메모리에 올라가서 바이너리 형태로 동작하기 때문에 생기는 차이점이라 할 수 있다.

자바 클래스들은 한번에 모든 클래스가 메모리에 올라가지 않는다. 각 클래스들은 필요할 때 어플리케이션에 올라가게 되며, 이 작업을 클래스로더가 해주게 된다.

 

Class Loader 는 다음과 같은 역할을 해준다. 


 - Loading : 클래스 파일에서 클래스 이름, 상속관계, 클래스의 타입(class, interface, enum) 정보, 메소드 & 생성자 & 멤버변수 정보, 상수 등에 대한 정보를 로딩해서 Binary 데이터로 변경한다.


 - Linking : Verification 과 Preparation, Resolution 단계를 거치면서 바이트코드를 검증하고 필요한 만큼의 메모리를 할당한다. Resolution 과정에서는 Symbolic Reference 를 Direct Reference 등으로 바꿔준다.


 - Initialization : static block 의 초기화 및 static 데이터들을 할당한다. Top->Bottom 방식으로 클래스들을 해석한다.


(자세한 기능 동작은 다음을 참조

https://jins-dev.tistory.com/entry/JVMJava-Virtual-Machine-%EC%9D%B4-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91%ED%95%98%EB%8A%94-%EC%A7%80-How-JVM-Works)


자바의 클래스로더는 3가지의 서로다른 클래스로더로 구성되어 있다.

 

 (1) Bootstrap Class Loader
가령 java.lang 이나 ArrayList 같이 java.lang.ClassLoader 가 로드할 수 없는 bootstrap 또는 primordial 클래스들에 대해서는 JRE의 Bootstrap ClassLoader 가 이 역할을 해준다.
Bootstrap ClassLoader 는 native 언어로 만들어진 JVM 코어의 일부분으로, 일반 클래스 로더가 불러올 수 없는 클래스 들의 로딩을 담당해준다.

 

 (2) Extension Class Loader
Extension Class Loader는 bootstrap Class loader 의 자식클래스로 일반적인 Core Java Class 들의 로딩을 담당한다.

 

 (3) System Class Loader
System Class Loader는 시스템 환경변수 또는 클래스 변수 등과 같은 환경에 종속된 클래스들에 대한 로딩을 담당한다.


클래스로더는 런타임에 모든 클래스들에 대한 정의를 로딩한다. 이때 만약 클래스 매핑에 실패한다면, NoClassDefFoundError 를 만나보게 된다.

 

Java 의 클래스로더는 3가지 원칙을 지키며 동작한다.

 

1. Delegation :  Java의 클래스는 필요할 때 로딩되어야 한다는 원칙이다.

 

2. Visibility : Child 클래스는 Parent 클래스로더에 의해 로딩된 클래스들을 확인할 수 있지만, 그 역은 불가능하다는 원칙이다.

 

3. Uniqueness : 한번 클래스로더에 의해 로딩된 클래스는 재로딩되지 않는다. 가령, Parent 클래스로더에 의해 이미 로딩된 클래스는 Child 클래스로더가 다시 로드하지 못한다.

 

Java의 ClassLoader 클래스를 상속하면, 사용자정의 클래스로더를 구현할 수도 있으며, 언제든 findClass() 와 loadClass() 메서드를 이용해 동적으로 로딩이 가능하다.





 Web Storage 는 HTML5 에서 새로 생겨난 신기술로, Cookie 를 대체할 목적으로 만들어진 Browser Storage 이다.


HTML5 이전에 Application data는 쿠키에 저장되었고 모든 Server 에 대한 Request 에 첨부되었다.

이에 반에 Web Storage 는 보다 안전하고 많은 데이터를 저장할 수 있으면서 웹 사이트 퍼포먼스 저하에 영향을 미치지 않는다.


4kb 까지 저장할 수 있는 쿠키와 다르게 5mb 까지 저장할 수 있으며 저장된 정보는 매요청마다 서버로 전달되지 않는다. 


또한 암호화가 가능하며, 쿠키에 비해 접근 및 내용확인이 어렵다.(보안 상 안전하다.)


실제로 오래 유지될 필요가 있을지는 의문이지만... 만료일자가 지정되어있는 쿠키와 다르게 반영구적 보존이 가능하다는 점도 장점이다.



HTML5 Web Storage 는 Local Storage & Session Storage 로 나뉘며 간단한 Key : Value 를 저장할 수 있는 점은 같다.


 - Local Storage : 로컬에 Origin 별로 지속되는 스토리지. Domain 마다 별도로 Local Storage 가 생성된다. Javascript 에서 Window 전역 객체의 localStorage 컬렉션으로 접근이 가능하다.


 - Session Storage : 현재 세션 동안만 유지되는 스토리지. Window 전역 객체의 sessionStorage 컬렉션을 통해 접근이 가능하다. Browser Context 내에서만 데이터가 유지되므로 브라우저 종료 시 데이터도 삭제된다.



HTML5 의 Web Storage 는 기존의 쿠키를 대체할 목적이 아닌 언어 레벨에서 제공해주는 훌륭한 Browser Storage 옵션에 가깝다. 

실제로 쿠키처럼 매 요청시 서버로 전송되지 않기 때문에 필요한 요청에 대해 명시적으로 Request 를 날려야할 필요가 있다.





DOM은 W3C 표준으로 정의되어있는 문서의 항목을 객체화하기 위한 방법으로, 다음과 같은 3가지 파트로 나뉘어 있다.


 - Core DOM : 대부분의 Document Type 에서의 Object 형태를 말한다.

 - XML DOM : XML 문서 타입에서의 객체형태를 말한다.

 - HTML DOM : 포스팅에서 다루고자 하는 내용이며, HTML 문서 내에서 객체들이 해석되기 위한 형태를 말한다.


즉, HTML 에서 DOM이라함은 W3C의 HTML DOM 표준을 말하는 것이다.


DOM 오브젝트란 Document Object Model 의 약어로 웹브라우저가 HTML 을 해석하는 방식이자, Document 및 내부 구성요소를 객체화한 형태의 집합이라 할 수 있다.


HTML 의 각 요소들은 HTML Tag 및 텍스트들로 구성되어 있고, 이 각각의 항목을 노드(Node) 라 하고, 각각의 항목들은 Tree 의 계층형 구조를 이루고 있다.


HTML DOM 은 프로그래밍적 인터페이스를 허용하게 되어있으며 그에 따라 인터프리터가 Object 형태로 관리하게 되어있다.

각 Element 들은 Property 나 methods, events 를 가질 수 있게 설계되어 있다.


HTML DOM 은 HTML 의 Element 들을 나타내는 방식이자 Web 에서 문서가 동작하기 위한 표준으로 이해하면 된다.


<참고 : https://www.w3schools.com/js/js_htmldom.asp>




Python 은 명시적인 Call by Reference 혹은 Call by Value 라는 개념이 존재하지 않는다.


Python의 function에 argument 를 전달할 때, 이는 Manual 에 따르면 call by assignment 라는 방식으로 전달된다. 


이는 Parameter로 전달받는 객체에 따라 객체의 참조방식이 결정된다는 의미로, 공식 문서에 따르면 Mutable Object 는 Call by reference의 형태로 참조형으로 변수를 다루며 Immutable Object는 Call by value 의 형태로 변수를 핸들링한다.


- Mutable Object : list, dict, set 등의 객체


- Immutable Object : str, int, tuple 등의 객체


가령 다음과 같은 코드는 전달되는 객체에 따라 파이썬이 변수를 어떻게 핸들링하는 지를 간단하게 보여준다.




출력 결과는 다음과 같다. 

foo 함수의 경우 int 형을 핸들링하기 때문에 call by value 로 새로 변수를 할당해서 처리하는 모습을 보여주고 list 를 입력받은 foo2 함수의 경우 call by reference 로 전달 받은 객체를 직접 변경하는 모습을 볼 수 있다.




'Programming Language > Python' 카테고리의 다른 글

Python 의 Package 와 __all__ 키워드  (0) 2018.09.25
Python 2 버전과 3 버전의 차이  (0) 2018.08.04


먼저 <div> 태그와 <span> 태그의 차이점을 알아보자.


사용하는데 있어서 차이를 알아내긴 어렵지만 이는 생각보다 간단한데 단순히 div 는 block element 이고, span 은 inline element 라는 점이다.


좀더 설명하자면, div는 Document 의 부분들을 감쌀 수 있도록 설계되어 있지만, span 은 small portion(text, image 등)에 해당하는 작은 부분만 감싸게끔 설계되어 있다.


여기서 Block Level Element 와 Inline Level Element 라는 다소 생소한 분류가 등장한다.


* Block Level Element 와 Inline Level Element 의 차이점


 : Block Level Element 들은 <body> 요소 안에서만 표현되도록 정의되어 있다. 또한 Block Level element 들은 

 감싸고 있는 표현 전후를 분리시켜주는(개행) 특징을 가진다. 즉, 이 영역은 앞 뒤 영역과 구분된 독자적인 영역이 된다.

 또한 Block Level Element 들은 Inline Level Element 들을 포함할 수 있다.


 : Inline Element 는 Tag 가 시작된 라인에서 바로 시작하며 이전과 이후를 구분(개행)하지 않는다. HTML5 이전의 일반적인 Inline Element 는 Block Element 를 포함하지 못한다.



 HTML5가 되면서, 몇몇 Block Element 들이 Inline Element 안에 포함이 가능하게 되면서, 차이점이 조금 불분명해졌다.


그럼에도 Span 은 Phrasing content 만을 안에 포함시킬 수 있고, div 는 flow content 를 포함시킬 수 있다는 차이점이 있다.

여기서 flow content 와 phrasing content 는 부가적인 분류 카테고리이다. 

flow content 는 마크업으로써 표현되는 컨텐츠 자체를 의미하며, phrasing content 는 해당 요소가 강조 하거나 꾸며주는 역할을 하는 도구로써의 Element 일 경우를 말한다.


HTML이 모던해짐에 따라 element 들은 복수의 역할을 수행할 수 있도록 진화하고 있으나, 그건 HTML 초기 디자인이 의도한 바가 아니다.

가령 <p> 태그는 paragraph 를 위해 만들어진 태그이며, <li> 는 list item 을 위해 만들어진 태그이다.

HTML 은 모던해짐과 동시에 혼용될 수 있는 역할에 따른 사용을 방지하기 위해 의미없는 차이임에도 태그를 나누는 경우들이 있다.





stdafx.h 란 자주 쓰이는 헤더들 여러 개를 한꺼번에 미리 컴파일 해놓아서 나중에 다시 컴파일하지 않고 그냥 다시 쓰겠다는 헤더이다

이렇게 미리 컴파일된(Precompiled) 파일이 .pch 파일이다

프로젝트의 크기가 커지고 헤더들의 크기가 커지거나 숫자가 많아지면 유용하게 써야할 필요가 있다


프로젝트 속성에서 Precompiled Header의 사용을 Enable 하게 해줘야한다

보통 Wizard로 프로젝트를 생성하는 경우 기본으로 stdafx.hInclude 되어 있는데, 여기서 stdio.hInclude 하면 중복이 되거나 헤더가 엉키는 현상이 발생해서 Unexpected File End 가 발생하게 된다


stdafx.h 를 사용할 때는 모든 cpp 파일이 이를 Include 해야 하며 가능한 깔끔하게 구조를 잡고 가는게 좋다.



'Programming Language > C&C++' 카테고리의 다른 글

[Old] C++Type Casting 정리  (0) 2018.09.25
RAII 의 개념 정리  (0) 2018.08.08


주의) 오래전 Effective C++을 바탕으로 보관한 자료이기 때문에 최신 C++ Trend 가 전혀 반영되어있지 않은 포스팅입니다.


 C++C에서의 Type Casting 보다 확장되고 안정성 있는 Type casting 기법 4가지를 제공한다.


(1) static_cast

 : 크게 implicit castexplicit cast로 나뉜다.



Expressionstatic_cast<type>(expression)으로 표현된다.

 

(2) dynamic_cast

 : 상속 관계를 가로지르거나 하향시킨 클래스(파생 클래스) 타입으로 캐스팅할 때 사용된다. 상속 계층 간에만 사용해야하며 가상 함수가 없는 타입에 적용시킬 수 없고 상수성 제거에도 적용할 수 없다.

dynamic_cast<type>(expression)


-> 일반적으로 사용하는 캐스트는 static_cast이다. 하지만 다형성을 이용하려는 경우에는 얘기가 다르다. 런타임에 다형성을 이용한 모호한 캐스팅이 이루어질 경우 static_cast는 문제가 됨에 반해, dynamic_cast는 실제 Instance를 조사하기 때문에 런타임 오류가 발생하지 않는다. 예를 들어 BC의 부모 클래스일때,



일 때는 다형성의 정의에 의하여 BC의 포인터를 가리킬 수 있으므로 문제가 안되지만,



의 경우에는 BC의 타입으로 변환될 경우에 문제가 생기게 된다

그런데 static_cast로는 타입체크를 하지 않기 때문에 변환되서 문제가 되는 값이 넘어가게 된다. 반면에 dynamic_cast로 변환시에는 NULL값으로 변환된다.

 

(3) reinterpret_cast

 : 연관성이 없는 포인터 타입을 변환하기 위해서 사용된다. 예를 들어


이 경우 위와 같이 static_cast로 변환을 시도하는 경우, 문법적으로 불가능하지만, reinterpret_cast를 이용하면 연관성 없는 두 포인터간 캐스팅이 가능하다

하지만 논리적으로 불안정하며 포인터에 대한 캐스팅만 수행이 가능하고 const 타입에 대한 캐스팅이 안된다.

 

(4) const_cast

 : 포인터 타입과 참조형에 대해서만 사용되는 캐스팅이며 동일 타입 내에서만 사용이 가능하다

그 외에는 is a 관계를 포함한 어떤 관계를 맺고 있더라도 불가능하다. 일반적으로 상수목적으로 지정된 객체 등에 대해서 변수목적으로 사용하고자 할 때 이용한다

또한 volitile 타입 한정자를 지닌 volatile 타입 객체를 참조형으로 변환하고자 할 때도 사용된다. Effective C++에서 이에 대해서 많이 다루고 있으니 참조하자.

 

'Programming Language > C&C++' 카테고리의 다른 글

Stdafx.h 란?  (0) 2018.09.25
RAII 의 개념 정리  (0) 2018.08.08


파이썬은 모듈 혹은 모듈의 집합을 패키지 단위로 묶어서 관리할 수 있고 이는 소스 트리를 구축하는데 있어서 매우 유용한 기법이다

패키지는 도트(.)를 이용해서 파이썬 모듈을 계층적으로 관리할 수 있게 해준다


2.x 버전 및 그 하위의 레벨에서는 반드시 패키지 폴더 내부에 __init__.py 라는 파일이 존재하게 되는데, 이 파일은 해당 디렉토리가 패키지의 일부임을 알려주는 역할을 한다

만약 패키지에 포함된 디렉토리 중 __init__.py 파일이 없다면 패키지로 인식되지 않는다

3.x 이후의 버전에서는 __init__.py 가 없더라도 패키지로 인식이 가능하게 변경되었으나, 하위 버전 호환을 위해서 __init__.py 파일을 생성하는 것이 안전한 방법이다


__init__.py를 이용할 경우 해당 파일 내에 __all__ 변수를 설정해서 외부에서 import 가능한 모듈을 정의해주어야 한다.

그렇지 않으면 하위 버전에서는 import *를 하게 되더라도 해당 모듈을 사용하지 못하게 될 수도 있다

(하지만 from 의 마지막 항목이 모듈인 상태로 import *를 하게 되면 이에 상관없이 전부 사용이 가능하다. 여기서 안 된다고 하는건 패키지를 대상으로 import *를 하게 되는 경우를 말한다.) 


__all__ 변수는 다음과 같이 모듈의 이름을 담는 리스트로 구성되며 as를 이용해서 다른 변수명으로 치환해서 사용되곤 한다.

__all__ = [‘moduleA’, ‘moduleB’] as moduleAll



'Programming Language > Python' 카테고리의 다른 글

Python 의 Call by assignment 의 개념  (0) 2018.10.07
Python 2 버전과 3 버전의 차이  (0) 2018.08.04

+ Recent posts