型判定の実装
const typeMapping = {};
const typeString = typeMapping.toString;
const Z = {};
function getType(value) {
return value == null ? String(value) : typeMapping[typeString.call(value)] || "object";
}
function checkObject(value) {
return getType(value) == "object";
}
function checkPlainObject(value) {
return checkObject(value) && !isWindow(value) &&
Object.getPrototypeOf(value) === Object.prototype;
}
function checkArray(value) {
return Array.isArray(value) || value instanceof Array;
}
extend関数の仕組み
Zeptoの拡張機能では、まず内部で使用されるextend関数が定義されています。この関数は3つのパラメータを受け取ります:target, source, deep。targetは拡張対象のオブジェクト、sourceは拡張元のオブジェクト、deepは深い拡張を行うかどうかを示します。
extend関数では、深い拡張が指定された場合でも再帰関数を通じて拡張が行われ、最終的にはtarget[key] = source[key]という形でプロパティが設定されます。違いは拡張の深さにあります。
浅い拡張の例
const obj1 = {
name: "original",
data: {
name: "nested",
alias: "old"
}
};
// 浅い拡張
extend(obj1, {name: "new", data: {name: "updated", data: {name: "deep"}}});
console.log(obj1);
deepパラメータを使用しない場合、オブジェクトの第一階層のプロパティのみが直接拡張・上書きされます。
深い拡張の例
// 深い拡張
extend(obj1, {name: "new", data: {name: "updated", data: {name: "deep"}}}, true);
console.log(obj1);
深い拡張を使用すると、元のオブジェクト内の対応する値が変更されずに、ネストされたオブジェクトも適切に拡張されます。
$.extendの機能
$.extendは外部から使用可能な拡張関数で、$オブジェクトに直接定義されています。Zeptoのプラグイン拡張は$.extendを通さなくてもZeptoオブジェクトに追加できます。これはZeptoのdom.__proto__ = $.fn, zepto.Z.prototype = $.fnという設計と、$が返されるためです。
$.extend関数は内部でargumentsを使用しているため、パラメータ数に制限はありません。深い拡張を行いたい場合は、最初のパラメータをtrueに設定します。
複数オブジェクトの浅い拡張
const obj2 = $.extend(obj1,
{name: "first", data: {name: "nested1", data: {name: "deep1"}}},
{name: "second"}
);
console.log(obj2);
複数オブジェクトの深い拡張
const obj3 = $.extend(true, obj1,
{name: "first", data: {name: "nested1", data: {name: "deep1"}}},
{name: "second", data: {name: "nested2"}}
);
console.log(obj3);