http://speakingjs.com/es5/ch28.html#_obstacle_1_instances_with_internal_properties
Most built-in constructors have instances with so-called internal properties (see Kinds of Properties), whose names are written in double square brackets, like this: [[PrimitiveValue]]. Internal properties are managed by the JavaScript engine and usually not directly accessible in JavaScript.
Furthermore, adding internal properties to an existing instance (1) is in general impossible, because they tend to fundamentally change the instance’s nature.
The work around proposed in order to add internal properties. http://speakingjs.com/es5/ch28.html#_workaround_for_obstacle_1
function MyArray(/*arguments*/) {
var arr = [];
// Don’t use Array constructor to set up elements (doesn’t always work)
Array.prototype.push.apply(arr, arguments); // (1)
copyOwnPropertiesFrom(arr, MyArray.methods);
return arr;
}
MyArray.methods = {
get size() {
var size = 0;
for (var i=0; i < this.length; i++) {
if (i in this) size++;
}
return size;
}
}
function copyOwnPropertiesFrom(target, source) {
Object.getOwnPropertyNames(source) // (1)
.forEach(function(propKey) { // (2)
var desc = Object.getOwnPropertyDescriptor(source, propKey); // (3)
Object.defineProperty(target, propKey, desc); // (4)
});
return target;
};
Interaction
> > var a = new MyArray('a', 'b')
> a.length = 4;
> a.length
4
> a.size
2
1º I understand, by adding only a getter to the property size, there's no way to set a.size
2º I also understand that we are defining a new property in an array by MyArray.methods, but I don't see in which kind of way it's been added "a new internal property". As far as I am concerned, internal properties are a kind of property not directly accessible by Javascript.
Could "size" be considered an internal property itself?
Greetings
I don't see in which kind of way it's been added "a new internal property". As far as I am concerned, internal properties are a kind of property not directly accessible by Javascript.
Yes, the point of an internal property is that you can't manually create it. So instead of constructing our object and adding the internal property that we want, we need to use an object which already has that internal property, and copy our methods onto it - basically as a mixin, because we cannot use prototypical inheritance.
The one we're after is the internal instance method [[DefineOwnProperty]]
of arrays which treats integer properties specially, and we also want to have the special behaviour of the .length
property (that is not internal, but cannot be manually constructed either). So we use var arr = []
to get these, and put our size
custom property on it.
Could "size" be considered an internal property itself?
No. "internal" means that it cannot be accessed via the means of the language, and are only used to describe the behaviour in the specification.