var pObj = document.getElementsByTagName('p');
console.log( [].slice.call(pObj) ); // 返回数组形式[p,p,p]
console.log( pObj.slice() ); // Error
我的疑问:
1.两个slice
方法中的this
是不是都是指向的pObj
?
2.正因为typeof pObj
是object
类型,所以不具备slice
方法,正如第二个中的error
。但是它又像数组所以可以采用第一种方法,理解的对吗?
3.如果上述两个我理解都对的话,其实slice
方法中的this
处理的是类数组,现在理解的对吗?
4.请大神一一指正。
1.
pObj
是一个 HTML 集合,也是一个类数组对象。Array.prototype.slice.call()
[].slice.call()
slice()
可以用来将类数组对象或者集合(比如上面的pObj
)转换为数组。只需要把slice()
方法绑定到要转换的类数组对象或者集合上即可。[].slice.call(pObj)
这就是一个转换数组的过程。2.
pObj.slice()
报错。看下面这个图,这个类数组对象(集合)没有
slice()
方法,当然报错。3.上述问题可忽略你对
this
的想法。建议重新理解一次this
关键字的应用。回答问题的时候刚好要出去,所以就截了个图示意了一下,没想到你没懂,哎。
pObj
是object没错,不过准确的说是HTMLCollection
对象HTMLCollection
对象中没有没有slice
方法(就是你说的不具备)。我上回就跟你说了,此slice
非彼slice
。你完全可以自己创建一个slice
方法啊。3.错误,
[1,2,3].slice(0,1)
中处理的就是数组,要看你具体处理的对象是什么。[].slice.call(pObj)
处理的才是伪数组。首先document.getElementsByTagName返回的结果并非array,而是
HTMLCollection
,可以通过document.getElementsByTagName('p').__proto__
查验因为
HTMLCollection
的原型里没有slice方法,所以pObj.slice
是undefined。如果给它赋值一个function,那么通过pObj.slice()
调用时,this就也会指向pObj
(问1)至于23,差不多对,本质是浏览器实现的
Array.prototype.slice
,包括数组的其他很多方法,是不局限于接受原生数组的,比如这里的HTMLCollection
,比如document.querySelectorAll
的NodeList
,还有函数里面的arguments
等实际上,chrome里面的
Array.prototype.slice
其实只看length属性和0,1,..这些属性