在Javascript中对内置构造函数和内部属性进行子类化

时间:2014-08-03 12:19:55

标签: javascript properties internal subclassing

http://speakingjs.com/es5/ch28.html#_obstacle_1_instances_with_internal_properties

  

大多数内置构造函数都有所谓的内部实例   属性(请参阅属性的种类),其名称以   双方括号,如下所示:[[PrimitiveValue]]。内部   属性由JavaScript引擎管理,通常不会   可以在JavaScript中直接访问。

     

此外,向现有实例(1)添加内部属性是   一般不可能,因为他们往往会从根本上改变   实例的本质。

为了添加内部属性,提出了解决方法。 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;
};

相互作用

> > var a = new MyArray('a', 'b')
> a.length = 4;
> a.length
4
> a.size
2

1º我明白,只通过在属性大小中添加一个getter,就无法设置a.size

2º我也明白我们正在通过MyArray.methods在数组中定义一个新属性,但我没有看到以哪种方式它被添加为“一个新的内部属性”。就我而言,内部属性是Javascript无法直接访问的一种属性。

“尺寸”可以被视为内部财产吗?

问候

1 个答案:

答案 0 :(得分:0)

  

我没有看到它被添加为“新内部属性”的方式。就我而言,内部属性是Javascript无法直接访问的一种属性。

是的,内部属性的要点是您无法手动创建它。因此,不是构造我们的对象并添加我们想要的内部属性,而是需要使用已经具有该内部属性的对象,并将我们的方法复制到它上 - 基本上作为mixin,因为我们不能使用原型继承。

我们追求的是数组的内部实例方法[[DefineOwnProperty]],它特别处理整数属性,我们还希望具有.length属性的特殊行为(不是内部的,但也不能手工构建)。因此,我们使用var arr = []来获取这些内容,并将size自定义属性放在其上。

  

“尺寸”可以被视为内部财产吗?

没有。 “internal”表示无法通过语言and are only used to describe the behaviour in the specification进行访问。