本文介绍了为什么设置阵列中的一个子类不会改变其长度位置?我不应该继承阵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的CoffeeScript程序,创建阵列这台在其构造两个位置的子类:

In the CoffeeScript program below, I create a subclass of Array which sets two positions in its constructor:

class SetPositionsArray extends Array
  constructor: (x,y) ->
    @[0] = x
    @[1] = y

  myLength: ->
    @length

sp_array = new SetPositionsArray 1, 2

console.log "sp_array: "
console.log sp_array
console.log "sp_array[0]: "
console.log sp_array[0]
console.log "sp_array[1]: "
console.log sp_array[1]
console.log "sp_array.length: "
console.log sp_array.length
console.log "sp_array.myLength(): "
console.log sp_array.myLength()

我希望这code会改变 sp_array 长度属性,因为它有效地设置它的立场。但是,输出我得到的是:

I would hope that this code would change the length property of sp_array, since it effectively sets positions on it. However, the output I get is:

$ coffee sp.coffee
sp_array: 
[ 1, 2 ]
sp_array[0]: 
1
sp_array[1]: 
2
sp_array.length: 
0
sp_array.myLength(): 
0

即,长度为0

然后,我创建了另一个类的实例推值而不是将它们设置的:

Then, I created another class which pushes values in the instance instead of setting them:

class PushValuesArray extends Array
  constructor: (x,y) ->
    @push x
    @push y

  myLength: ->
    @length


pv_array = new PushValuesArray 1, 2


console.log "pv_array: "
console.log pv_array
console.log "pv_array[0]: "
console.log pv_array[0]
console.log "pv_array[1]: "
console.log pv_array[1]
console.log "pv_array.length: "
console.log pv_array.length
console.log "pv_array.myLength(): "
console.log pv_array.myLength()

在这种情况下,我得到预期的结果,但有一个的实际长度数组中的属性(虽然我会想象这将是一些内部细节):

In this case, I get the expected result, except that there is an actual length attribute in the array (while I would imagine that it would be some internal detail):

$ coffee pv.coffee
pv_array: 
[ 1, 2, length: 2 ]
pv_array[0]: 
1
pv_array[1]: 
2
pv_array.length: 
2
pv_array.myLength(): 
2

那么,为什么设置的位置在数组中不改变其长度是多少?

So, why does setting the position in the array does not change its length?

这个问题是。

This question is related to this one for which I posted this answer.

推荐答案

最简单的解释是:长度魔法

长度显然不能像普通的财产,因为当你插入/它的对象上删除其他属性(,相反,设置<$改变其价值C $ C>长度= 0 将删除其他属性);但没有什么特别之处的标识的长度。这意味着你可以很容易地编写 foo.length ='酒吧',世界将不停地转动。只有在阵列它有它的特殊性。

length obviously doesn't behave like an ordinary property, since it changes its value when you insert/delete other properties on its object (and, conversely, setting length = 0 will delete other properties); but there's nothing special about the identifier "length". That means you can easily write foo.length = 'bar', and the world will keep turning. Only on arrays does it have its special nature.

现在,你可能期望时,当你延长阵列的构造函数,你得到一个数组,但这样做您?那么,在某种意义上,你做的:

Now, you might expect when when you extend the Array constructor, that you get an array—but do you? Well, in one sense you do:

class PushValuesArray extends Array
(new PushValuesArray) instanceof Array  # true

不幸的是,对于长度,你不这样做的目的。所有扩展关键词在这里所做的就是创建一个原型链,而阵列的原型的有一个明显的非魔法长度属性:

Unfortunately, for the purpose of length, you don't. All the extends keyword does here is create a prototype chain, and the Array prototype has a distinctly non-magical length property:

Array::length  # 0

这就是你得到你的 PushValues​​Array 实例。可悲的是,有没有办法复制在自己的对象长度魔法。你唯一的选择是要么写一个函数来代替(比如尺寸()),或修改阵列原型你想和使用真正的数组来代替的方法。

That's all you get on your PushValuesArray instance. Sadly, there's no way to duplicate that length magic on your own objects. Your only option is to either write a function instead (say, size()), or modify the Array prototype with the methods you want and use true arrays instead.

要总结:子类化阵列不会让你很远这就是为什么,例如,jQuery有一个非常类似数组。其对象API -

To sum up: Subclassing Array won't get you very far. That's why, for instance, jQuery has a very array-like API on its objects—

$('body').length  # 1
$('body')[0]      # [object HTMLBodyElement]

- 但实际上并没有使这些对象从数组原型继承:

—but doesn't actually make those objects inherit from the Array prototype:

$('body') instanceof Array  # false

这篇关于为什么设置阵列中的一个子类不会改变其长度位置?我不应该继承阵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 16:04