Javascript 是否有可能访问;“内部”;ES5-8.6.2中定义的对象属性?
“内部”指ES5 8.6.2中定义的内容: 可以使用访问[[Class]]内部属性Javascript 是否有可能访问;“内部”;ES5-8.6.2中定义的对象属性?,javascript,Javascript,“内部”指ES5 8.6.2中定义的内容: 可以使用访问[[Class]]内部属性 Object.prototype.toString(Object) 这些属性的用途是什么?这些属性是否可访问 该规范未声明定义修改方法(第32页页脚) 注意:本规范未定义ECMAScript语言运算符或 允许程序修改对象属性的内置函数 [[Class]]或[[Prototype]]内部属性或更改值 将[[Extensible]]的值从false改为true。具体实施 修改[[Class]]、[[Protot
Object.prototype.toString(Object)
这些属性的用途是什么?这些属性是否可访问
该规范未声明定义修改方法(第32页页脚)
注意:本规范未定义ECMAScript语言运算符或
允许程序修改对象属性的内置函数
[[Class]]或[[Prototype]]内部属性或更改值
将[[Extensible]]的值从false改为true。具体实施
修改[[Class]]、[[Prototype]]或[[Extensible]]的扩展必须
不违反上一段中定义的不变量
他们可以接近吗
不完全如此,您可以计算出它们返回的内容(基于它们各自的定义),但您无法更改它们的工作方式
以下是解决大多数问题的方法(在中列出)。
对于所有示例,我假设对象存储为obj
,属性键为name
,val
为值,descriptor
为属性描述符
[[Prototype]]
[[Class]]
[[Extensible]]
,[[Get]]
obj[name]
[[GetOwnProperty]
,[[GetProperty]]
与上行继承(对象.getOwnPropertyDescriptor(obj,name)
)对象.getPrototypeOf
,[[Put]]
obj[name]=val
,如果undefined是[[CanPut]]
可扩展(),请查找obj
?否则,请检查setter集合的可写性或存在性getOwnPropertyDescriptor
[[HasProperty]]
[[Delete]]
,对此不确定[[DefaultValue]]
[[DefineOwnProperty]
ES6+ 在ES6中,我们可以访问s,这意味着我们可以创建对象,然后使用
代理将它们包装起来,以便以自定义方式处理get、set、has等
// have some object
let o = {};
// wrap with proxy defining a get handler and set handler
let p = new Proxy(o, {
get(t, n) {
console.log(t, n, t[n]);
return t[n];
},
set(t, n, v) {
t[n] = +v;
return true;
}
});
// now accessing via proxy
p.foo; // undefined
// get handler logs Object o, "foo", undefined (this happens before .foo returns)
p.foo = '123'; // uses handler to sets on `o`
p.foo; // 123, notice value is Number due to set handler
// get handler logs Object o, "foo", 123 (this happens before .foo returns)
对
它们可以访问:
Object.defineProperty({}, 'key', {
get: function(){
console.log('GOT %s', 'key');
return someValue;
},
set: function(value){
console.log('SET %s', 'key');
this[key] = value;
}
});
这相当于:
var object = {
_name: '',
get name(){ return this._name; },
set name(value){ this._name = value; }
};
但是,我还不知道如何访问[[Put]]&[[Delete]]——如果你知道,请详细说明。内部“不就是说它们不应该公开吗?(我指的是语言特征)。事实上,它们甚至不必实现,只要解释器的行为与它们一样。你所说的“暴露”是什么意思?“[[class]]的值可以通过上述方法检索。我编辑了我的评论以澄清这一点。我的意思是暴露为语言特征。实际上,其他人是以[[Class]]的方式公开的,例如[[Value]]。还有一些甚至可以修改,比如[[Enumerable]]在属性描述符的情况下。我想把这句话作为一个答案。它们只是用来描述语言行为的人工制品。还有一个例子(这次是从8.6.2中的列表中):[[GetOwnProperty]]似乎被公开为对象。getOwnPropertyDescriptor
。你能举个例子说明如何使用[[Put]]和[[Delete]]属性吗?@Cody除了我在答案中已经给出的以外,我不完全确定你在问什么。也许你想要一个综合的例子。。假设您有一些stateObj={}
,可以切换属性foo的存在if(stateObj.hasOwnProperty('foo'))/*[[Delete]]]*/Delete stateObj.foo;else/*[[Put]]*/stateObj.foo=true代码>@Paul\S,谢谢你的回复。我的意思是,不是像Object.defineProperty({},'key',{Set:function(){…}})那样插入[[Set]]]
代码>--如何插值[[Put]]
s(?)。更像是,Object.defineProperty({},[[Put]]”,function(){alert('newproperty added!');})代码>这样就可以跟踪对象何时添加了新属性。@科迪,我想你误解了这些属性的公开。你不能那样做,这就像在你喝完茶后要求换一种茶一样。如果要修改这些内容,必须对引擎进行更改并自己编译。对象有内部方法来修改[[Get]]s和[[set]]s的工作方式。像[[Get]]和[[Set]]这样的CRUD操作(创建、读取、更新和删除——映射到Put、Get、Set、Delete)是可以修改的——认为[[Put]]和[[Delete]]也可以修改并不牵强。唯一的区别是它们的比例不同(对象与对象属性比例相反)。换句话说,我只是在修改Get&Set时改变了我的茶的“类型”——在句子中使用“类型”时要小心:我没有改变它的类型——它仍然是一个对象;我只是在改变一个内部方法,[[Put]];前几天我遇到了这个问题,并且(假设你仍然需要它,并且在一个可以使用它的环境中)认为它可能与你想要做的事情有关@Paul S。这是个好消息!我在一个非常小的教程中遇到代理,不确定它是否是我想要的。非常感谢!你应该写一个小要点并发表在这个评论下;)。。。也就是说,如果您已经非常熟悉代理(我不是)。