2016-06-28 3 views
1

저는 며칠 동안 자바 스크립트 (64 비트 데비안 제시에 최신 Chrome 빌드 사용)를 배우고 있습니다. 지금 정확히 Object.defineProperty의 작동 방식을 이해해야합니다.Object.defineProperty - 객체를 반환하는 함수 내에서 범위 및 사용?

function createPerson() { 
    var person = { 
     firstName: 'Lilly', 
     lastName: 'Louis', 
    }; 

    Object.defineProperty(person, 'fullName', { 
     get: function() { 
      return this.firstName + ' ' + this.lastName; 
     }, 
     set: function(name) { 
      var words = name.split(' '); 
      this.firstName = words[0] || ''; 
      this.lastName = words[1] || ''; 
     } 
    }); 
} 

var p1 = createPerson(); 
console.log("Person's default name is \"" + p1.fullName + "\""); 

은 내가 console.log(...) 내부의 속성을 사용하려고 라인에서 Uncaught TypeError: Cannot read property 'fullName' of undefined 얻을 : 나는 다음과 같은 페이지가 있습니다. 함수 외에서 Object.defineProperty과 함께 person의 정의를 배치하면 모든 것이 잘 작동합니다. 내가 p1 후 함수 외부 Object.defineProperty을 이동하면 다음과 같이 작성됩니다

var p1 = createPerson(); 
Object.defineProperty(p1, 'fullName', { 
    get: function() { 
     return this.firstName + ' ' + this.lastName; 
    }, 
    set: function(name) { 
     var names = name.split(' '); 
     this.firstName = names[0] || ''; 
     this.lastName = names[1] || ''; 
    } 
}); 

내가 콘솔이가 (anonymous function) (즉 p1이다) 더욱 혼란 된 호출 지적 다음 Uncaught TypeError: Object.defineProperty called on non-object를 얻을 수 이후로 나는 그걸 읽었습니다. callPerson을 내 p1에 대괄호없이 할당하면 함수 객체를 전달할 것입니다. 그렇지 않으면 함수 자체를 호출하고 그 반환 값을 지정합니다. (없는 경우 은 정의되지 않음이 반환 됨) to p1.

저는 두 문제가 완전히 별개이지만 여전히 동일한 질문을하기로 결정했기 때문에 100 % 확신하지 못했습니다. 내가 여기서 잘못하고있는 충고는 무엇입니까? 나는 단순히

function createPerson() { 
    var person = { 
     firstName: 'Lilly', 
     lastName: 'Louis', 
     getFullName: function() { 
      return ...; 
     } 
     setFullName: function(name) { 
      ... 
     } 
    }; 
} 

을 수행하여 내 gettersetter 옛날 방식을 정의 할 수 있습니다하지만 난 여기에 무슨 일이 일어나고 있는지 이해하고 싶습니다. : D

답변

4

defineProperty 전화는 아주 좋습니다. 문제는 createPerson이 아무 것도 반환하지 않으므로 호출 결과가 undefined입니다. 당신은 마지막에 return person;을 원하는 :

function createPerson() { 
 
    var person = { 
 
    firstName: 'Lilly', 
 
    lastName: 'Louis', 
 
    }; 
 

 
    Object.defineProperty(person, 'fullName', { 
 
    get: function() { 
 
     return this.firstName + ' ' + this.lastName; 
 
    }, 
 
    set: function(name) { 
 
     var words = name.split(' '); 
 
     this.firstName = words[0] || ''; 
 
     this.lastName = words[1] || ''; 
 
    } 
 
    }); 
 
    
 
    return person; // <======= 
 
} 
 

 
var p1 = createPerson(); 
 
console.log("Person's default name is \"" + p1.fullName + "\"");

다른 방법으로는, 그것을 (new와 함께 사용)를 생성자 기능보다는 공장 기능을 확인하고 함수 내에서 this를 사용합니다. 이 경우 이름에서 create을 삭제하고 함수가 다른 객체를 반환하지 않으면 기본적으로 new XYZ의 결과가 해당 객체에서 생성 된 객체이기 때문에 (일반적으로) return this;을 사용하지 않을 것입니다. new 연산자와 this로 함수에 공급 : 당신은 person 변수를 만들었지 만 그것을 반환되지 않기 때문에

function Person() { 
 
    this.firstName = 'Lilly'; 
 
    this.lastName = 'Louis'; 
 

 
    Object.defineProperty(this, 'fullName', { 
 
    get: function() { 
 
     return this.firstName + ' ' + this.lastName; 
 
    }, 
 
    set: function(name) { 
 
     var words = name.split(' '); 
 
     this.firstName = words[0] || ''; 
 
     this.lastName = words[1] || ''; 
 
    } 
 
    }); 
 
} 
 

 
var p1 = new Person(); 
 
console.log("Person's default name is \"" + p1.fullName + "\"");

+0

* facepalm * Christ, 코드를 이동하면서 코드를 삭제했습니다. 그래서 나 바보 같아. 고마워. 고마워. – rbaleksandar

1

이다. 따라서 함수에서 아무 것도 반환되지 않고 할당은 정의되지 않습니다.

function createPerson() { 
    var person = { 
     firstName: 'Lilly', 
     lastName: 'Louis', 
    }; 

    Object.defineProperty(person, 'fullName', { 
     get: function() { return this.firstName + ' ' + this.lastName; }, 
     set: function(name) { 
      var words = name.split(' '); 
      this.firstName = words[0] || ''; 
      this.lastName = words[1] || ''; 
     } 
    }); 
    return person; // Add this line 
} 
관련 문제