有没有办法在ES5之前创建没有原型的对象?
即。像Object.create(null)
(ES5)
我认为这样的事情可能有效,但最后的陈述意外地返回true
:
function withPrototype(p) {
function temp(){}
temp.prototype = p;
return new temp();
}
Object.getPrototypeOf(withPrototype(null)) === Object.prototype; // true
Object.getPrototypeOf
是ES5。我在这里用它来说明。
答案 0 :(得分:2)
没有。在ES3 spec中搜索[[Prototype]]
表示将[[Prototype]]更改为任意给定值的唯一方法是通过[[Construct]]。
但是,只有当一个对象的值时,它才有效。如果不是(包括null),[[Prototype]]将被设置为Object.prototype
的初始值。
13.2.2 [[Construct]]
当调用Function对象F的[[Construct]]属性时, 采取以下步骤:
- 创建一个新的本机ECMAScript对象。
- 将Result(1)的[[Class]]属性设置为
"Object"
。- 获取F。
的prototype
属性的值- 如果Result(3)是对象,请将Result(1)的[[Prototype]]属性设置为Result(3)。
- 如果Result(3)不是对象,请将Result(1)的[[Prototype]]属性设置为原始Object原型对象,如 15.2.3.1。
- 调用F的[[Call]]属性,提供Result(1)作为 this 值,并提供传递给[[Construct]]的参数列表作为参数值。
- 如果Type(Result(6))是Object,则返回Result(6)。
- 返回结果(1)。
醇>
答案 1 :(得分:2)
正如@Oriol所示,没有“官方”(符合规范)的方式来做到这一点。
然而,确实存在一个没有原型的对象 - Object.prototype
本身。
15.2.4对象原型对象的属性
Object原型对象的内部
[[Prototype]]
属性的值为null
,内部[[Class]]
属性的值为"Object"
。
您可以通过实例化新环境(ES6术语中的“领域”)来“创建”此类对象,例如:通过<iframe>
,抓住它的Object.prototype
,剥去它的属性并vo-你有一个新的空物体。
function getNoProtoObject(callback) {
var iframe = document.createElement('iframe');
iframe.onload = function() {
var obj = iframe.contentWindow.Object.prototype;
document.body.removeChild(iframe);
// Remove all built-in enumerable properties.
for (var name in obj) {
delete obj[name];
}
// Remove known built-in non-enumerable properties, which may vary.
delete obj['constructor'];
delete obj['hasOwnProperty'];
delete obj['isPrototypeOf'];
delete obj['propertyIsEnumerable'];
delete obj['toLocaleString'];
delete obj['toString'];
delete obj['toSource'];
delete obj['valueOf'];
delete obj['watch'];
delete obj['unwatch'];
delete obj['__defineGetter__'];
delete obj['__defineSetter__'];
delete obj['__lookupGetter__'];
delete obj['__lookupSetter__'];
delete obj['__proto__'];
callback(obj);
};
iframe.src = 'about:blank';
iframe.style.display = 'none';
document.body.appendChild(iframe);
}
getNoProtoObject(function(o) {
console.log(o); // Object { }
console.log(Object.getPrototypeOf(o)); // null
console.log(o.__proto__); // undefined
});