2016-07-05 2 views
0

개체가 인스턴스화 될 때 문자열/함수/등일 경우 __proto__ 속성이 포함됩니다. 이 속성은 ... Object.prototype__proto__ 접근에 의해 생성 된 것으로 보인다하이재킹 .__ proto__

Object.prototype == { 
    __defineGetter__ : __defineGetter__() 
    __defineSetter__ : __defineSetter__() 
    __lookupGetter__ : __lookupGetter__() 
    __lookupSetter__ : __lookupSetter__() 
    constructor   : Object() 
    hasOwnProperty  : hasOwnProperty() 
    isPrototypeOf  : isPrototypeOf() 
    propertyIsEnumerable: propertyIsEnumerable() 
    toLocaleString  : toLocaleString() 
    toString   : toString() 
    valueOf    : valueOf() 
    get __proto__  : __proto__()    // getter 
    set __proto__  : __proto__()    // setter 
}; 

이 객체가 인스턴스화 될 때 코드 블록을 실행하려면이 __proto__ 속성을 납치 할 수 있다면 궁금하네요. 새 인스턴스에 __proto__을 만들기 위해 원래 접근자를 호출하기 전에 __proto__ 속성을 일부 코드를 실행하는 사용자 지정 속성으로 바꾸는 것이 좋습니다.

그럴리가요! 아직 제대로 작동하는지 말할 수 없다

pro = Object.prototype; 
tmp = {}; 
Object.defineProperty(tmp, '__proto__', 
    Object.getOwnPropertyDescriptor(pro, '__proto__') 
); 
delete pro.__proto__; 
Object.defineProperty(pro, '__proto__',{ 
    get:function(){ 
     console.warn('intercepted Get __proto__'); 
     return tmp.__proto__; 
    }, 
    set(p){ 
     console.warn('intercepted Set __proto__'); 
     tmp.__proto__ = p; 
    } 
}); 

하지만 그것은 단지 시도하는 예입니다 내가 달성하기 위해 노력하고있어 보여 : 나는까지 해요 어디 있지 여기하다면입니다.

+0

"* a'__proto__' 속성이 포함됩니다. *"- 음, 아니요, ** 상속 **입니다. 'hasOwnProperty' 속성이 모든 객체에 포함되어 있다고 말할 수는 없겠지요? – Bergi

+0

아니요, 더 이상 * 그들을 납치 할 수 없습니다. [좋은 일입니다] (http://stackoverflow.com/a/13040748/1048572). – Bergi

답변

2

__proto__ 속성을 인스턴스화 할 때 코드 블록을 실행하는 것이 가능한지 궁금합니다.

아니요. 개체를 만들 때 __proto__ 속성의 접근자는 호출되지 않습니다. __proto__을 가져 오거나 설정할 때만 호출됩니다. 당신은 어떤 객체가 the spec보고 생성 될 때 발생 볼 수 있습니다

ObjectCreate (프로토를 [internalSlotsList])

인수 프로토와 추상 작업 ObjectCreate (AN 객체 또는 null)은 새로운 일반 객체의 런타임 생성을 지정하는 데 사용됩니다. 선택적 인수 internalSlotsList은 개체의 일부로 정의해야하는 추가 내부 슬롯의 이름 목록입니다. 목록이 제공되지 않으면 새로운 빈 목록이 사용됩니다. 이 추상 작업은 다음 단계를 수행합니다 internalSlotsList이 제공되지 않았습니다

  1. 경우, internalSlotsList 새로운 빈 목록이 될 수 있습니다.
  2. obj내부 슬롯 번호에 각 이름의 내부 슬롯이있는 새로 만든 개체로 만들자.
  3. obj을 9.1에 지정된 기본 일반 개체 정의에 필수적인 내부 메서드로 설정하십시오.
  4. [Prototype] 내부 슬롯 objproto으로 설정하십시오.
  5. 의 [[Extensible]] 내부 슬롯을 obj에서 까지으로 설정하십시오.
  6. 돌아 가기 obj.

리콜 그게 __proto__은 아니다 객체의 프로토 타입 참조; 코드에서 액세스 할 수없는 객체의 슬롯은 [[Prototype]]입니다. __proto__은 (웹 전용) 해당 슬롯의 값에 액세스하는 수단입니다. (또한 공식적으로 __proto__ 반면, 외부 브라우저를 작동하지 않는 일반적인 방법은, ObjectReflectgetPrototypeOf/setPrototypeOf입니다.) 또한 모든 객체가 Object.prototype에서 상속하지 때문에 모든 객체가 __proto__을 가지고 있습니다 :

var o1 = {}; 
 
console.log("__proto__" in o1); // true 
 
var o2 = Object.create(null); // No prototype 
 
console.log("__proto__" in o2); // false 
 
var o3 = Object.create(o2);  // Has a prototype, but still no link to Object.prototype 
 
console.log("__proto__" in o3); // false

+0

개체를 인스턴스화 할 때 컴파일러에서'get __proto__'를 호출한다고 가정합니다. – LostInCyberSpace

+1

@LostInCyberSpace : 아니요, 엔진은 객체를 인스턴스화 할 때 접근자를 호출하지 않습니다. –

+0

건배, 거기에 ... – LostInCyberSpace