考虑以下代码
function getCleanObject() {
var obj = {};
for (var _i = 0, _a = Object.getOwnPropertyNames(obj.__proto__); _i < _a.length; _i++) {
var prop = _a[_i];
obj[prop] = undefined;
}
obj.__proto__ = undefined;
return obj;
}
var a = 1;
console.log(getCleanObject(a).__proto__);
//'undefined' in browser
//'{}' in nodejs
一个简单的函数,它返回对象,所有内容都被剥离或设置为undefined
。在浏览器控制台中执行此操作时,将得到undefined
,这是预期的,因为__proto__
设置为undefined
,但是当我们在节点中执行相同的代码时,则会得到{{1} },我很困惑为什么会这样。
这是{}
CTF竞赛的一部分
答案 0 :(得分:4)
getCleanObject
并没有多大意义,因为它先分配属性,然后尝试取消设置对象原型,这将导致对象具有大量垃圾键。
__proto__
是non-compliant property,在某些实现中可能存在,但不应依赖。 Object.getPrototypeOf
和Object.setPrototypeOf
是访问对象原型的正确方法。
__proto__
将在V8(Node.js,Chrome)中运行,因为它们支持它。它是Object.prototype
上的描述符:
({}).hasOwnProperty('__proto__') === false
(Object.prototype).hasOwnProperty('__proto__') === true
它不允许分配任意值,只能分配null
和对象:
Object.prototype的 proto 属性是一个访问器属性(一个getter函数和一个setter函数),它通过以下方法公开对象的内部[[Prototype]](对象或null)可以访问它。
obj.__proto__ = undefined
不正确,不应正常工作。它可以在Node中作为obj.__proto__ = null
使用。正确的方法是Object.setPrototypeOf(obj, null)
。
如果没有getCleanObject
中应该修改的现有对象(不建议修改原型,因为这样做可能会扼杀优化),则可能是:
const obj = Object.create(null);