1: h 函数
1: h 函数会返回一个vnode 节点; vnode 是一个对象;
2: 函数的重载的, 就是一个函数有多种用法, 可以传递多个参数
// 也就是说, 调用函数的时候形态必须是以下三种形态之一:
// 第一: h('div', {}, '');
// 第二: h('div', {}, []);
// 第三: h('div', {}, h());
export default function (sel, data, c) { // c: 代表第三个参数
// 检查参数的个数
if(argumnets.length !==3 ) {
throw new Error('h函数必须传入三个参数, 这是低配的h 函数')
}
// 检参参数c 的类型
if(typeof c == 'string' || typeof c == 'number') {
// 现在调用h 函数是第一种
return vnode(sel, data, undefined, c, undefined );
}else if (Array.isArray(c)) {
// 说明现在调用h 函数是第二种
// 便利c 参数c 是数组
for(let i=0; i<c.length; i++) {
// 检测c[i] 必须是一个对象, 如果不满足
let children = [];
if(!(typeof c[i] =='object' && c[i].hasOwnProperty('sel'))) {
throw new Error('传入的数组参数中有项不是h 函数');
// 这里如果不用执行c[i], 因为你的测试语句中已经有了执行
// 此时只需要收集好就可以了
children.push(c[i]);
}
// 循环结束了, 就说明children 收集完毕了, 此时可以返回虚拟节点了, 它有children 属性
return vnode(sel, data, children, undefined, undefined);
}
}else if(typeof c == 'object' && c.hasOwnProperty('sel')) { // 并且有sel 属性
// 说明现在调用的是h函数第三种
即是传入的c 是唯一的children, 不用执行c, 因为测试语句中已经执行了
let children = [c];
return vnode(sel, data, children, undefined, undefined);
}else {
throw new Error('传入的第三个参数类型不正确')
}
}