javascript怎么实现range函数

JavaScript013

javascript怎么实现range函数,第1张

range = (start,end,step)=>Array.from({length:Math.ceil((end-start)/step.toFixed(2))},(e,i)=>start+i*step)

var sel = window.getSelection(), range

if (sel.getRangeAt && sel.rangeCount) {

    range = sel.getRangeAt(0)

    range.deleteContents()

    var el = document.createElement("div")

    el.innerHTML = "<ul><li>\u200B</li></ul>"    //\u200B为空文本节点,否则光标定位有问题

    var frag = document.createDocumentFragment(), node, lastNode

    //你这里可以不要创建el这个元素,这里是为了防止插入的html不规范而写的。

    while ((node = el.firstChild)) {

        lastNode = frag.appendChild(node)

    }

    range.insertNode(frag)

    if (lastNode) {

        range = range.cloneRange()

        range.endContainer = lastNode

        range.startContainer = lastNode

        range.startOffset = 0

        range.endOffset = 0

        range.collapse(true)

        sel.removeAllRanges()

        sel.addRange(range)

    }

}

这里的代码不兼容IE9以下。

很早以前我就知道可以把

arguments

转化为数组:[].slice.call(arguments),因为

arguments

是个类数组对象,所以才可以这么用。但是我一直不清楚什么叫做类数组对象(

array-like

objects)

今天看

Effective

JavaScript

就有一节是专门讲这个的,感觉真是太拽了。

先看我写的一些示例代码:

复制代码

代码如下:

a

=

"hello"

[].map.call(a,

(e)

->

e.toUpperCase())

#

=>

[

'H',

'E',

'L',

'L',

'O'

]

[].reduceRight.call(a,

(acc,

e)

->

acc

+

e)

#

=>

'olleh'

b

=

{1:

"a",

2:

"b",

4:

"c",

length:

6}

[].reduce.call(b,

(acc,

e)

->

acc

+

e)

#

=>

'abc'

前面那几个是操作字符串的,嗯,字符串也可以看成类数组对象。但是后面那个

b

对象居然

也是类数组对象。

看书上的解释:

复制代码

代码如下:

So

what

exactly

makes

an

object

“array-like”?

The

basic

contract

of

an

array

object

amounts

to

two

simple

rules.

It

has

an

integer

length

property

in

the

range

0...2^32

1.

The

length

property

is

greater

than

the

largest

index

of

the

object.

An

index

is

an

integer

in

the

range

0...2^32

2

whose

string

representation

is

the

key

of

a

property

of

the

object.

居然只有这两条简单的规则。

所以为什么

arguments,

字符串,和上面那个

b

对象可以看作类数组对象呢?

它们都有一个合法的

length

属性(0

2**32

-

1

之间的正整数)。

length

属性的值大于它们的最大索引(index)。

再举个例子:

复制代码

代码如下:

b

=

{1:

"a",

2:

"b",

4:

"c",

length:

3}

[].reduce.call(b,

(acc,

e)

->

acc

+

e)

#

=>

'ab'

嗯,就不对了,成了'ab'

了,因为违反了规则2:length

属性是3,

最大索引值是4要比

length

属性大了。所以表现的不正常了。

太强大了,好像只是定义了一个接口,只要符合这个接口,就可以利用数组的所有方法。

其实不是可以利用所有方法,Array.prototype.concat

是不能用的,因为它是把两个数组连接起来,你不是数组肯定是没法用它的。

还有一个小问题是,字符串创建以后是不可变的(immutable),所以你怎么折腾它都是不可变的。

但是这本书根本就没有解释为什么是符合这两个条件就可以看成类数组对象,另外这本书的作者

是那个什么

ECMAScript

委员会的成员,所以基本还是可信的。至于为什么符合这两个条件就可以看成是类数组对象,我也不知道,谷歌搜了半天也没看到什么合理的解释。

以上所述就是本文的全部内容了,希望大家能够喜欢。