为什么节点js会这样表现?

时间:2018-10-15 18:46:03

标签: javascript node.js

考虑以下代码

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竞赛的一部分

1 个答案:

答案 0 :(得分:4)

getCleanObject并没有多大意义,因为它先分配属性,然后尝试取消设置对象原型,这将导致对象具有大量垃圾键。

__proto__non-compliant property,在某些实现中可能存在,但不应依赖。 Object.getPrototypeOfObject.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);