<script src="./javascripts/x3dom/jquery-3.7.1.min.js"></script>
function enter(){
var data = [["apple","orange","lemon"],{name: "taro", occupation: "singer"}];
var hoge = data;
data[0].splice(1,0,"tomato");
console.log(JSON.stringify(data));//[["apple","tomato","orange","lemon"],{"name":"taro","occupation":"singer"}]
console.log(JSON.stringify(hoge));//[["apple","tomato","orange","lemon"],{"name":"taro","occupation":"singer"}]
var hage = structuredClone(data);
data[1]["nation"] = "japan";
console.log(JSON.stringify(data));//[["apple","tomato","orange","lemon"],{"name":"taro","occupation":"singer","nation":"japan"}]
console.log(JSON.stringify(hoge));//[["apple","tomato","orange","lemon"],{"name":"taro","occupation":"singer","nation":"japan"}]
console.log(JSON.stringify(hage));//[["apple","tomato","orange","lemon"],{"name":"taro","occupation":"singer"}]
var numdata = {value: 1};
console.log(JSON.stringify(numdata));//{"value":1}
console.log(numdata);//{"value":666}
numdata["value"] = 666;
enter2();
}
let defprp = {name: "Taro", nation: "Japan"};
class Person {
constructor(p = defprp) {
this.property = structuredClone(p);
}
clone() {
return new Person(this.property);
}
greet() {
return `Hello, I'm ${this.property.name}.`;
}
}
function enter2(){
const originalPerson = new Person({name: "Jiro", nation: "Japan", score: 95});
const clonedPerson = originalPerson.clone();
originalPerson.property.score = 100;
console.log(clonedPerson.property.score);//95
console.log(clonedPerson instanceof Person);//true
console.log(clonedPerson.greet());//Hello, I'm Jiro.
const taro = new Person({name: "Taro"});
const jiro = new Person({name: "Jiro"});
Person.prototype.sing = function(song) {
return `${this.property.name} is singing "${song}".`;
};
console.log(taro.sing("Happy Birthday")); // "Taro is singing "Happy Birthday"."
console.log(jiro.sing("Twinkle Star")); // "Jiro is singing "Twinkle Star"."
enter3();
}
const Person2defaultProperties = {
profile: { name: "Default Name", age: 25 },
settings: { theme: "light", notifications: true }
};
class Person2 {
constructor(p) {
this.property = $.extend(true, {}, Person2defaultProperties, p);
}
clone() {
return new Person2(this.property);
}
merge(p){
this.property = $.extend(true, {}, this.property, p);
return this;
}
greet() {
return `Hello, I'm ${this.property.profile.name}.`;
}
}
const taroData = {
variablename: "taroData",
profile: { name: "Taro", nation: "Japan", items: {0: "ball", 1: "glove"} },
settings: { theme: "red" }
};
/*
itemsにmapやfilterを使いたい場合には配列として
const taroData = {
profile: { name: "Taro", nation: "Japan", items: ["ball", "glove"] },
settings: { theme: "red" }
};
こうしてね
*/
const jiroData = {
variablename: "jiroData",
profile: { name: "Jiro", nation: "Japan" },
settings: { theme: "dark" }
};
const zakoData = {
variablename: "zakoData",
profile: { name: "Zako", nation: "Japan" },
settings: { theme: "blue" }
};
Person2.prototype.sing = function(song) {
return `${this.property.profile.name} is singing "${song}".`;
};
function enter3(){
const taro = new Person2(taroData);
const jiro = new Person2().merge(jiroData);
console.log(taro.property);
/*
taro.property = {
profile: { age: 25, items: {0: 'ball', 1: 'glove'}, name: "Taro", nation: "Japan" },
settings: { notifications: true, theme: "red" }
};
*/
console.log(jiro.property);
/*
jiro.property = {
profile: {age: 25, name: "Jiro", nation: "Japan" },
settings: {notifications: true, theme: "dark" }
};
*/
console.log(taro.sing("Happy Birthday")); // "Taro is singing "Happy Birthday"."
console.log(jiro.sing("Twinkle Star")); // "Jiro is singing "Twinkle Star"."
enter4();
}
/**
* MyManagedClassの結果はオブジェクトとして返されるが、配列型が必要な場合はtoArrayIfIndexedを使用。
* 例: const items = toArrayIfIndexed(instance.property.profile.items, true);
*/
/**
* MyManagedClassは配列をオブジェクトとして処理します。
* 配列型が必要な場合、toArrayIfIndexedを使用して変換してください。
* 例:
* const instance = new MyManagedClass({ items: [{ id: 1 }, { id: 2 }] });
* const itemsArray = toArrayIfIndexed(instance.property.items, true); // [{ id: 1 }, { id: 2 }]
// 配列プロパティの取得
const instance = new MyManagedClass({ profile: { items: [{ id: 1 }, { id: 2 }] } });
const items = toArrayIfIndexed(instance.property.profile.items, true);
items.forEach(item => console.log(item.id)); // 1, 2
// トップレベルが配列
const arrayInstance = new MyManagedClass([{ id: 1 }, { id: 2 }]);
const array = toArrayIfIndexed(arrayInstance.property, true);
console.log(array); // [{ id: 1 }, { id: 2 }] */
/**
* 数字文字列のキーを持つオブジェクトを配列に整形する
* @param {Object} obj - 変換対象のオブジェクト
* @param {boolean} [force=false] - キーが数字文字列でない場合も強制的に配列に変換
* @param {String} [sparseHandling = 'keep'] - 空白配列のコンパクト化の選択
* @returns {Array|Object} 配列(変換可能な場合)または元のオブジェクト
*/
function toArrayIfIndexed(obj, force = false, sparseHandling = 'keep') {
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return obj;
const keys = Object.keys(obj);
const isIndexed = keys.every((key, i) => String(i) === key);
if (!isIndexed && !force && process.env.NODE_ENV !== 'production') {
console.warn('Non-sequential keys detected; consider using force=true or sparseHandling="compact"');
}
const maxIndex = keys.length > 0 ? Math.max(...keys.map(Number)) + 1 : 0;
const result = new Array(maxIndex);
for (const key of keys) {
result[Number(key)] = obj[key];
}
if (sparseHandling === 'compact') {
return result.filter(x => x !== undefined);
}
return result;
}
// フォールバック用の簡易クローン関数
function fallbackClone(item, seen = new WeakSet()) {
if (item === null || typeof item !== 'object') return item;
if (seen.has(item)) {
throw new Error('Circular reference detected in fallbackClone');
}
seen.add(item);
if (typeof item.clone === 'function') {
return item.clone();
}
if (Array.isArray(item)) return item.map(item => fallbackClone(item, seen));
if (item instanceof Date) return new Date(item);
if (item instanceof Map) return new Map(fallbackClone([...item], seen));
if (item instanceof Set) return new Set(fallbackClone([...item], seen));
if (item instanceof RegExp) return new RegExp(item);
const cloned = {};
for (const key in item) {
cloned[key] = fallbackClone(item[key], seen);
}
return cloned;
}
// 安全なstructuredCloneラッパー
function safeStructuredClone(item) {
try {
return structuredClone(item);
} catch (e) {
return fallbackClone(item);
}
}
function recursiveClone(item, seen = new WeakSet()) {
// 循環参照のチェック
if (item && typeof item === 'object' && seen.has(item)) {
throw new Error('Circular reference detected');
}
if (item && typeof item === 'object') {
seen.add(item);
}
// 1. clone() メソッドを持つ場合
if (item && typeof item.clone === 'function') {
return item.clone();
}
// 2. 配列の場合
if (Array.isArray(item)) {
return item.map(element => recursiveClone(element, seen));
}
// 3. プレーンなオブジェクトの場合
if (item && typeof item === 'object' && item.constructor === Object) {
const clonedObject = {};
for (const key in item) {
clonedObject[key] = recursiveClone(item[key], seen);
}
return clonedObject;
}
// 4. その他(プリミティブ値など)
return safeStructuredClone(item);
}
function simpleDeepMerge(target, source, seen = new WeakSet(), deep = true) {
if (!deep) {
return Object.assign({}, target, source);
}
// ターゲットが有効なオブジェクトであることを確認
// ターゲットがオブジェクトでなければ、ソースをディープコピーして返す(上書き)
if (target === null || typeof target !== 'object') {
// ターゲットが無効な場合、処理を継続する意味がないので、ソースをそのまま返すか、safeStructuredCloneを使う
return safeStructuredClone(source);
}
// ソースが有効なオブジェクトであることを確認
if (source === null || typeof source !== 'object') {
return target; // マージするものがないため、ターゲットをそのまま返す
}
// 1. 循環参照チェックと登録
// この層での処理が確定したら登録
if (seen.has(target) || seen.has(source)) {
throw new Error('Circular reference detected');
}
seen.add(target);
seen.add(source);
// 配列をオブジェクトに変換するヘルパー関数
const arrayToObject = arr => ({ ...arr });
if (Array.isArray(target) && process.env.NODE_ENV !== 'production') {
console.warn('Target array converted to object in simpleDeepMerge. Use toArrayIfIndexed to convert back.');
}
// 配列処理の統一: 配列はすべてインデックス付きのプレーンなオブジェクトとして扱う
if (Array.isArray(target)) {
// targetはマージのターゲットであり、型を維持するため、新しいオブジェクトに変換
// 既存の target の内容を維持しつつ、オブジェクトとしてマージするために、新しいオブジェクトを作る
target = Object.assign({}, target);
}
if (Array.isArray(source)) {
source = arrayToObject(source);
}
// 2. マージロジック
for (const key in source) {
const sourceValue = source[key];
const targetValue = target[key];
// ターゲットの値がオブジェクトで、ソースの値もオブジェクトの場合にのみ再帰する
if (sourceValue && typeof sourceValue === 'object' && sourceValue.constructor === Object) {
// ターゲットの値がオブジェクトでなければ、新しい空のオブジェクトで初期化
if (!targetValue || typeof targetValue !== 'object' || Array.isArray(targetValue)) {
target[key] = {};
}
// 配列をオブジェクトとして扱うため、ここでは Array.isArray(targetValue) のチェックは削除しても良いが、
// ターゲットが配列として存在していた場合は既に Object.assign({}, target) でオブジェクトになっているはず
simpleDeepMerge(target[key], sourceValue, seen); // 再帰
} else if (typeof sourceValue?.clone === 'function') {
// カスタムクラスは clone() で上書き
target[key] = sourceValue.clone();
} else {
// プリミティブ、その他のオブジェクトは safeStructuredClone でディープコピーして上書き
target[key] = safeStructuredClone(sourceValue);
}
}
return target;
}
function enter4(){
// 使用例: 複数の型とネスト構造を持つ配列
const nestedHoge = [
new Person2(taroData),
['a', ['b', new Person2(jiroData)]],
{ x: 1, y: 2 }
];
const clonedHage = recursiveClone(nestedHoge);
nestedHoge[1][0] = 'changed';
console.log(nestedHoge);
/*
const nestedHoge = [
new Person2(taroData),
['cahnged', ['b', new Person2(jiroData)]],
{ x: 1, y: 2 }
];
*/
console.log(clonedHage);
/*
const clonedHage = [
new Person2(taroData),
['a', ['b', new Person2(jiroData)]],
{ x: 1, y: 2 }
];
*/
const personMap = {
leader: new Person2(taroData),
member: {
subleader: new Person2(jiroData),
bench: new Person2(zakoData)
}
};
const clonedPM = recursiveClone(personMap);
const tmpP = personMap.leader.clone();
personMap.leader = personMap.member.bench.clone();
personMap.member.bench = tmpP.clone();
console.log(personMap);
/*
const personMap = {
leader: new Person2(zakoData),
member: {
subleader: new Person2(jiroData),
bench: new Person2(taroData)
}
};
*/
console.log(clonedPM);
/*
const clonedPM = {
leader: new Person2(taroData),
member: {
subleader: new Person2(jiroData),
bench: new Person2(zakoData)
}
};
*/
enter5();
}
const MyManagedClassDefaultProperty = Object.freeze({
variablename: "MyManagedClassDefaultProperty",
profile: Object.freeze({ name: "Default Name", age: 25 }),
settings: Object.freeze({ theme: "light", notifications: true })
});
class MyManagedClass {
constructor(p, deep = true) {
if(deep) {
const target = recursiveClone(MyManagedClassDefaultProperty);
this.property = simpleDeepMerge(target, p);
}
else {
this.property = Object.assign({}, MyManagedClassDefaultProperty, p);
}
}
clone() {
return new MyManagedClass(this.property);
}
merge(p, deep = true) {
// 1. コピー先のベースとなるプロパティを決定する
let baseProperty;
if (deep) {
// ディープコピーしてからマージするために、まず自身のpropertyをディープコピーする
baseProperty = recursiveClone(this.property);
// 2. 新しいプロパティオブジェクト (baseProperty) に新しいデータ (p) をディープマージする
// (simpleDeepMergeがターゲットをインプレイスで更新すると仮定)
simpleDeepMerge(baseProperty, p);
} else {
// シャローマージ: Object.assignでthis.propertyのシャローコピーにpのプロパティを上書き
baseProperty = Object.assign({}, this.property, p);
}
// 3. 不変性を維持するため、新しいプロパティを持つ新しいインスタンスを返す
return new MyManagedClass(baseProperty, deep);
}
isThisType(rh){
return rh instanceof MyManagedClass;
}
toString(){
try {
// JSON.stringify(データ, リプレイサー, スペース数)
// スペース数に「2」を指定することで、JSONは2スペースでインデントされます。
const jsonString = JSON.stringify(this.property, null, 2);
// JSON文字列の各行の先頭に、カスタムヘッダーに合わせたインデント(ここでは2スペース)を追加
// 最初の中括弧{は除く
const indentedJson = jsonString.split('\n')
.map((line, index) => (index > 0 ? ' ' : '') + line)
.join('\n');
// ヘッダーと整形されたJSONを結合
if(this.property.variablename) return `MyManagedClass Instance (${this.property.variablename}) {\n "property": ${indentedJson}\n}`;
else return `MyManagedClass Instance {\n "property": ${indentedJson}\n}`;
} catch (e) {
// 循環参照などが含まれる場合の処理
return `MyManagedClass Instance [Serialization Error: ${e.message}]`;
}
}
//ここにそのほかのメソッドを記述
}
function enter5(){
const data = new MyManagedClass(taroData);
const elm = document.getElementById('TDATA');
elm.value = data.toString();
console.log(data.toString());
/*
MyManagedClass Instance (taroData) {
"property": {
"variablename": "taroData",
"profile": {
"name": "Taro",
"age": 25,
"nation": "Japan",
"items": {
"0": "ball",
"1": "glove"
}
},
"settings": {
"theme": "red",
"notifications": true
}
}
}
*/
const MyManagedClassMap = {
leader: new MyManagedClass(taroData),
member: {
subleader: new MyManagedClass(jiroData),
bench: new MyManagedClass(zakoData)
}
};
const clonedMM = recursiveClone(MyManagedClassMap);
const tmpM = MyManagedClassMap.leader.clone();
MyManagedClassMap.leader = MyManagedClassMap.member.bench.clone();
MyManagedClassMap.member.bench = tmpM.clone();
console.log(MyManagedClassMap);
/*
const MyManagedClassMap = {
leader: new MyManagedClass(zakoData),
member: {
subleader: new MyManagedClass(jiroData),
bench: new MyManagedClass(taroData)
}
};
*/
console.log(clonedMM);
/*
const clonedPM = {
leader: new MyManagedClass(taroData),
member: {
subleader: new MyManagedClass(jiroData),
bench: new MyManagedClass(zakoData)
}
};
*/
}
/**
//################################################################################################################################
* MyManagedClass : マネージドクラスの模倣クラスのクラステンプレート
* MyManagedClass.property にクラスのデータを一括管理させる
* ディープ/シャローマージ対応
* マージするときに配列をオブジェクトに自動変換します(キーの衝突/結合の複雑さの回避)
* 配列にしたい場合はfunction toArrayIfIndexed(obj, force = false, sparseHandling = 'keep')を
* 逐次利用してください
* 注意:MyManagedClass.property の要素にMyManagedClass自身を含めると循環参照の危険があり避けてください
*/
/**
* MyManagedClassの結果はオブジェクトとして返されるが、配列型が必要な場合はtoArrayIfIndexedを使用。
* 例: const items = toArrayIfIndexed(instance.property.profile.items, true);
*/
/**
* MyManagedClassは配列をオブジェクトとして処理します。
* 配列型が必要な場合、toArrayIfIndexedを使用して変換してください。
* 例:
* const instance = new MyManagedClass({ items: [{ id: 1 }, { id: 2 }] });
* const itemsArray = toArrayIfIndexed(instance.property.items, true); // [{ id: 1 }, { id: 2 }]
// 配列プロパティの取得
const instance = new MyManagedClass({ profile: { items: [{ id: 1 }, { id: 2 }] } });
const items = toArrayIfIndexed(instance.property.profile.items, true);
items.forEach(item => console.log(item.id)); // 1, 2
// トップレベルが配列
const arrayInstance = new MyManagedClass([{ id: 1 }, { id: 2 }]);
const array = toArrayIfIndexed(arrayInstance.property, true);
console.log(array); // [{ id: 1 }, { id: 2 }] */
/**
* 数字文字列のキーを持つオブジェクトを配列に整形する
* @param {Object} obj - 変換対象のオブジェクト
* @param {boolean} [force=false] - キーが数字文字列でない場合も強制的に配列に変換
* @param {String} [sparseHandling = 'keep'] - 空白配列のコンパクト化の選択
* @returns {Array|Object} 配列(変換可能な場合)または元のオブジェクト
*/
function toArrayIfIndexed(obj, force = false, sparseHandling = 'keep') {
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return obj;
const keys = Object.keys(obj);
const isIndexed = keys.every((key, i) => String(i) === key);
if (!isIndexed && !force && process.env.NODE_ENV !== 'production') {
console.warn('Non-sequential keys detected; consider using force=true or sparseHandling="compact"');
}
const maxIndex = keys.length > 0 ? Math.max(...keys.map(Number)) + 1 : 0;
const result = new Array(maxIndex);
for (const key of keys) {
result[Number(key)] = obj[key];
}
if (sparseHandling === 'compact') {
return result.filter(x => x !== undefined);
}
return result;
}
// フォールバック用の簡易クローン関数
function fallbackClone(item, seen = new WeakSet()) {
if (item === null || typeof item !== 'object') return item;
if (seen.has(item)) {
throw new Error('Circular reference detected in fallbackClone');
}
seen.add(item);
if (typeof item.clone === 'function') {
return item.clone();
}
if (Array.isArray(item)) return item.map(item => fallbackClone(item, seen));
if (item instanceof Date) return new Date(item);
if (item instanceof Map) return new Map(fallbackClone([...item], seen));
if (item instanceof Set) return new Set(fallbackClone([...item], seen));
if (item instanceof RegExp) return new RegExp(item);
const cloned = {};
for (const key in item) {
cloned[key] = fallbackClone(item[key], seen);
}
return cloned;
}
// 安全なstructuredCloneラッパー
function safeStructuredClone(item) {
try {
return structuredClone(item);
} catch (e) {
return fallbackClone(item);
}
}
function recursiveClone(item, seen = new WeakSet()) {
// 循環参照のチェック
if (item && typeof item === 'object' && seen.has(item)) {
throw new Error('Circular reference detected');
}
if (item && typeof item === 'object') {
seen.add(item);
}
// 1. clone() メソッドを持つ場合
if (item && typeof item.clone === 'function') {
return item.clone();
}
// 2. 配列の場合
if (Array.isArray(item)) {
return item.map(element => recursiveClone(element, seen));
}
// 3. プレーンなオブジェクトの場合
if (item && typeof item === 'object' && item.constructor === Object) {
const clonedObject = {};
for (const key in item) {
clonedObject[key] = recursiveClone(item[key], seen);
}
return clonedObject;
}
// 4. その他(プリミティブ値など)
return safeStructuredClone(item);
}
function simpleDeepMerge(target, source, seen = new WeakSet(), deep = true) {
if (!deep) {
return Object.assign({}, target, source);
}
// ターゲットが有効なオブジェクトであることを確認
// ターゲットがオブジェクトでなければ、ソースをディープコピーして返す(上書き)
if (target === null || typeof target !== 'object') {
// ターゲットが無効な場合、処理を継続する意味がないので、ソースをそのまま返すか、safeStructuredCloneを使う
return safeStructuredClone(source);
}
// ソースが有効なオブジェクトであることを確認
if (source === null || typeof source !== 'object') {
return target; // マージするものがないため、ターゲットをそのまま返す
}
// 1. 循環参照チェックと登録
// この層での処理が確定したら登録
if (seen.has(target) || seen.has(source)) {
throw new Error('Circular reference detected');
}
seen.add(target);
seen.add(source);
// 配列をオブジェクトに変換するヘルパー関数
const arrayToObject = arr => ({ ...arr });
if (Array.isArray(target) && process.env.NODE_ENV !== 'production') {
console.warn('Target array converted to object in simpleDeepMerge. Use toArrayIfIndexed to convert back.');
}
// 配列処理の統一: 配列はすべてインデックス付きのプレーンなオブジェクトとして扱う
if (Array.isArray(target)) {
// targetはマージのターゲットであり、型を維持するため、新しいオブジェクトに変換
// 既存の target の内容を維持しつつ、オブジェクトとしてマージするために、新しいオブジェクトを作る
target = Object.assign({}, target);
}
if (Array.isArray(source)) {
source = arrayToObject(source);
}
// 2. マージロジック
for (const key in source) {
const sourceValue = source[key];
const targetValue = target[key];
// ターゲットの値がオブジェクトで、ソースの値もオブジェクトの場合にのみ再帰する
if (sourceValue && typeof sourceValue === 'object' && sourceValue.constructor === Object) {
// ターゲットの値がオブジェクトでなければ、新しい空のオブジェクトで初期化
if (!targetValue || typeof targetValue !== 'object' || Array.isArray(targetValue)) {
target[key] = {};
}
// 配列をオブジェクトとして扱うため、ここでは Array.isArray(targetValue) のチェックは削除しても良いが、
// ターゲットが配列として存在していた場合は既に Object.assign({}, target) でオブジェクトになっているはず
simpleDeepMerge(target[key], sourceValue, seen); // 再帰
} else if (typeof sourceValue?.clone === 'function') {
// カスタムクラスは clone() で上書き
target[key] = sourceValue.clone();
} else {
// プリミティブ、その他のオブジェクトは safeStructuredClone でディープコピーして上書き
target[key] = safeStructuredClone(sourceValue);
}
}
return target;
}
const MyManagedClassDefaultProperty = Object.freeze({
variablename: "MyManagedClassDefaultProperty",
profile: Object.freeze({ name: "Default Name", age: 25 }),
settings: Object.freeze({ theme: "light", notifications: true })
});
class MyManagedClass {
constructor(p, deep = true) {
if(deep) {
const target = recursiveClone(MyManagedClassDefaultProperty);
this.property = simpleDeepMerge(target, p);
}
else {
this.property = Object.assign({}, MyManagedClassDefaultProperty, p);
}
}
clone() {
return new MyManagedClass(this.property);
}
merge(p, deep = true) {
// 1. コピー先のベースとなるプロパティを決定する
let baseProperty;
if (deep) {
// ディープコピーしてからマージするために、まず自身のpropertyをディープコピーする
baseProperty = recursiveClone(this.property);
// 2. 新しいプロパティオブジェクト (baseProperty) に新しいデータ (p) をディープマージする
// (simpleDeepMergeがターゲットをインプレイスで更新すると仮定)
simpleDeepMerge(baseProperty, p);
} else {
// シャローマージ: Object.assignでthis.propertyのシャローコピーにpのプロパティを上書き
baseProperty = Object.assign({}, this.property, p);
}
// 3. 不変性を維持するため、新しいプロパティを持つ新しいインスタンスを返す
return new MyManagedClass(baseProperty, deep);
}
isThisType(rh){
return rh instanceof MyManagedClass;
}
toString(){
try {
// JSON.stringify(データ, リプレイサー, スペース数)
// スペース数に「2」を指定することで、JSONは2スペースでインデントされます。
const jsonString = JSON.stringify(this.property, null, 2);
// JSON文字列の各行の先頭に、カスタムヘッダーに合わせたインデント(ここでは2スペース)を追加
// 最初の中括弧{は除く
const indentedJson = jsonString.split('\n')
.map((line, index) => (index > 0 ? ' ' : '') + line)
.join('\n');
// ヘッダーと整形されたJSONを結合
if(this.property.variablename) return `MyManagedClass Instance (${this.property.variablename}) {\n "property": ${indentedJson}\n}`;
else return `MyManagedClass Instance {\n "property": ${indentedJson}\n}`;
} catch (e) {
// 循環参照などが含まれる場合の処理
return `MyManagedClass Instance [Serialization Error: ${e.message}]`;
}
}
//ここにそのほかのメソッドを記述
}
const taroData = {
variablename: "taroData",
profile: { name: "Taro", nation: "Japan", items: {0: "ball", 1: "glove"} },
settings: { theme: "red" }
};
const jiroData = {
variablename: "jiroData",
profile: { name: "Jiro", nation: "Japan" },
settings: { theme: "dark" }
};
const zakoData = {
variablename: "zakoData",
profile: { name: "Zako", nation: "Japan" },
settings: { theme: "blue" }
};
function enter5(){
const data = new MyManagedClass(taroData);
const elm = document.getElementById('TDATA');
elm.value = data.toString();
console.log(data.toString());
/*
MyManagedClass Instance (taroData) {
"property": {
"variablename": "taroData",
"profile": {
"name": "Taro",
"age": 25,
"nation": "Japan",
"items": {
"0": "ball",
"1": "glove"
}
},
"settings": {
"theme": "red",
"notifications": true
}
}
}
*/
const MyManagedClassMap = {
leader: new MyManagedClass(taroData),
member: {
subleader: new MyManagedClass(jiroData),
bench: new MyManagedClass(zakoData)
}
};
const clonedMM = recursiveClone(MyManagedClassMap);
const tmpM = MyManagedClassMap.leader.clone();
MyManagedClassMap.leader = MyManagedClassMap.member.bench.clone();
MyManagedClassMap.member.bench = tmpM.clone();
console.log(MyManagedClassMap);
/*
const MyManagedClassMap = {
leader: new MyManagedClass(zakoData),
member: {
subleader: new MyManagedClass(jiroData),
bench: new MyManagedClass(taroData)
}
};
*/
console.log(clonedMM);
/*
const clonedPM = {
leader: new MyManagedClass(taroData),
member: {
subleader: new MyManagedClass(jiroData),
bench: new MyManagedClass(zakoData)
}
};
*/
}