Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

this 바인딩 #7

Open
BKJang opened this issue May 23, 2019 · 1 comment
Open

this 바인딩 #7

BKJang opened this issue May 23, 2019 · 1 comment
Labels
Basic of JS It is related to basic concept of JS.

Comments

@BKJang
Copy link
Owner

BKJang commented May 23, 2019

🙏 Reference

@BKJang BKJang added the Basic of JS It is related to basic concept of JS. label May 23, 2019
@BKJang
Copy link
Owner Author

BKJang commented May 23, 2019

JavaScript의 this

자바스크립트에서 this의 바인딩은 함수의 호출 방식에 따라 결정된다.

  • 객체의 메서드 호출
  • 일반 함수 호출
  • 생성자 함수의 호출
  • callapply를 이용한 this 바인딩
  • ES6의 화살표 함수

객체의 메서드 호출

var obj = {
    organization : 'Im-D',
    sayHello : function() {
        return 'Welcome to ' + this.organization;
    }
}

console.log(obj.sayHello());

객체의 메서드를 호출할 때 this해당 객체에 바인딩된다.

일반 함수 호출

var organization = 'Im-D';

function sayHello() {
    var organization = 'Kyonggi';
    return 'Welcome to ' + this.organization
}

console.log(sayHello());

일반 함수를 호출할 때, 자바스크립트의 this전역 객체(window 객체)에 바인딩 된다.

생성자 함수의 호출

function Organization(name, country) {
    this.name = name;
    this.country = country;
}

var imD = new Organization('Im-D', 'South Korea');
var kyonggi = Organization('Kyonggi', 'South Korea');

console.log(imD);

console.log(kyonggi);

생성자 함수를 new키워드를 통해 호출할 경우, 새로 생성되는 빈 객체에 바인딩 된다. 단, new키워드를 사용하지 않으면 this는 전역객체에 바인딩된다.

call, apply, bind를 활용한 this바인딩

call

function Module(name) {
    this.name = name;
}

Module.prototype.getName = function() {
  const changeName = function() {
    console.log(this);
    return this.name + '입니다.';
  }
  // return changeName.call(this, 1,2,3,4);
  return changeName.call(this);
}

const module = new Module('BKJang');

console.log(module.getName());

apply

function Module(name) {
    this.name = name;
}

Module.prototype.getName = function() {
  const changeName = function() {
    console.log(this);
    return this.name + '입니다.';
  }
  
    // return changeName.apply(this, [1,2,3,4]);
    return changeName.apply(this);
}

const module = new Module('BKJang');

console.log(module.getName());

또한 call이나 apply메서드를 활용하여 유사배열 객체를 일반 배열로 바꿀 수도 있다.

function sayHello() {
    console.log(arguments);
    var args = Array.prototype.slice.apply(arguments);
    console.log(args);
}    

sayHello('Im-D', 'South Korea');

callapply는 내부 함수에서 사용할 this를 설정하고 함수 바로 실행까지 해주지만, bindthis만 설정해주고 함수 실행은 하지 않고 함수를 반환한다.

function Module(name) {
    this.name = name;
}

Module.prototype.getName = function() {
  const changeName = function() {
    console.log(this);
    return this.name + '입니다.';
  }
  let bindChangeName = changeName.bind(this);
    return bindChangeName();
}

const module = new Module('BKJang');

console.log(module.getName());

화살표 함수

var obj = {
    organization : 'Im-D',
    outerFunc : function() {
        var that = this;
        console.log(this.organization);

        innerFunc = function() {
            console.log(that.organization);
            console.log(this.organization);
        }

        innerFunc();
    }
}

obj.outerFunc();
var obj = {
    organization : 'Im-D',
    outerFunc : function() {
        console.log(this.organization);

        innerFunc = () => {
            console.log(this.organization);
        }

        innerFunc();
    }
}

obj.outerFunc();

ES5에서는 원래 내부 함수에서의 thiswindow객체에 바인딩 되었기 때문에 var that=this;와 같이 선언하여 thatthis를 할당하고 내부 함수에서는 that을 활용하는 방식을 사용했었다.

하지만, ES6에서 등장한 화살표 함수에서는 this가 무조건 상위 스코프의 this를 가리킨다.
이에 따라 내부함수에서 var that=this;와 같은 구문을 사용할 필요가 없다.
이처럼 정적으로 this가 바인딩되기 때문에 Lexical this라고 한다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Basic of JS It is related to basic concept of JS.
Projects
None yet
Development

No branches or pull requests

1 participant