admin管理员组文章数量:1405754
I have a library with the following addition for Array types -
Array.prototype.top = function() {
return (this.length > 0) ? this[this.length-1] : null;
}
It seems to be applied to non-Array objects - e.g.,
for (key in myrecordset) {
alert(key); // will iterate and alert "top";
}
In the debugger console:
> myrecordset.length
< undefined
> typeof myrecordset
< 'object'
> myrecordset instanceof(Array)
< false
> myrecordset['top']
< f() {
return (this.length ...
}
So, what the ? The object is not a javascript array (ie, no length, not an instance of, ...) but the Array.prototype.top seems to have been applied?
Note: in addition, trying to follow the prototype chain I get
> myrecordset.constructor()
< {}
[[ Prototype ]]: Object
SCOPE: screen shot with myrecordset
I have a library with the following addition for Array types -
Array.prototype.top = function() {
return (this.length > 0) ? this[this.length-1] : null;
}
It seems to be applied to non-Array objects - e.g.,
for (key in myrecordset) {
alert(key); // will iterate and alert "top";
}
In the debugger console:
> myrecordset.length
< undefined
> typeof myrecordset
< 'object'
> myrecordset instanceof(Array)
< false
> myrecordset['top']
< f() {
return (this.length ...
}
So, what the ? The object is not a javascript array (ie, no length, not an instance of, ...) but the Array.prototype.top seems to have been applied?
Note: in addition, trying to follow the prototype chain I get
> myrecordset.constructor()
< {}
[[ Prototype ]]: Object
SCOPE: screen shot with myrecordset
Share Improve this question edited Mar 8 at 5:23 Nick Parsons 51.2k6 gold badges57 silver badges78 bronze badges asked Mar 8 at 4:04 Chrys GChrys G 11110 bronze badges 19 | Show 14 more comments2 Answers
Reset to default 1To properly extend a prototype you should make the new props non enumerable. In your case you could be interested in a fix that runs after including the problematic code, it will convert all enumerable props to non enumerable:
Array.prototype.top = function () {
return this.length ? this[this.length-1] : null;
}
function makeNonEnumerable(obj){
const props = Object.getOwnPropertyDescriptors(obj);
for(const name in props){
const desc = props[name]
if(desc.enumerable){
desc.enumerable = false;
Object.defineProperty(obj, name, desc);
}
}
}
makeNonEnumerable(Array.prototype);
console.log([1,2,3].top()); // 3
class RecordSet {
constructor(...items) {
Object.assign(this, items);
Object.assign(this, Array.prototype);
}
}
const myrecordset = new RecordSet({a:1}, {b:2});
console.log(myrecordset); // "0": .. "1":
There are many ways that an object may get a property that is equal to top
. The screenshot proves that myrecordset
has a top
property that is not an inherited property, but is an "own" property. This means it got copied there.
Here is one possible scenario that could have happened:
Array.prototype.top = function () {
return this.length ? this[this.length-1] : null;
}
console.log([1,2,3].top()); // 3
class RecordSet {
constructor(...items) {
Object.assign(this, items);
Object.assign(this, Array.prototype);
}
}
const myrecordset = new RecordSet({a:1}, {b:2});
console.log("top" in myrecordset); // true
console.log(myrecordset.length); // undefined
console.log(typeof myrecordset); // object
console.log(myrecordset instanceof Array); // false
console.log(myrecordset.top === Array.prototype.top); // true
console.log(myrecordset); // "0": .. "1": .. "top": ..
One way to possibly prevent this, is to define top
as a non-enumerable property on the Array prototype:
Object.defineProperty(Array.prototype, "top", {
configurable: true,
writable: true,
value() {
return this.length ? this[this.length-1] : null;
}
});
console.log([1,2,3].top()); // 3
class RecordSet {
constructor(...items) {
Object.assign(this, items);
Object.assign(this, Array.prototype);
}
}
const myrecordset = new RecordSet({a:1}, {b:2});
console.log("top" in myrecordset); // false
console.log(myrecordset.top); // undefined
console.log(myrecordset); // "0": .. "1": ..
本文标签: javascriptarrayprototype is being applied to a nonarray object ()Stack Overflow
版权声明:本文标题:javascript - array.prototype is being applied to a non-array object (?) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744903403a2631479.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
myrecordset
is. Please, answer a simple question: What happens if you callmyrecordset['top']()
? (Iflenght
is undefined...) – Sergey A Kryukov Commented Mar 8 at 4:19Object.getPrototypeOf(myrecordset);
or just logmyrecordset
and follow the[[Prototype]]
internal slots to follow the prototype chain, not.constructor()
– Nick Parsons Commented Mar 8 at 4:30myrecordset
. – Barmar Commented Mar 8 at 5:07