最近在重写web核心库文件(基于React),预期新框架开发模式上贴近小程序原生架构(开发性一致),组件操作便利性贴近JQUERY。
JQUERY有一个非常方便的特性即元素查找,能够返回一个JQUERY封装的对象,是一个类数组对象,可以批量处理查找到的所有元素及定义一系列的方法,新框架中需要用到这样的元素查找能力。
什么是类数组对象
看下面的列子
function test(){
console.log(arguments[0]) // a
console.log(arguments[1]) // b
console.log(arguments.length) // 2
console.log(argument)
}
test('a', 'b')
arguments既是一个类数组,再看一个JQUERY的例子
上例是JQUERY元素查找的结果,总结一下什么是类数组
一个类数组对象:
- 具有:指向对象元素的数字索引下标以及 length 属性告诉我们对象的元素个数
- 默认不具有:诸如 push 、 forEach 以及 indexOf 等数组对象具有的方法
这里说明默认不具有Array的方法,当然可以通过一些操作使其能够使用Array的方法
如何构建类数组
let obj = {}
obj[0] = '...'
obj[1] = '...'
obj.length = 2
这就是一个很基础的类数组,是不是很简单,打印一下
接下来让他与jquery更接近一点
let obj = {}
obj[0] = '...'
obj[1] = '...'
obj.length = 2
obj.splice = function(){}
上面这个打印就与jquery基本一致了,它不是一个数组,但又具有数组的一些特性。
其实上面的打印是一个console.log的bug,设置了
splice的对象,打印效果和数组是一样一样的,但其实它仍是对象
接下来我们为该对象绑定一些数组方法及自定义方法
let obj = {}
obj[0] = '加油,'
obj[1] = '川建国,'
obj.length = 2
obj.forEach = [].forEach
obj.push = [].push
obj.join = function(){
let str = ''
this.forEach(item=>{
str+=item
})
return str
}
obj.push('注意安全')
let mystr = obj.join() // 加油,川建国,注意安全
join是自定义方法,forEach/push是借用了Array的原生方法。
通过上例发现能够很简单的构建一个类数组对象,只是平时很少会用到,类数组的好处是可以很方便的处理集合数据,能够自由的为该对象指定array方法及自定义方法。
定义原型链方法
上面例子中都是显示指定方法,打印的时候总是不那么完美,观察jqurey的例子,扩展方法都是定义在 原型链上,因此我们也要定义原型链方法,以求达到完美
prototype和__proto__
下面一段文字摘自这里,个人觉得很清晰的概述了这两者的不同,因此我们需要使用__proto__(es6版本)来定义原型链方法
prototype是函数才有的属性
具体原因,可以看看阮一峰大神的这篇文章Javascript继承机制的设计思想,里面介绍了prototype的设计由来。
__proto__是每个对象都有的属性
它不是一个规范属性,虽然一些浏览器目前仍然支持它。__proto__属性已在ES6中标准化,现在更推荐使用Object.getPrototypeOf/Reflect.getPrototypeOf和和Object.setPrototypeOf/Reflect.setPrototypeOf。
let obj = {}
obj[0] = '加油,'
obj[1] = '川建国,'
obj.length = 2
// 开始定义原型链方法
Object.setPrototypeOf(obj, {
splice: [].splice,
push: [].push,
forEach: [].forEach,
join: function(){
let str = ''
this.forEach(item=>{
str+=item
})
return str
}
})
console.log(obj)
完工!