Add checkIfInstanceOf (LeetCode 2618) with TypeScript prototype chain…#236
Conversation
… analysis - Add JavaScript and TypeScript implementations of Check if Object Instance of Class - Include checkIfInstanceOf function with primitive value support - Implement prototype chain traversal using isPrototypeOf() - Add type-safe strictCheckIfInstanceOf variant with type guard - Document V8 optimization strategies and performance considerations - Add comprehensive documentation and visualizations - Include flowchart and data flow diagrams with Mermaid - Add detailed edge case analysis and FAQ section - Provide complexity analysis (O(d) time, O(1) space) - Include interactive React-based README visualization
📝 WalkthroughSummary by CodeRabbitリリースノート
✏️ Tip: You can customize this high-level summary in your review settings. 概要LeetCode問題2618「オブジェクトがクラスのインスタンスであるかチェック」の包括的なドキュメンテーションと実装例を提供する4つのファイルを追加します。JavaScriptとTypeScriptの実装、詳細なREADME、およびReactベースのビジュアライゼーションが含まれます。 変更内容
推定コードレビュー工数🎯 3 (Moderate) | ⏱️ ~25 分 ポエム
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Fix all issues with AI agents
In `@JavaScript/2618`. Check if Object Instance of Class/Claude Code Sonnet
4.5/Check_if_Object_Instance_of_Class_JS.ipynb:
- Around line 396-418: The "recommended submission" block contains the same
inverted isPrototypeOf logic in checkIfInstanceOf (e.g., using
Number.prototype.isPrototypeOf(classFunction.prototype)), which yields incorrect
results (e.g., checkIfInstanceOf(5, Object)); either remove this erroneous
snippet or mark it explicitly as a "wrong implementation example" and replace it
with the correct logic shown later in the notebook (use the
classFunction.prototype.isPrototypeOf(...) or the corrected branch logic in the
"問題分析と修正" section); update references to the checkIfInstanceOf function and the
Number.prototype.isPrototypeOf / String.prototype.isPrototypeOf /
Boolean.prototype.isPrototypeOf occurrences accordingly so the notebook no
longer presents the buggy code as the recommended solution.
- Around line 300-337: The primitive-specific fast-path in checkIfInstanceOf is
using isPrototypeOf backwards (e.g., the t === 'number' branch uses
Number.prototype.isPrototypeOf(classFunction.prototype)); fix it by replacing
those checks with the correct prototype check (use
classFunction.prototype?.isPrototypeOf(obj) or remove the primitive-specific
branches and fall back to the single canonical check) so that the function
consistently uses classFunction.prototype.isPrototypeOf(obj) for determining
instances; update the t === 'number' / 'string' / 'boolean' branches (and any
symbol/bigint handling) to use the corrected pattern or drop them and rely on
the general return in checkIfInstanceOf.
In `@JavaScript/2618`. Check if Object Instance of Class/Claude Code Sonnet
4.5/Check_if_Object_Instance_of_Class_TS.ipynb:
- Around line 198-221: You have two declarations with the same name: the
function declaration checkIfInstanceOf and the later var checkIfInstanceOf; pick
one approach—either remove the duplicate var declaration and export the single
function, or rename the var declaration (e.g., checkIfInstanceOfVar) and update
exports accordingly so both can be exported with unique names; locate and modify
the symbols function checkIfInstanceOf and var checkIfInstanceOf and adjust the
export statements to match the chosen name(s).
In `@JavaScript/2618`. Check if Object Instance of Class/Claude Code Sonnet
4.5/README_react.html:
- Around line 1686-1712: The useEffect references stepsData.length but stepsData
is not in the dependency array, causing stale reads or unnecessary re-renders;
fix by either adding stepsData (or a stable derived value like stepsData.length)
to the dependency array of the useEffect that manages timerRef and isPlaying, or
memoize stepsData with useMemo where it’s defined and then include that memoized
variable in the dependency array so useEffect correctly reacts to changes;
symbols to look for: useEffect (the effect body checking activeStep and
stepsData.length), timerRef, isPlaying, activeStep, and the stepsData definition
(wrap with useMemo or include stepsData/stepsData.length in the effect deps).
- Around line 1199-1201: The HTML currently loads React development builds via
the script tags referencing react.development.js and react-dom.development.js;
for production replace those script sources with the corresponding production
minified builds (react.production.min.js and react-dom.production.min.js) so the
page uses the optimized runtime instead of the development runtime (update the
two script src attributes that reference React and ReactDOM in the snippet);
ensure any tooling that requires the development build (e.g., `@babel/standalone`)
is intentionally kept or removed for production deployment.
- Line 1840: ReactDOM.render is deprecated in React 18; replace the call to
ReactDOM.render(<App />, document.getElementById('react-root')) by importing and
using createRoot from 'react-dom/client', create a root with
createRoot(document.getElementById('react-root')), then call root.render(<App
/>) (references: ReactDOM.render, createRoot, root.render,
document.getElementById('react-root')).
In `@JavaScript/2618`. Check if Object Instance of Class/Claude Code Sonnet
4.5/README.md:
- Around line 280-299: The file declares two functions with the same name —
function checkIfInstanceOf and var checkIfInstanceOf — which can cause confusion
or shadowing; resolve this by distinguishing the examples: rename the
LeetCode-style variant (var checkIfInstanceOf) to a distinct identifier such as
checkIfInstanceOfLeetCode (or move it into a clearly labeled README example
block), update any references/tests accordingly, and add a short comment above
each declaration clarifying which variant it is (standard vs LeetCode
submission) so both implementations can coexist without name collisions.
| "Wrong Answer\n", | ||
| "305 / 311 testcases passed\n", | ||
| "LeetCode環境では以下のアプローチが最速です:\n", | ||
| "\n", | ||
| "```javascript\n", | ||
| "'use strict';\n", | ||
| "\n", | ||
| "/**\n", | ||
| " * 値が指定されたクラスまたはスーパークラスのインスタンスかチェック(最適化版)\n", | ||
| " * \n", | ||
| " * @param {*} obj - チェック対象の値\n", | ||
| " * @param {*} classFunction - クラスコンストラクタ\n", | ||
| " * @return {boolean}\n", | ||
| " * \n", | ||
| " * 時間計算量: O(d)\n", | ||
| " * 空間計算量: O(1)\n", | ||
| " */\n", | ||
| "function checkIfInstanceOf(obj, classFunction) {\n", | ||
| " // 最速の早期リターン\n", | ||
| " if (obj == null || typeof classFunction !== 'function') return false;\n", | ||
| " \n", | ||
| " // プリミティブの型チェック(型判定一回で済ます)\n", | ||
| " const t = typeof obj;\n", | ||
| " \n", | ||
| " // プリミティブ専用の高速パス\n", | ||
| " if (t === 'number') return classFunction === Number || Number.prototype.isPrototypeOf(classFunction.prototype);\n", | ||
| " if (t === 'string') return classFunction === String || String.prototype.isPrototypeOf(classFunction.prototype);\n", | ||
| " if (t === 'boolean') return classFunction === Boolean || Boolean.prototype.isPrototypeOf(classFunction.prototype);\n", | ||
| " if (t === 'symbol') return classFunction === Symbol;\n", | ||
| " if (t === 'bigint') return classFunction === BigInt;\n", | ||
| " \n", | ||
| " // オブジェクト/関数: isPrototypeOf を活用\n", | ||
| " // これが最も高速(V8 の組み込み最適化)\n", | ||
| " return classFunction.prototype?.isPrototypeOf(obj) ?? false;\n", | ||
| "}\n", | ||
| "\n", | ||
| "module.exports = { checkIfInstanceOf };\n", | ||
| "```\n", |
There was a problem hiding this comment.
誤った isPrototypeOf ロジックが「超高速」としてマークされている
このセクションは「Wrong Answer 305/311 testcases passed」と記載されていますが、コードブロック自体が誤解を招く可能性があります。
// 間違い (lines 325-329)
if (t === 'number') return classFunction === Number || Number.prototype.isPrototypeOf(classFunction.prototype);この isPrototypeOf の使い方は逆です。Number.prototype.isPrototypeOf(classFunction.prototype) は「Number.prototype が classFunction.prototype のプロトタイプチェーンに存在するか」をチェックしますが、本来必要なのは「classFunction.prototype が obj のプロトタイプチェーンに存在するか」です。
ノートブックの後半で正しく修正されていますが、読者が誤ったパターンをコピーしないよう、このセクションにより明確な警告を追加することを検討してください。
🤖 Prompt for AI Agents
In `@JavaScript/2618`. Check if Object Instance of Class/Claude Code Sonnet
4.5/Check_if_Object_Instance_of_Class_JS.ipynb around lines 300 - 337, The
primitive-specific fast-path in checkIfInstanceOf is using isPrototypeOf
backwards (e.g., the t === 'number' branch uses
Number.prototype.isPrototypeOf(classFunction.prototype)); fix it by replacing
those checks with the correct prototype check (use
classFunction.prototype?.isPrototypeOf(obj) or remove the primitive-specific
branches and fall back to the single canonical check) so that the function
consistently uses classFunction.prototype.isPrototypeOf(obj) for determining
instances; update the t === 'number' / 'string' / 'boolean' branches (and any
symbol/bigint handling) to use the corrected pattern or drop them and rely on
the general return in checkIfInstanceOf.
| "```javascript\n", | ||
| "'use strict';\n", | ||
| "\n", | ||
| "/**\n", | ||
| " * @param {*} obj\n", | ||
| " * @param {*} classFunction\n", | ||
| " * @return {boolean}\n", | ||
| " */\n", | ||
| "var checkIfInstanceOf = function(obj, classFunction) {\n", | ||
| " if (obj == null || typeof classFunction !== 'function') return false;\n", | ||
| " \n", | ||
| " const t = typeof obj;\n", | ||
| " if (t === 'number') return classFunction === Number || Number.prototype.isPrototypeOf(classFunction.prototype);\n", | ||
| " if (t === 'string') return classFunction === String || String.prototype.isPrototypeOf(classFunction.prototype);\n", | ||
| " if (t === 'boolean') return classFunction === Boolean || Boolean.prototype.isPrototypeOf(classFunction.prototype);\n", | ||
| " if (t === 'symbol') return classFunction === Symbol;\n", | ||
| " if (t === 'bigint') return classFunction === BigInt;\n", | ||
| " \n", | ||
| " return classFunction.prototype?.isPrototypeOf(obj) ?? false;\n", | ||
| "};\n", | ||
| "```\n", | ||
| "\n", | ||
| "このコードで **Runtime 上位20-30%** に入ることが期待できます!" |
There was a problem hiding this comment.
「推奨する提出コード」にも同じバグが含まれている
Lines 408-414 の「推奨する提出コード」ブロックにも、先ほどと同じ isPrototypeOf の逆転ロジックが含まれています。
if (t === 'number') return classFunction === Number || Number.prototype.isPrototypeOf(classFunction.prototype);この実装は checkIfInstanceOf(5, Object) のようなケースで誤った結果を返します(Number.prototype.isPrototypeOf(Object.prototype) は false を返すため)。
ノートブック後半の「問題分析と修正」セクション(lines 426以降)で正しい実装が提供されているため、このセクションは削除するか、明確に「誤った実装例」としてマークすることを推奨します。
🤖 Prompt for AI Agents
In `@JavaScript/2618`. Check if Object Instance of Class/Claude Code Sonnet
4.5/Check_if_Object_Instance_of_Class_JS.ipynb around lines 396 - 418, The
"recommended submission" block contains the same inverted isPrototypeOf logic in
checkIfInstanceOf (e.g., using
Number.prototype.isPrototypeOf(classFunction.prototype)), which yields incorrect
results (e.g., checkIfInstanceOf(5, Object)); either remove this erroneous
snippet or mark it explicitly as a "wrong implementation example" and replace it
with the correct logic shown later in the notebook (use the
classFunction.prototype.isPrototypeOf(...) or the corrected branch logic in the
"問題分析と修正" section); update references to the checkIfInstanceOf function and the
Number.prototype.isPrototypeOf / String.prototype.isPrototypeOf /
Boolean.prototype.isPrototypeOf occurrences accordingly so the notebook no
longer presents the buggy code as the recommended solution.
| "// LeetCode提出用エクスポート\n", | ||
| "export { checkIfInstanceOf };\n", | ||
| "\n", | ||
| "/**\n", | ||
| " * LeetCode フォーマット(var 宣言)\n", | ||
| " */\n", | ||
| "\n", | ||
| "// Analyze Complexity\n", | ||
| "// Runtime 70 ms\n", | ||
| "// Beats 64.02%\n", | ||
| "// Memory 63.97 MB\n", | ||
| "// Beats 30.37%\n", | ||
| "\n", | ||
| "var checkIfInstanceOf = function(obj: unknown, classFunction: unknown): boolean {\n", | ||
| " if (obj == null || typeof classFunction !== 'function') {\n", | ||
| " return false;\n", | ||
| " }\n", | ||
| " \n", | ||
| " if (typeof obj !== 'object' && typeof obj !== 'function') {\n", | ||
| " obj = Object(obj);\n", | ||
| " }\n", | ||
| " \n", | ||
| " return (classFunction as AnyFunction).prototype?.isPrototypeOf(obj as object) ?? false;\n", | ||
| "};\n", |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
同じ名前の関数が2回宣言されている
Lines 155-196 で function checkIfInstanceOf として宣言された後、lines 211-221 で var checkIfInstanceOf として再宣言されています。
これはノートブックのドキュメント目的としては問題ありませんが、実際の TypeScript ファイルにエクスポートする場合は、どちらか一方を選択するか、名前を変えて両方エクスポートすることを検討してください。
// 例: 両方をエクスポートする場合
export { checkIfInstanceOf };
export { checkIfInstanceOfVar }; // var 版に別名を付ける🤖 Prompt for AI Agents
In `@JavaScript/2618`. Check if Object Instance of Class/Claude Code Sonnet
4.5/Check_if_Object_Instance_of_Class_TS.ipynb around lines 198 - 221, You have
two declarations with the same name: the function declaration checkIfInstanceOf
and the later var checkIfInstanceOf; pick one approach—either remove the
duplicate var declaration and export the single function, or rename the var
declaration (e.g., checkIfInstanceOfVar) and update exports accordingly so both
can be exported with unique names; locate and modify the symbols function
checkIfInstanceOf and var checkIfInstanceOf and adjust the export statements to
match the chosen name(s).
| <script src="https://unpkg.com/react@18/umd/react.development.js"></script> | ||
| <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> | ||
| <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
本番環境では React の development ビルドを避けるべき
開発用ビルドが使用されています:
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>このファイルがドキュメント/デモ目的であれば問題ありませんが、本番環境で使用する場合は .production.min.js バージョンを使用してください。Development ビルドには追加の警告とチェックが含まれており、パフォーマンスに影響します。
🤖 Prompt for AI Agents
In `@JavaScript/2618`. Check if Object Instance of Class/Claude Code Sonnet
4.5/README_react.html around lines 1199 - 1201, The HTML currently loads React
development builds via the script tags referencing react.development.js and
react-dom.development.js; for production replace those script sources with the
corresponding production minified builds (react.production.min.js and
react-dom.production.min.js) so the page uses the optimized runtime instead of
the development runtime (update the two script src attributes that reference
React and ReactDOM in the snippet); ensure any tooling that requires the
development build (e.g., `@babel/standalone`) is intentionally kept or removed for
production deployment.
| const [activeStep, setActiveStep] = useState(1); | ||
| const [isPlaying, setIsPlaying] = useState(false); | ||
| const timerRef = useRef(null); | ||
|
|
||
| useEffect(() => { | ||
| if (isPlaying) { | ||
| // 最終ステップに到達したら次のタイマーで停止してStep 1に戻る | ||
| if (activeStep > stepsData.length) { | ||
| setIsPlaying(false); | ||
| setActiveStep(1); | ||
| return; | ||
| } | ||
|
|
||
| timerRef.current = setTimeout(() => { | ||
| // 最終ステップの次はStep 1に戻る | ||
| if (activeStep === stepsData.length) { | ||
| setActiveStep(1); | ||
| setIsPlaying(false); | ||
| } else { | ||
| setActiveStep((prev) => prev + 1); | ||
| } | ||
| }, 2000); | ||
| } | ||
| return () => { | ||
| if (timerRef.current) clearTimeout(timerRef.current); | ||
| }; | ||
| }, [isPlaying, activeStep]); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
stepsData が依存配列に含まれていない
useEffect フック内で stepsData.length を参照していますが、依存配列に stepsData が含まれていません。
useEffect(() => {
// stepsData.length を使用
if (activeStep > stepsData.length) { ... }
if (activeStep === stepsData.length) { ... }
}, [isPlaying, activeStep]); // stepsData が欠落stepsData はコンポーネント内で定義されているため、レンダリングごとに新しい配列が作成されます。依存配列に追加するか、stepsData を useMemo でメモ化することを検討してください。
♻️ 修正案
+ const stepsData = useMemo(() => [
+ {
+ step: 1,
+ title: '入力と型確認',
+ // ... rest of steps
+ },
+ // ... other steps
+ ], []);
- }, [isPlaying, activeStep]);
+ }, [isPlaying, activeStep, stepsData]);🤖 Prompt for AI Agents
In `@JavaScript/2618`. Check if Object Instance of Class/Claude Code Sonnet
4.5/README_react.html around lines 1686 - 1712, The useEffect references
stepsData.length but stepsData is not in the dependency array, causing stale
reads or unnecessary re-renders; fix by either adding stepsData (or a stable
derived value like stepsData.length) to the dependency array of the useEffect
that manages timerRef and isPlaying, or memoize stepsData with useMemo where
it’s defined and then include that memoized variable in the dependency array so
useEffect correctly reacts to changes; symbols to look for: useEffect (the
effect body checking activeStep and stepsData.length), timerRef, isPlaying,
activeStep, and the stepsData definition (wrap with useMemo or include
stepsData/stepsData.length in the effect deps).
| ); | ||
| } | ||
|
|
||
| ReactDOM.render(<App />, document.getElementById('react-root')); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
React 18 では ReactDOM.render は非推奨
React 18 では ReactDOM.render は非推奨となり、createRoot API を使用することが推奨されています。
♻️ 修正案
- ReactDOM.render(<App />, document.getElementById('react-root'));
+ const root = ReactDOM.createRoot(document.getElementById('react-root'));
+ root.render(<App />);現在のコードでも動作しますが、コンソールに deprecation warning が表示されます。
🤖 Prompt for AI Agents
In `@JavaScript/2618`. Check if Object Instance of Class/Claude Code Sonnet
4.5/README_react.html at line 1840, ReactDOM.render is deprecated in React 18;
replace the call to ReactDOM.render(<App />,
document.getElementById('react-root')) by importing and using createRoot from
'react-dom/client', create a root with
createRoot(document.getElementById('react-root')), then call root.render(<App
/>) (references: ReactDOM.render, createRoot, root.render,
document.getElementById('react-root')).
| /** | ||
| * LeetCode提出用フォーマット(var 宣言 + アロー関数) | ||
| * TypeScript strict mode 対応版 | ||
| */ | ||
| var checkIfInstanceOf = function (obj: unknown, classFunction: unknown): boolean { | ||
| // 早期リターン: null/undefined または classFunction が関数でない | ||
| if (obj == null || typeof classFunction !== 'function') { | ||
| return false; | ||
| } | ||
|
|
||
| // プリミティブはボックス化 | ||
| if (typeof obj !== 'object' && typeof obj !== 'function') { | ||
| obj = Object(obj); | ||
| } | ||
|
|
||
| // Optional Chaining + Nullish Coalescing で安全に処理 | ||
| // ?. により prototype が undefined の場合は undefined を返す | ||
| // ?? により undefined の場合は false を返す | ||
| return (classFunction as AnyFunction).prototype?.isPrototypeOf(obj as object) ?? false; | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
同一ファイル内で同名関数の重複宣言
function checkIfInstanceOf (lines 231-278) と var checkIfInstanceOf (lines 284-299) が同じファイル内で宣言されています。
ドキュメント目的として両方のスタイルを示すのは理解できますが、実際のコードファイルでは混乱を招く可能性があります。README では明確に「LeetCode提出用の代替形式」として区別するか、異なる関数名を使用することを検討してください。
// 例: 明確な区別
// 標準形式
function checkIfInstanceOf(...) { ... }
// LeetCode 提出用(別名または同一ファイルに含めない)
var checkIfInstanceOfLeetCode = function(...) { ... };🤖 Prompt for AI Agents
In `@JavaScript/2618`. Check if Object Instance of Class/Claude Code Sonnet
4.5/README.md around lines 280 - 299, The file declares two functions with the
same name — function checkIfInstanceOf and var checkIfInstanceOf — which can
cause confusion or shadowing; resolve this by distinguishing the examples:
rename the LeetCode-style variant (var checkIfInstanceOf) to a distinct
identifier such as checkIfInstanceOfLeetCode (or move it into a clearly labeled
README example block), update any references/tests accordingly, and add a short
comment above each declaration clarifying which variant it is (standard vs
LeetCode submission) so both implementations can coexist without name
collisions.
… analysis
Add JavaScript and TypeScript implementations of Check if Object Instance of Class
Add comprehensive documentation and visualizations