js原型和原型链你只要看这一篇

js原型和原型链你只要看这一篇一 什么是原型 任何对象都有一个原型对象 这个原型对象由对象的内置属性 proto 指向它的构造函数的 prototype 指向的对象 即任何对象都是由一个构造函数创建的 但是不是每一个对象都有 prototype 只有方法才有 prototype functionPers varp newPerson 方法才有 prototype 普通对象无 protot

一、原型概述

    任何对象都有一个原型对象,这个原型对象由对象的内置属性_proto_指向它的构造函数的prototyoe指向的对象,即任何对象都是由一个构造函数创建的,被创建的对象都可以获得构造函数的prototype属性,注意:对象是没有prototype属性,只有方法才有prototype属性。

    任何对象都有一个constructor属性,指向创建此对象的构造函数,比如说{}对象,它的构造函数是function Object(){}。

 

 function Person() { } var p = new Person(); //方法才有prototype,普通对象无prototype console.log(Person.prototype); // Object{} console.log(p.prototype); // undifined //任何对象都是有构造函数constructor,由构造函数创建的对象也可以获得构造函数的引用 //此处只是打印下列对象的构造函数是什么。 console.log(p.constructor); //function Person(){} console.log(Person.constructor); //function Function(){} console.log({}.constructor); // function Object(){} console.log(Object.constructor); // function Function() {} console.log([].constructor); //function Array(){} 

    那什么是构造函数呢?

    用function声明的都是函数,而如果直接调用的话,那么Person()就是一个普通函数,只有用函数new产生对象时,这个函数才是new出来对象的构造函数

二、创建对象的过程

    2.1 、声明方法的过程

    首先,当我们声明一个function关键字的方法时,会为这个方法添加一个prototype属性,指向默认的原型对象,并且此prototype的constructor属性就是此方法。此二个属性会在创建对象时被对象的属性引用。

 function Hello() { } console.log(Hello.prototype); // Object {} -- > 内部的constructor 指向Hello方法 console.log(Hello.prototype.constructor); // function Hello(){}

  2.2、创建一个对象,从构造函数继承了什么属性?

 console.log(h.constructor); // function Hello(){} console.log(Object.getPrototypeOf(h)==Hello.prototype); // true  备注:getPrototypeOf是获取_proto_ 

  我们惊喜的发现,new出来的对象,它的constructor指向了方法对象,它的_proto_和prototype相等。

  即new一个对象,它的_proto_属性指向了方法的prototype属性,并且constructor指向了prototype的constructor属性。

  由构造函数创建一个对象,此对象多了一个_proto_属性指向构造函数的prototype,一个constructor属性指向构造函数的prototype的constructor属性。

  2.3 、创建一个对象的过程

 function Hehe(name) { this.name = name; } var h = new Hehe("笑你妹"); //伪代码: function newObj(name){ var obj = {}; obj.__proto__ = Hehe.prototype; obj.constructor = Hehe.prototype.constructor; var result = Hehe.call(obj, name); return typeof result==='object'&& result!=null ? result : obj; //当无返回对象或默认时返回obj。 } var hh = newObj("笑你妹"); console.log(hh); console.log(h); //虽然hh!=h,但是可以看到这个hh就和h的结构一样了。

    过程:先创建一个空对象,设置一个_proto_指向方法的原型,设置constructor,用新对象做this指向方法,返回新对象。

2.4、总结

    从上面说明的过程中,我们发现只要是对象就是有构造函数来创建的,并且内部二个属性是从构造函数的prototype衍生的一个指向,而构造函数的prototype也是一个对象,那么它应该肯定也有一个构造函数,首先它是一个Object {} 对象,那么它的构造函数肯定是Object,所以就会有一个指针_proto_指向Object.prototype。最后Object.prototype因为没有_proto_,指向null,这样就构成了一个原型链。

