ES6 노트(5) - Object

69000 단어 ES6es6/es7object
디렉토리:
  • 추가된 대상 글씨체 문법
  • 멤버 스케치
  • 메소드 스케치
  • 계산 속성명
  • 새로운 Object 방법
  • Object.is
  • Object.assign
  • Object.setPrototypeOf
  • Object.keys, Object.values, Object.entries

  • Class
  • 【확장】대상방향 소개
  • class(클래스)로 대상 지원 향상
  • 류의 기타 쓰기 방식
  • 류의 계승

  • 새로 추가된 객체 글꼴 구문


    멤버 스케치


    ES5의 쓰기 대상 구성원에 대한 질문


    우리는 개발 과정에서 항상 이러한 논리를 만날 수 있다. 사용자가 사용자 이름과 비밀번호를 입력했고 우리는 비밀번호를 받아서 백엔드에 제출했다
    //  ,  
    function loginHandler( username, pwd ) {
        ajax('/login', {
            username: username,
            pwd: pwd
        })
    }
    
    loginHandler( 'admin', 123 ); 
    

    보통 이렇게 쓰죠, 백엔드는 틀림없이 하나의 대상을 받아들일 거예요. 우리는 이상한 점을 발견할 거예요.
  • aax 요청에서username과pwd는 두 번 썼습니다. 첫 번째username과pwd는 키 이름이고 두 번째는value값이기 때문에 이 책은 고상하지 않지만 보기만 해도 이상합니다
  • ES6 솔루션


    ES6는 대상의 속성value가 하나의 변수에서 나오고 이 변수 이름이 대상의 속성 키 이름과 일치하면 구성원 스케치로 코드량을 줄일 수 있습니다
    function loginHandler( username, pwd ) {
        ajax('/login', {
            username, //  key value ,  value,  username: username
            pwd //  pwd: pwd
        })
    }
    
    loginHandler( 'admin', 123 ); 
    
    

    메소드 스케치


    과거에 나는 대상에서 글을 쓰는 방법을 썼다


    과거에 우리가 대상에서 쓴 방법은 다음과 같다
    const obj = {
        sayHello: function() {
            console.log('hello');
        }
    }
    

    ES6의 간결한 쓰기


    ES6에서는 객체의 글자 크기에 콜론과 function 키워드를 생략할 수 있도록 허용합니다.
    const obj = {
        sayHello() {
            console.log('hello');
        }
    }
    

    계산 속성 이름


    과거에 우리가 처리한 대상의 구성원 이름은 하나의 표현식에서 나온 상황은 다음과 같다

    const prop1 = 'name';
    
    const obj = {}; //  key ,  
    
    obj[prop1] = 'loki'; //  
    
    console.log(obj); // { name: 'loki' }
    

    이렇게 쓰는 것도 사실 아무런 문제가 없지만 논리적으로 말하자면 이것은 좀 부적당하다. 왜냐하면 속성 초기화는 내가 처음부터 할 수 있었지만 ES6 이전에는 할 수 없었기 때문이다.

    ES6 솔루션


    ES6에서는 중괄호만 붙이면 객체의 키 값을 표현식으로 직접 표시할 수 있습니다.
    const prop1 = 'name';
    const obj = {
        [prop1]: 'loki'
    }
    
    console.log(obj); // { name: 'loki' }
    

    새 Object 메서드


    Object.is


    두 데이터가 동일한지 아닌지를 판단하는 데 쓰인다

    과거에 우리는 두 그룹의 데이터가 같다는 상황을 판정했다


    ES6 이전에 우리는 일반적으로 ==일반적인 비교를 하고 ====로 엄격한 비교를 했지만 엄격한 비교를 할 때 문제가 있었다
    console.log( +0 === -0 ); // true
    console.log( NaN === NaN ); // false
    

    상기 두 가지는 모두 합리적이지 않다. +0과-0은 사실 하나는 플러스이고 하나는 마이너스이다. 비록 본질적으로 그들은 큰 의미가 없지만 엄격히 수학 논리에 따르면 이 두 값은 같지 않을 것이다. 두 번째는 더욱 터무니없다. 낸은 낸과 같지 않다. 이것은 완전히 말이 안 된다.

    ES6 솔루션


    그래서 ES6에서 나온 Object입니다.is는 우리가 이 문제를 잘 해결할 수 있도록 도와주었다
    // Object.is  ,   ===  , Object.is 
    console.log( Object.is( +0, -0 ) ); // false
    console.log( Object.is( NaN, NaN ) ); // true
    

    Object.assgin


    블렌드 객체

    과거에 우리는 혼합 대상이 필요한 상황에 부딪혔다

    //  ,  ES6 
    const obj1 = {
        name: 'loki',
        age: 18
    }
    const obj2 = {
        name: 'thor',
        age: 20
    }
    
    //  
    function assign( ...objs ) {
        let lastObj = {};
        objs.forEach( it => {
            for( let prop in it ) {
                lastObj[prop] = it[prop];
            }
        } )
        return lastObj;
    }
    
    const lastObj = assign( obj1, obj2 );
    console.log(lastObj);  //    {name: "thor", age: 18, sex: "male"}
    

    기본적으로 우리는 스스로 하나의 방법을 봉하여 합병을 진행하는데, 때로는 약간 번거로울 수도 있고, 심지어는 사실 우리가 쓴 방법이 매우 우호적이지 않을 수도 있다

    ES6 솔루션


    ES6를 공부한 후, 우리는 이전에 ES6가 확장 연산자를 사용하여 대상의 합병을 할 수 있다는 것을 알고 있었다.
    const obj1 = {
        name: 'loki',
        age: 18
    }
    const obj2 = {
        name: 'thor',
        age: 20
    }
    
    const lastObj = {...obj1, ...obj2}; //  
    
    console.log(lastObj);  //    {name: "thor", age: 18, sex: "male"}
    

    이 동시에 ES6는 새로운api, 즉 Object를 제공했다.assign, 합병 대상을 사용할 수 있습니다
    Object.assign은 매개 변수를 한정하지 않습니다. 그는 마지막 매개 변수부터 순서대로 이전의 매개 변수를 합쳐서 마지막에 첫 번째 매개 변수를 덮어씁니다(즉 첫 번째 매개 변수를 바꾸게 된다는 뜻). 그리고 첫 번째 매개 변수의 값을 되돌려줍니다. 말하자면 추상적일 수 있지만 당신을 보면 알 수 있습니다.
    const obj1 = {
        name: 'loki',
        age: 12
    }
    
    const obj2 = {
        name: 'thor',
        age: 16,
        sex: 'male'
    }
    
    const obj3 = {
        skill: 'eat'
    }
    
    const lastObj = Object.assign( obj1, obj2, obj3 );
    
    console.log(lastObj); // { name: 'thor', age: 16, sex: 'male', skill: 'eat' }
    console.log(lastObj === obj1); // true
    

    바로 당신이 전달한 첫 번째 파라미터는 최종적으로 덮어씌울 것이다. 첫 번째 파라미터는 target이고 당신이 최종적으로 잃어버릴 대상이라고 이해할 수 있다. 그리고 뒤에 남은 파라미터는origin이다. 복제할 원본 대상이다. 위와 같이 조작하면 첫 번째 대상의 값에 영향을 줄 수 있기 때문에 우리는 일반적으로 이렇게 조작한다.
    const obj1 = {
        name: 'loki',
        age: 12
    }
    
    const obj2 = {
        name: 'thor',
        age: 16,
        sex: 'male'
    }
    
    const obj3 = {
        skill: 'eat'
    }
    
    //  ,  ,  
    const lastObj = Object.assign( {}, obj1, obj2, obj3 );
    
    console.log(lastObj); // { name: 'thor', age: 16, sex: 'male', skill: 'eat' }
    console.log(lastObj === obj1); // false
    

    Object.setPrototypeOf


    과거에 우리는 대상의 원형을 설정하는 것에 관해

    // 1.  Object.create
    function Person() {}
    const obj = Object.create(Person.prototype);
    
    console.log(obj.__proto__ === Person.prototype); // true
    
    // 2.  __proto__
    const obj2 = {};
    obj2.__proto__ = Person.prototype;
    console.log(obj2);
    

    첫 번째 방안은 창설할 때만 설정할 수 있고 중간에 고치려고 하면 갈 수 없다. 한계가 있다. 두 번째 방안은 변경할 수 있지만 사람들이 라고 말한다.proto__스텔스 속성이야, 네가 굳이 다른 사람의 스텔스 속성을 잡고 고치지 않으면 이치에 맞지 않아. 게다가 일부 브라우저들은 너에게 이 속성을 고치지 않아.

    ES6 시나리오


    Es6는 setPrototypeOf를 출시하여 언제 어디서나 대상을 수정할 수 있는 원형을 만들어 주었다
    function Person() {}
    const obj = {}; 
    Object.setPrototypeOf(obj, Person.prototype);
    
    console.log(obj.__proto__ === Person.prototype); // true
    
    //  ?  ? Object.create 
    

    Object.keys, Object.values, Object.entries


    ES5 객체의 속성을 지정하는 방법

    const obj = {
        name: 'loki',
        age: 18
    }
    
    //  
    function getObjKeys( obj ) {
        if( !obj instanceof Object ) {
            return;
        }
    
        const keys = [];
    
        for( const prop in obj ) {
            keys.push( prop );
        }
    
        return keys;
    }
    
    const keys = getObjKeys( obj );
    console.log(keys); // ['name', 'age']
    

    이렇게 하면 약간 번거로울 수 있다. 그래서...

    ES6 솔루션

    const obj = {
        name: 'loki',
        age: 18
    }
    const keys = Object.keys( obj );
    
    console.log(keys); // ['name', 'age']
    
    

    사실 ES6에서는 Object만 제공하는 것이 아니다.keys, Object도 제공합니다.values 및 Object.entries, 각자 뭘 처리하는지 봅시다.
    // Object.keys key ,  Object.values value 
    
    const obj = {
        name: 'loki',
        age: 18
    }
    
    const values = Object.values( obj ); // [ 'loki', 18 ]
    
    // Object.entries 
    const entries = Object.entries( obj ) // [['name', 'loki'], ['age', 18]]
    

    Class


    【확장】대상방향 안내


    대상을 향한: 일종의 프로그래밍 사상으로 구체적인 언어와 무관하다
    과정에 대한 사고점은 기능 절차이다
    대상을 향한 사고점은 대상의 구분이다
    우리는 유명한 예[코끼리 냉장고]를 살펴보자. 대상을 향한 것과 과정을 향한 것이 각각 어떻게 처리되는지, 그 중에서 이 두 가지 프로그래밍 사고의 차이를 발견할 수 있을 것이다.
    //  
    
    // 1.  
    function openRefrigeratorDoor() {
        console.log(' ');
    }
    
    // 2.  
    function pushElephantIn() {
        console.log(' ');
    }
    
    // 3.  
    function closeRefrigeratorDoor() {
        console.log(' ')
    }
    
    //  
    function Elephant() {
    
    }
    
    
    Frigerator.prototype = {
        openDoor() {
            console.log(' ');
        },
    
        closeDoor() {
            console.log(' ');
        },
    
        push( target ) {
            console.log(` ${ target } `)}
    }
    function Frigerator() {
    
    }
    

    클래스로 대상 지원을 더 잘 하기


    과거에 우리가 구조 함수를 성명한 방식

    function Person( name, age ) {
        this.name = name;
        this.age = age;
    }
    
    Person.prototype.sayName = function() {
        console.log(this.name);
    }
    
    Person.printA = function() {
        console.log('a');
    }
    
    

    위에서 이렇게 구조 함수를 성명한 것은 사실 다음과 같은 몇 가지 폐단이 있다
  • 속성과 원형 방법의 정의를 분리하여 코드의 가독성을 낮추었다
  • 원형 구성원은 매거할 수 있다
  • 기본적으로 구조 함수는 일반 함수로 호출할 수 있음
  • ES6에서 구조 함수를 선언하는 방법

    class Person {
        //  static 
        static printA() {
            console.log('a');
        }
        //  constructor function Person() {},  
        constructor( name, age ) {
            this.name = name;
            this.age = age;
        }
    
        //  
        sayName() {
            console.log(this.name);
        }
        
        //  foo
        foo() {}
    }
    

    ES6는class클래스를 사용하여 구조 함수를 더욱 ok로 정의하고 기능을 더욱 집중시켰다고 생각한다
    클래스 선언의 특징:
  • 류의 성명은 승급되지 않으며let,const와 같이 일시적인 사구가 존재
  • 클래스의 모든 코드는 엄격한 모드에서 실행됩니다
  • 류의 모든 방법은 일일이 열거할 수 없다
  • 류의 모든 방법은 내부에서 구조 함수로 사용할 수 없다
  • 류의 구조기는 반드시 new 연산자를 사용하여 호출해야 한다
  • 기타 쓰기 방식


    계산 가능한 구성원 이름

    //  printName class 
    const printName = 'print';
    
    class Person {
        constructor( name ) {
            this.name = name; 
        }
    
        //  ES6 
        [ printName ]() {
            console.log(this.name);
        }
    }
    
    

    Getter 및 setter


    만약 우리가 대상의 특정한 속성의 읽기와 쓰기를 정의하고 싶다면, 과거에는 Object를 사용했다.defineProperty,class에서 ES6는 우리에게 더욱 편리한 Getter와setter를 제공합니다
    //  constructor getter setter,   200
    //  20 
    
    class Person {
        constructor( name, age ) {
            this.name = name;
            this.age = age;
        }
    
       get age() {
           console.log( 'hello' );
           return this._age;
       }
    
       set age( age ) {
           console.log('age ');
           if( age > 200 ) {
               age = 200;
           }
           this._age = age;
       }
    }
    
    const person = new Person( 'loki', 18 );
    person.age = 300;
    console.log(person.age); // 200
    

    정적 구성원


    ES5에서 저희가 정적 멤버를 쓰는 건 보통 이렇게 써요.
     .xxx = xxx;
    

    이렇게 하면 사실 클래스의 속성과 클래스 자체를 분리하여 읽기에 불리하기 때문에 ES6는 우리에게 새로운 쓰기 정적 구성원의 쓰기 방법을 내놓았다
    클라스 클래스에서 우리는 쓰기 원형 구성원은 클라스에서 직접 쓰면 된다는 것을 알고 있다. 그러면 쓰기 정적 구성원도 마찬가지다. 유일하게 그들을 구분하는 것은 정적 구성원이다. static 키워드를 붙여야 한다.
    class Person {
        constructor( name ) {
            this.name = name;
        }
    
        //  sayName
        sayName() {
            console.log(this.name);
        }
    
        //  static  
        static printMaxLife() {
            console.log( '200' );
        }
    }
    
    

    필드 초기화기


    필드 초기화기가 나오기 전에, 우리는class 클래스에 정적 속성을 추가하기 어려울 것입니다. 필드 초기화기는 우리가class 클래스에서 직접 부치호를 사용하여 정적 속성을 설명할 수 있도록 합니다
    class Person {
        constructor( name ) {
            this.name = name;
        }
    
        //  ,  
        static maxLifeTime = 200;
    
        static = () => {
            console.log(this);
        }
    }
    
    

    필드 초기화기가 온 후에 그는 우리도class에서 화살표 함수를 쓸 수 있도록 허락했다. 이전에는 안 되었다. 어떤 경우에는this문제를 해결하는 데 도움을 줄 수 있다. (만약react를 사용한 적이 있다면 내가 무슨 말을 하는지 알 수 있을 것이라고 믿는다.)
    참고 사항:
  • static 키워드를 사용하는 필드 초기화기, 정적 구성원 추가
  • static 키워드를 사용하지 않은 필드 초기화기, 추가된 구성원은 원형 구성원이 아니라 대상에게 직접 추가됩니다
  • class Person {
        constructor( name ) {
            this.name = name;
        }
        sayName = () => {
            console.log(this.name);
        }
    }
    
    const person1 = new Person( 'andy' );
    const person2 = new Person( 'peggy' );
    console.log(person1.sayName === person2.sayName); // false
    

    [확장] 데코레이터(장식기)


    예를 들어 우리는 하나의 수요가 있다. 우리가 클래스 안의 어떤 방법을 호출할 때 우리는 일지의 기록을 해야 한다. 이것은 이 방법이 호출되었다는 것을 의미한다. 많은 학우들이 이렇게 쓸 수 있다.
    class Person {
        constructor( name ) {
            this.name = name;
        }
    
        sayName() {
            console.log(' ');
            console.log(this.name);
        }
    }
    

    다음과 같은 몇 가지 질문이 적혀 있습니다.
  • sayName의 출력 방법이 호출된 줄에 어떤 방법이 호출되었는지 기록할 수 있습니까? ES5 비엄격한 모드에서callee를 사용할 수 있습니다. 엄격한 모드에서 방법이 있습니까?
  • 만약class에서 로그를 기록하는 여러 가지 방법이 있고 여러 종류에서도 같은 로그를 기록하는 기능이 있다면 당신은 그럴 수 있습니까?

  • 두 번째 점에 대해 많은 친구들이 바로 함수를 생각할 수 있다. 장식기의 본질에도 하나의 함수이다. 장식기를 사용하는 방법을 살펴보자.
    class Person {
        constructor( name ) {
            this.name = name;
        }
    
        @printLog //  @ 
        sayName() {
            console.log(this.name);
        }
    }
    
    
    // target =>  , methodsName =>  , descriptot =>  :  
    function printLog( target, methodsName, descriptor ) {
        console.log(`${target.name} ${methodsName} `);
    }
    
    

    클래스 상속


    만약 두 종류의 A와 B가 A가 B라고 묘사할 수 있다면 A와 B는 계승 관계를 형성한다(예를 들어 개는 동물이기 때문에 개와 동물은 계승 관계를 형성한다)

    ES6 이전 JS의 상속


    가장 완벽한 게 성배 모드예요.
    //  
    
    const inherit = (function () {
        function F() { }
        return function (target, origin) {
            F.prototype = origin.prototype;
            target.prototype = new F();
            target.prototype.constructor = target;
            target.prototype.super = origin;
        }
    }())
    
    
    Animal.prototype = {
        say() {
            console.log(' ');
        }
    }
    function Animal() {
    
    }
    
    function Dog() { }
    
    inherit(Dog, Animal);
    
    const dog = new Dog();
    
    dog.say(); //  
    console.log(dog.constructor, dog.super); //  function Dog() {} function Animal() {}
    

    ES6 처리 방법

  • Object.setPrototypeOf
  • //  Object.setPrototypeOf
    
    Animal.prototype = {
        say() {
            console.log(' ');
        }
    }
    function Animal() {}
    function Dog() {}
    
    Object.setPrototypeOf( Dog.prototype, Animal.prototype );
    
    const dog = new Dog();
    
    dog.say(); //  
    
  • Class의 extends
  • 위의 문법은 OK이지만 우리가 전에 말한 것처럼 클래스의 일부 조작은 클래스 자체와 분리되어 읽기가 쉽지 않다. 그래서 es6는 우리에게 extends 계승을 제공했다.
    class Animal {
        say() {
            console.log(' ');
        }
    }
    
    
    class Dog extends Animal {
        
    }
    
    
    const dog = new Dog();
    
    dog.say(); //  
    

    구조 함수를 빌려 쓰는 것에 관한 일들


    우리는 어떤 상황에서 부류를 계승해도 우리의 요구에 도달할 수 없다는 것을 알고 있다. 우리는 심지어 구조 함수에서this에서 만든 속성이 고도로 일치한다. 다음과 같다.
    function Animal( name, sex ) {
        this.name = name;
        this.sex = sex;
    }
    
    //  new  Animal,  Dog 
    
    function Dog( name, sex ) {
        //  this.name = name, this.sex = sex,  ,  ,  
        Animal.call( this, name, sex );
    }
    
    const dog = new Dog(' ', ' ');
    console.log(dog.name, dog.sex); //  ,  
    
    

    ES6에서는 Super 키워드를 사용하여 이 단계를 완료할 수 있습니다.
    class Animal {
        constructor( name, sex ) {
            this.name = name;
            this.sex = sex;
        }
    }
    
    class Dog extends Animal {
        constructor( name, sex ) {
            //  super Animal.call(this, name, sex) 
            super( name, sex );
            this.voice = ' '; //  
        }
    }
    
    const dog = new Dog(' ', ' ');
    console.log(dog.name, dog.sex); //  ,  
    

    주의:es6 요구 사항은 constructor를 정의하고 이 클래스가 하위 클래스라면, 이 클래스의 constructor 첫 줄에서 부모 클래스의 구조 함수를 수동으로 호출해야 합니다. (수동으로 슈퍼를 호출합니다.)
    super 키워드의 두 가지 용도:
  • 를 함수로 사용하고 부류를 대표하는 구조 함수
  • 대상으로 사용하면 부류의 원형
  • 을 나타낸다
    class Animal {
        constructor( name, sex ) {
            this.name = name;
            this.sex = sex;
        }
        print() {
            console.log(' ', this.name);
            console.log(' ', this.sex);
        }
    }
    
    
    class Dog extends Animal {
        constructor( name, sex ) {
            super( name, sex ); //  
        }
    
        print() {
            super.print(); //  
        }
    }
    

    좋은 웹페이지 즐겨찾기