在 ES5 之前,有没有办法在没有原型的情况下创建对象?
Was there a way to create an object without a prototype prior to ES5?
有没有办法在 ES5 之前创建一个没有原型的对象?
即像 Object.create(null)
(ES5)
我以为这样的事情可能会奏效,但最后的声明出人意料returns true
:
function withPrototype(p) {
function temp(){}
temp.prototype = p;
return new temp();
}
Object.getPrototypeOf(withPrototype(null)) === Object.prototype; // true
Object.getPrototypeOf
是 ES5。我在这里用它来说明。
没有。在 ES3 spec 中搜索 [[Prototype]]
表明将 [[Prototype]] 更改为任意给定值的唯一方法是通过 [[Construct]].
但是,只有当该值是一个对象时它才有效。如果不是(包括null
),[[Prototype]]将被设置为Object.prototype
的初始值。
13.2.2 [[Construct]]
When the [[Construct]] property for a Function object F is called, the
following steps are taken:
- Create a new native ECMAScript object.
- Set the [[Class]] property of Result(1) to
"Object"
.
- Get the value of the
prototype
property of the F.
- If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
- If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as described in
15.2.3.1.
- Invoke the [[Call]] property of F, providing Result(1) as the this value and providing the argument list passed into [[Construct]] as the argument values.
- If Type(Result(6)) is Object then return Result(6).
- Return Result(1).
如@Oriol 所示,没有"official"(符合规范的)方法来做到这一点。
然而,确实存在一个没有原型的对象 - Object.prototype
本身。
15.2.4 Properties of the Object Prototype Object
The value of the internal [[Prototype]]
property of the Object prototype object is null
and the value of the internal [[Class]]
property is "Object"
.
您可以通过实例化一个新环境("realm" 在 ES6 术语中)潜在地 "create" 这样一个对象,例如通过 <iframe>
,捕获它的 Object.prototype
,剥离它的属性,瞧瞧——你得到了一个新的空对象。
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
});
有没有办法在 ES5 之前创建一个没有原型的对象?
即像 Object.create(null)
(ES5)
我以为这样的事情可能会奏效,但最后的声明出人意料returns true
:
function withPrototype(p) {
function temp(){}
temp.prototype = p;
return new temp();
}
Object.getPrototypeOf(withPrototype(null)) === Object.prototype; // true
Object.getPrototypeOf
是 ES5。我在这里用它来说明。
没有。在 ES3 spec 中搜索 [[Prototype]]
表明将 [[Prototype]] 更改为任意给定值的唯一方法是通过 [[Construct]].
但是,只有当该值是一个对象时它才有效。如果不是(包括null
),[[Prototype]]将被设置为Object.prototype
的初始值。
13.2.2 [[Construct]]
When the [[Construct]] property for a Function object F is called, the following steps are taken:
- Create a new native ECMAScript object.
- Set the [[Class]] property of Result(1) to
"Object"
.- Get the value of the
prototype
property of the F.- If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
- If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as described in 15.2.3.1.
- Invoke the [[Call]] property of F, providing Result(1) as the this value and providing the argument list passed into [[Construct]] as the argument values.
- If Type(Result(6)) is Object then return Result(6).
- Return Result(1).
如@Oriol 所示,没有"official"(符合规范的)方法来做到这一点。
然而,确实存在一个没有原型的对象 - Object.prototype
本身。
15.2.4 Properties of the Object Prototype Object
The value of the internal
[[Prototype]]
property of the Object prototype object isnull
and the value of the internal[[Class]]
property is"Object"
.
您可以通过实例化一个新环境("realm" 在 ES6 术语中)潜在地 "create" 这样一个对象,例如通过 <iframe>
,捕获它的 Object.prototype
,剥离它的属性,瞧瞧——你得到了一个新的空对象。
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
});