js原型和原型链你只要看这一篇

    三、原型链分析

    什么是原型链?

    原型链的核心就是依赖对象的_proto_的指向,当自身不存在的属性时,就一层层的扒出创建对象的构造函数,直至到Object时,就没有_proto_指向了。

    如何分析原型链?

    因为_proto_实质找的是prototype,所以我们只要找这个链条上的构造函数的prototype。其中Object.prototype是没有_proto_属性的,等于null。

    3.1、最简单的原型链分析

 function Person(name){ this.name = name; } var p = new Person(); //p ---> Person.prototype --->Object.prototype---->null

     上面原型链的分析:p的构造函数是Person创建的,那么Person.prototype就是继承的第一个原型,而Person.prototype没有自定义设置,默认就是一个Object对象,即是Object构造函数创建的,那么就是继承了Object.prototype,而Object.prototype再往上就没有_proto_指向了,等于null

     3.2、原型继承

//原型继承的基本案例 function Person(name, age) { this.name = name; this.age = age; } //1.直接替换原型对象 var parent = { sayHello : function() { console.log("方式1:替换原型对象"); } } Person.prototype = parent; var p = new Person("张三", 50); p.sayHello(); //2.混入式原型继承 console.log(".............混入式原型继承.............."); function Student(name, age) { this.name = name; this.age = age; } var parent2 = { sayHello : function() { console.log("方式2:原型继承之混入式加载成员"); } } for ( var k in parent2) { Student.prototype[k] = parent2[k]; } var p = new Student("张三", 50); p.sayHello();

    3.3 原型链案例

// 查询原型链上的对象的方法 function findProtoType(obj) { var arr = []; while (obj != null) { obj = Object.getPrototypeOf(obj); arr.push(obj); } return arr; }; function Root() {} function Child() {} Child.prototype = new Root(); Child.prototype.constructor = Child; // 这个步骤是为了让原型对象打印显示成自身(继承prototype同时也继承了constructor,因此替换成自身) function Item() {} Item.prototype = new Child(); Item.prototype.constructor = Item; var result = findProtoType(new Item()); console.log(result); // [ Item { constructor: [Function: Item] },Child { constructor: [Function: Child] }, Root {}, {}, null ]

谢谢观看!

end!

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/227740.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午8:39
下一篇 2026年3月16日 下午8:39


相关推荐

  • python表白代码大全简单-python告白代码,只属于程序员的浪漫

    python表白代码大全简单-python告白代码,只属于程序员的浪漫不知何时,不知何因,程序员这个行业成为大家茶余饭后取乐的无辜群体。只要说到程序员,脑海中就浮现出刻板印象,标配穿搭:格子衫,牛仔裤,黑框眼镜。当然秃顶也是必须的,更狠的吐槽还有邋里邋遢,不懂浪漫,不知人情世故!开始可能只是幽默玩笑,后面慢慢就越传越多,大家便信以为真!可是程序员真的是这样吗?随着现在编程这个行业的普遍高薪收入,程序员又成为大家关注的焦点,深入的了解后,发现程序员其实是很可爱的一个群…

    2022年6月2日
    41
  • python 快速排序算法

    python 快速排序算法随机数快速排序 python 实现

    2026年3月17日
    1
  • Linux下干净卸载mysql详解

    Linux下干净卸载mysql详解1、使用以下命令查看当前安装mysql情况rpm-qa|grep-imysql可以看到如下图的所示:显示之前安装了:MySQL-client-5.5.25a-1.rhel5MySQL-server-5.5.25a-1.rhel52、停止mysql服务、删除之前安装的mysql删除命令:rpm-e–nodeps包名rpm-evMySQL

    2022年6月16日
    77
  • @Html.DropDownList[通俗易懂]

    @Html.DropDownList[通俗易懂]page@Html.DropDownList("ID",Model.SystemParameterList)ViewModel:publicIEnumerable<

    2022年7月2日
    39
  • Windows如何删除MySql服务

    Windows如何删除MySql服务在CMD里输入一跳命令就可以将服务删除:scdeletemysql//这里的mysql是你要删除的服务名

    2022年6月24日
    31
  • java中containsKey方法

    java中containsKey方法java 中 containsKey 方法 判断 map 中是否有 keyif map containKey key map put key 1 没有则把 key 存入 map 中

    2026年3月18日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号