const object1 = {};
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1'));
// Expected output: true
console.log(object1.hasOwnProperty('toString'));
// Expected output: false
console.log(object1.hasOwnProperty('hasOwnProperty'));
// Expected output: false
hasOwnProperty(prop)
👉
쉐도잉
어떤 블록(구역) 안에 또 다른 블록이 있을 때, 밖의 블록 범위 중 일부분을 안에 있는 블록이 차지하는 것을 말한다.
즉, 밖의 블록에서 선언된 변수와 안의 블록에서 선언된 변수의 이름이 같을시, 블록 안에선 안의 블록에서 선언된 변수가 우선권을 갖는 것을 의미한다.
객체 속성 선언을 통해 객체 프로토타입 체이닝을 이용하지 못하는 현상을 쉐도잉(shadowing)
이라고 한다.
다음 코드에서 변수 a에 명시적으로 hasOwnProperty
객체 속성을 지정해주었을 때 일어날 수 있는 쉐도잉 문제점을 지적한다.
const a = Object.create(null);
console.log(a); // {}
a.b = "hello";
console.log(a); // {b: "hello"}
console.log(a.__proto__); // undefined
a.hasOwnProperty = function() {
return true;
}
console.log(a.hasOwnProperty("notExist")); // 항상 true
위의 쉐도잉을 이용해 nodejs 서버에 DOS 공격이 들어올 수 있다.
👉 객체 생성의 근원지를 장담할 수 없는 경우에는 다음과 같이 사용해야 한다.
Object.prototype.hasOwnProperty.call(foo, "bar");
obj.func?.(args)
는 함수가 정의되어 있다면 호출하라는 의미이다.
하지만, ?.
operator는 func이 함수임을 보장하지 않는다.
obj가 nullish한지만 체크한다.
?.
옆에 ()
처럼 함수 호출식이 적혀있기 때문에 마치 non-nullish
하고 callable
두 가지 조건을 모두 만족할 경우에만 호출하라는, 즉 safe call 기능을 하는 것 처럼 오해를 가져다줄 수 있다.
optional chaning function call은 safe call이 아니다.
ESLint 룰인 no-prototype-builtins
은 Object.prototype
메소드를 사용하는 것을 금지한다.
가장 현실적인 방법으로, 다음처럼 builtin 메소드를 직접적으로 참조해서 사용할 경우 에러를 발생한다.
/*eslint no-prototype-builtins: "error"*/
Object.prototype.hasOwnProperty.call(foo, "bar");
var hasBarProperty = foo.hasOwnProperty("bar");
var isPrototypeOfBar = foo.isPrototypeOf(bar);
var barIsEnumerable = foo.propertyIsEnumerable("bar");