2026/4/17 23:24:19
网站建设
项目流程
企业品牌文化建设学习网站,seo裤子的关键词首页排名有哪些,怎么做app网站ui原型,小程序源码无需服务器手写 instanceof#xff1a;从原型链里揪出 血缘关系#x1f50d; #x1f468;#x1f469;#x1f467;#x1f466;
一、回顾原型、原型对象和原型链
在 JavaScript 的世界里#xff0c;“原型” 这东西就像个神秘的族谱#xff0c;藏着对象们的…手写 instanceof从原型链里揪出 血缘关系 一、回顾原型、原型对象和原型链在 JavaScript 的世界里“原型” 这东西就像个神秘的族谱藏着对象们的家族关系。要搞懂 instanceof得先扒开这层神秘面纱1.什么是原型先看三个 “老熟人”prototype、__proto__和constructor。prototype是构造函数的 “专属名片”。比如function Animal() {}这个 Animal 构造函数身上就挂着prototype属性指向一个原型对象相当于给未来的 “子孙后代” 准备的 基因库。__proto__则是实例对象的 “寻根指针”。当我们用new创建实例时比如const dog new Dog()dog 身上就有个__proto__偷偷指向构造函数的prototype。就像刚出生的小狗天生就知道自己的 基因来源constructor是原型对象上的 “认亲暗号”。每个原型对象都有constructor属性指向它对应的构造函数。比如Dog.prototype.constructor就指向 Dog相当于原型对象在说“我是 Dog 家的基因库”2.核心关联规则 —— 原型链这些小家伙们串起来就形成了原型链。看下面的代码javascriptconst arr []; console.log(arr.__proto__ Array.prototype); // arr.__proto__指向Array.prototype console.log(arr.__proto__.__proto__ Object.prototype); // true console.log(arr.__proto__.__proto__.__proto__); // null数组 arr 的__proto__指向 Array 的原型Array 原型的__proto__又指向 Object 的原型Object 原型的__proto__是 null—— 这就是一条完整的原型链像链条一样一环扣一环直到尽头。二、instanceof 介绍1.instanceof 是什么instanceof就像 JavaScript 里的 “亲子鉴定师”专门判断一个对象是不是某个构造函数的 “后代”包括直接后代和间接后代。看下面的代码javascriptPerson.prototype new Animal(); const p new Person(); console.log(p instanceof Person); // true console.log(p instanceof Animal); // truep 是 Person 的直接实例同时也是 Animal 的间接实例因为 Person 继承了 Animal所以两次判断都是 true。2.instanceof 有什么作用它的核心作用是检测对象的原型链判断左边的对象实例的原型链上是否存在右边构造函数的prototype。简单说就是“你家族谱里有没有这个老祖宗”3.基于什么需求创造的 instanceof在大型项目里多人协作时经常会遇到 “这对象到底是谁家的” 的灵魂拷问。比如你拿到一个dog对象想知道它能不能调用Animal的方法这时instanceof就能告诉你“它是 Animal 家的后代能调用” 就像团队协作时先搞清楚每个人的 “所属部门”才好分配任务呀三、手写 instanceof明白了原理咱们也来当回 “亲子鉴定师”手写一个instanceof1.手写代码展示废话不多说直接上代码:javascriptfunction insInstanceOf(left, right) { // 拿实例的__proto__当起点 let proto left.__proto__; // 顺着原型链一路找 while(proto) { // 找到构造函数的prototype就认亲成功 if(proto right.prototype) { return true; } // 没找到就继续往上爬 proto proto.__proto__; } // 爬到顶了还没找到就是外人 return false; }验证一下我们手搓的instanceof有没有bugjavascriptfunction Animal() {} function Cat() {} Cat.prototype new Animal(); function Dog() {} Dog.prototype new Animal(); const dog new Dog(); console.log(insInstanceOf(dog,Dog)); // true直接后代 console.log(insInstanceOf(dog,Animal)); // true间接后代 console.log(insInstanceOf(dog,Object)); // true所有对象都继承Object console.log(insInstanceOf(dog,Cat)); // false猫和狗不是一家结果和原生instanceof一模一样说明咱们的 “亲子鉴定师” 很称职2.手写代码的详细解释起点设置let proto left.__proto__—— 从实例的原型指针开始找就像查族谱从 “本人” 开始翻。循环遍历while(proto)—— 只要还没到原型链尽头proto 不为 null就继续找。核心判断if(proto right.prototype)—— 如果当前原型就是构造函数的原型说明是 “自家人”返回 true。继续向上proto proto.__proto__—— 没找到就往上翻一代相当于 “查爸爸的爸爸”。终点处理循环结束还没找到返回 false——“查遍了族谱确实没这号亲戚”。这里有个小细节为什么用let声明proto而不是const因为proto需要不断更新往上爬原型链const声明的变量不能重新赋值呀四、面试官会问instanceof 和 typeof 有啥区别typeof 是 “粗略分类”比如typeof []返回 “object”啥也分不清而 instanceof 是 “精细认亲”能准确判断[] instanceof Array为 true。null 和 undefined 用 instanceof 会怎样会返回 false因为它们没有__proto__原型链都不存在自然谈不上 后代手写 instanceof 时为什么要比较 prototype 而不是构造函数本身因为实例的原型链上挂的是构造函数的prototype而不是构造函数本身。比如dog.__proto__指向Dog.prototype而不是 Dog 函数原型链的终点是什么是 null就像族谱查到最早的老祖宗再往上就没人啦arr.__proto__.__proto__.__proto__返回 null。五、结语搞定instanceof的关键其实是吃透原型链这个 “家族族谱”。从prototype到__proto__从直接实例到间接继承这些概念环环相扣想要搞定这些知识点可以看看我稀土掘金社区介绍原型、原型对象和原型链的文章吃透 JS 原型从构造函数到原型链一篇讲透核心逻辑JS原型是其面向对象的灵魂以“委托”而非传统血缘实现继承以及讲解原型继承的文章原型继承不翻车一个空函数如何拯救了父子关系从 call/apply 的“灵魂传送”到原型链的“共享陷阱”。下次再遇到 “这对象到底啥来头” 的问题不妨心里默念“让我顺着原型链康康” 实在不行就把咱们手写的insInstanceOf掏出来保准能理清所有 血缘关系最后友情提示面试被问手写 instanceof 时可别光顾着写代码把原型链的原理讲清楚才是加分项哦