问题描述
在下面的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
这就是你得到你的 PushValuesArray
实例。可悲的是,有没有办法复制在自己的对象长度
魔法。你唯一的选择是要么写一个函数来代替(比如尺寸()
),或修改阵列
原型你想和使用真正的数组来代替的方法。
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
这篇关于为什么设置阵列中的一个子类不会改变其长度位置?我不应该继承阵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!