JavaScript 原型和原型链

张开发
2026/4/18 18:24:58 15 分钟阅读

分享文章

JavaScript 原型和原型链
文章目录JavaScript 原型和原型链概述原型Prototype对象的隐式原型函数的显式原型关系原型链Prototype Chain原型链的查找机制new的执行过程instanceof用法原理原理伪代码属性判断hasOwnProperty()inJavaScript 原型和原型链概述内存效率方法定义在原型上所有实例共享节省内存动态性可以在运行时修改原型所有实例立即生效继承机制实现对象之间的继承关系代码复用避免重复定义相同的方法原型Prototype在 JavaScript 中每个对象在创建时都会关联另一个对象这个关联的对象就是原型。每个对象都会从原型继承属性和方法。对象的隐式原型每个对象都有一个隐式原型可以通过__proto__属性和Object.getPrototypeOf()访问。constobj{}console.log(obj.__proto__)console.log(Object.getPrototypeOf(obj))函数的显式原型每个构造函数都有一个显式原型可以通过prototype属性访问用于共享属性和方法。functionPerson(name){this.namename}Person.prototype.sayHellofunction(){console.log(hello,${this.name})}constp1newPerson(小明)constp2newPerson(小华)p1.sayHello()// hello, 小明p2.sayHello()// hello, 小华console.log(p1.sayHellop2.sayHello)// trueconsole.log(p1.__proto__Person.prototype)// true关系__proto__属于对象指向他的构造函数的 prototypeprototype属于函数用于实例继承functionPerson(){}constpersonnewPerson();console.log(person.__proto__Person.prototype)// trueconsole.log(Person.prototype.__proto__Object.prototype)// trueconsole.log(Person.__proto__Function.prototype)// trueconstobj{}console.log(obj.__proto__Object.prototype)// trueconstfunc(){}console.log(func.__proto__Function.prototype)// true原型链Prototype Chain原型链是 JavaScript 实现继承的核心机制。每个对象都有一个内部属性__proto__指向他的原型对象。原型对象也有自己的原型这样层层链接形成原型链。原型链的终点是 null。functionPerson(){}constpersonnewPerson()console.log(person.__proto__Person.prototype)// trueconsole.log(Person.prototype.__proto__Object.prototype)// trueconsole.log(Object.prototype.__proto__null)// trueconsole.log(Person.__proto__Function.prototype)// trueconsole.log(Function.prototype.__proto__Object.prototype)// trueconsole.log(Object.__proto__Function.prototype)// true原型链的查找机制当访问对象的属性或方法时JavaScript 会按照以下顺序查找先查找自身如果没有找到则沿着__proto__向上查找继续向上查找直到顶端 null如果整个原型链都没有找到则返回 undefinedfunctionPerson(name){this.namename;}Person.prototype.sayHellofunction(){console.log(${this.name}hello!!!);}functionXiaoMing(name,age){Person.call(this,name);// 继承this.ageage;}// 原型链继承XiaoMing.prototypenewPerson();XiaoMing.prototype.constructorXiaoMing;XiaoMing.prototype.runfunction(){console.log(跑步)}constxiaomingnewXiaoMing(小明,18)xiaoming.run();// 跑步在 XiaoMing.prototytpe上找到xiaoming.sayHello();// 小明 hello!!!在 Person.prototype上找到console.log(xiaoming.toString())// [object Object]在Object.prototype上找到// xiaoming.hahaha() // 报错原型链上没找到new的执行过程functionmyNew(constructor,...args){// 1.创建一个空对象constobj{}// 2.将空对象的原型指向构造函数的 prototypeobj.__proto__constructor.prototype;// 3.执行构造函数this 指向新对象constresultconstructor.apply(obj,args);// 4.如果构造函数返回对象则返回该对象否则返回新对象return(typeofresultobjectresult!null)?result:obj}functionPerson(name){this.namename;}constpersonmyNew(Person,Tom)console.log(person.name);// Tominstanceof用法instanceof是用于检测对象是否属于该类型。functionFn(){}constfnnewFn();console.log(fninstanceofFn);// trueconsole.log(fninstanceofString);// falseconsole.log(fninstanceofObject);// true原理obj instanceof Type其原理是判断Type类型的原型对象是否在obj对象的原型链上。functionFn(){}constfn1newFn();constfn2newFn();consto1newObject();consto2newObject();console.log(FninstanceofFunction);// trueconsole.log(FninstanceofObject);// trueconsole.log(ObjectinstanceofFunction);// trueconsole.log(ObjectinstanceofObject);// trueconsole.log(FunctioninstanceofFunction);// trueconsole.log(FunctioninstanceofObject);// trueconsole.log(fn1instanceofFn);// trueconsole.log(fn1instanceofFunction);// falseconsole.log(fn1instanceofObject);// trueconsole.log(o1instanceofObject);// trueconsole.log(o1instanceofFunction);// false说明根据上图的解构先找到对象的原型链上的所有原型对象再查看类型的原型对象如果又则返回true否则返回false。原理伪代码functionmyInstanceof(obj,constructor){// 如果obj为null或undefined直接返回falseif(objnull||objundefined){returnfalse;}// 获取对象的原型letprotoObject.getPrototypeOf(obj);// 获取构造函数的prototype对象letprototypeconstructor.prototype;// 递归查找原型链while(true){// 找到原型链末端返回falseif(protonull){returnfalse;}// 找到匹配的原型返回trueif(protoprototype){returntrue;}// 继续在原型链上查找protoObject.getPrototypeOf(proto);}}属性判断hasOwnProperty()hasOwnProperty() 用于判断属性是否属于对象自身。varperson{name:Alice};console.log(person.hasOwnProperty(name));// trueconsole.log(person.hasOwnProperty(toString));// falseinin 操作符用于判断属性是否属于对象自身以及原型链。varperson{name:Alice};console.log(nameinperson);// trueconsole.log(toStringinperson);// true

更多文章