百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

JS中原型链的理解

itomcoil 2025-02-28 16:08 40 浏览

在谈原型链之前,我们首先要了解自定义函数与 Function 之间是什么关系,而构造函数、原型和实例之间又存在什么千丝万缕的关系呢?其实,所有的函数都是 Function 的实例。在构造函数上都有一个原型属性 prototype,该属性也是一个对象;那么在原型对象上有一个 constructor 属性,该属性指向的就是构造函数;而实例对象上有一个 _proto_ 属性,该属性也指向原型对象,并且该属性不是标准属性,不可以用在编程中,该属性用于浏览器内部使用。

1    // _proto_
2 在函数里有一个属性prototype
3 由该函数创建的对象默认会连接到该属性上
4     //prototype 与 _proto_ 的关系
5 _proto_是站在对象角度来说的
6 prototype 是站在构造函数角度来说的

下面,我们来看图说话。

1、构造函数、原型和实例之间的关系

①+Object

了解这些之后,我们再来讨论什么是原型链。说白了,其实就是有限的实例对象和原型之间组成有限链,就是用来实现共享属性和继承的。下面,我们看代码说话。

 1    var obj = new Object;
 2 对象是有原型对象的
 3 原型对象也有原型对象 
 4    obj._proto_._proto_._proto_
 5 原型对象也有原型对象,对象的原型对象一直往上找,会找到一个null
 6 // 原型链示例
 7    var arr = ;
 8    arr -> Array.prototype ->Object.prototype -> null
 9    var o = new Object;
10    o -> Object.prototype -> null;
function Foo1{
   this.name1 = '1';
}
function Foo2{
   this.name2 = '2';
}
Foo2.prototype = new Foo1;
function Foo3{
   this.name = '3';
}
Foo3.prototype = new Foo2;
var foo3 = new Foo3;
console.dir(foo3);

接下来就是继承问题了。

2、继承

1)原型继承

 1  function Animal(name){
 2        this.name = name;
 3    }
 4    function Tiger(color){
 5        this.color = color;
 6    }
 7 //   var tiger = new Tiger('yellow');
 8 //   console.log(tiger.color);
 9 //   console.log(tiger.name);  //undefined
10 //      Tiger.prototype = new Animal('老虎');   //一种方式
11    Object.prototype.name = '大老虎';   //第二种方式
12         var tiger = new Tiger('yellow');
13         console.log(tiger.color);
14         console.log(tiger.name);

值得注意的是,这里存在两个主要的问题: ①它不方便给父级类型传递参数;②父级类型当中的引用类型被所有的实例共享

2)ES5 提供了Object.create 方法来实现继承

 1 ————做兼容
 2   //shim垫片
 3     function create(obj){
 4         if(Object.create){
 5 return Object.create(obj);
 6         }else{
 7 function Foo{}
 8 Foo.prototype = obj;
 9 return new Foo;
10         }
11     }

这种方法是ES5的新特性,其实就是复制继承。

3)拷贝继承

1 var obj = {};
2 obj.extend = function(obj){
3     for(var k in obj){
4       this[k] = obj[k];
5     }
6 }

4)借用构造函数继承

——被借用的构造函数中原型上的成员没有被借过来

 1 function Animal(name){
 2     this.name = name;
 3 }
 4 function Mouse(nickname){
 5     Animal.call(this,'老鼠');
 6     this.nickname = nickname;
 7 }
 8 var m = new Mouse('杰瑞');
 9 console.log(m.name);
10 console.log(m.nickname);

存在的问题:可以解决原型继承当中传参问题,但是父类型当中的原型对象上的成员(属性和方法)不能被继承到

5)组合继承

——prototype对象是有动态性的

 1 function Person(name){
 2    this.name = name;
 3 }
 4 Person.prototype.showName = function{
 5    console.log(this.name);
 6 }
 7 function Student(name,age){
 8    Person.call(this,name);
 9    this.age = age;
10 }
11 Student.prototype = new Person;
12 Student.prototype.contructor = Student;
13 Student.prototype.showAge = function{
14     console.log(this.age);
15 }
16 var stu = new Student('张三',12);
17 stu.showName;
18 stu.showAge;

【原型继承+借用构造函数继承】它的特点就是属性每个实例一份,方法共享

【小结】套用一句很粗暴的话,所谓原型链就是找妈的一种行为方式,就可以理解为人是人他妈生的,妖是妖他妈生的。原型链的核心其实就只有一个:属性共享和独立的控制,当你的对象实例需要独立的属性,所有做法的本质都是在对象实例里面创建属性。若不考虑太多,你大可以在Person里面直接定义你所需要独立的属性来覆盖掉原型的属性。总之,使用原型继承的时候,要对于原型中的属性要特别注意,因为他们都是牵一发而动全身的存在。现在最常用的方法是组合模式。

1、原型链

1)构造函数、原型和实例的关系

①构造函数都有一个属性prototype,这个属性是一个对象(Object的实例)

②原型对象prototype里面有一个constructor属性,该属性指向原型对象所属的构造函数

③实例对象都有一个_proto_属性,该属性也指向构造函数的原型对象,它是一个非标准属性,不可以用于编程,它是用于浏览器自己使用的

2)prototype与_proto_的关系

①prototype是构造函数的属性

②_proto_是实例对象的属性

——这两者都指向同一个对象

【总结】i)函数也是对象,对象不一定是函数;

ii)对象的本质:无序的键值对集合;键值对当中的值可以是任意数据类型的值

iii)对象就是一个容器,这个容器当中放的是(属性和方法)

3)属性搜索

①在访问对象的某个成员的时候会先在对象中找是否存在

②如果当前对象中没有就在构造函数的原型对象中找

③如果原型对象中没有找到就到原型对象的原型上找

④知道Object的原型对象的原型是null为止

2、Function

——所有函数都是Function的实例

①本地对象:独立于宿主环境(浏览器)的对象——包括Object、Array、Date、RegExp、Function、Error、Number、String、Boolean

②内置对象——包括Math、Global(window,在js中就是全局变量),使用的时候不需要new

③宿主对象——包括自定义对象、DOM、BOM

相关推荐

《Queendom》宣布冠军!女团MAMAMOO四人激动落泪

网易娱乐11月1日报道据台湾媒体报道,南韩女团竞争回归的生死斗《Queendom》昨(10/31)晚播出大决赛,并以直播方式进行,6组女团、女歌手皆演唱新歌,并加总前三轮的赛前赛、音源成绩与直播现场投...

正确复制、重写别人的代码,不算抄袭

我最近在一篇文章提到,工程师应该怎样避免使用大量的库、包以及其他依赖关系。我建议的另一种方案是,如果你没有达到重用第三方代码的阈值时,那么你就可以自己编写代码。在本文中,我将讨论一个在重用和从头开始编...

HTML DOM tr 对象_html event对象

tr对象tr对象代表了HTML表格的行。HTML文档中出现一个<tr>标签,就会创建一个tr对象。tr对象集合W3C:W3C标签。集合描述W3Ccells返回...

JS 打造动态表格_js如何动态改变表格内容

后台列表页最常见的需求:点击表头排序+一键全选。本文用原生js代码实现零依赖方案,涵盖DOM查询、排序算法、事件代理三大核心技能。效果速览一、核心思路事件入口:为每个<th>绑...

连肝7个晚上,总结了66条计算机网络的知识点

作者|哪吒来源|程序员小灰(ID:chengxuyuanxiaohui)计算机网络知识是面试常考的内容,在实际工作中经常涉及。最近,我总结了66条计算机网络相关的知识点。1、比较http0....

Vue 中 强制组件重新渲染的正确方法

作者:MichaelThiessen译者:前端小智来源:hackernoon有时候,依赖Vue响应方式来更新数据是不够的,相反,我们需要手动重新渲染组件来更新数据。或者,我们可能只想抛开当前的...

为什么100个前端只有1人能说清?浏览器重排/重绘深度解析

面试现场的"致命拷问""你的项目里做过哪些性能优化?能具体讲讲重排和重绘的区别吗?"作为面试官,我在秋招季连续面试过100多位前端候选人,这句提问几乎成了必考题。但令...

HTML DOM 介绍_dom4j html

HTMLDOM(文档对象模型)是一种基于文档的编程接口,它是HTML和XML文档的编程接口。它可以让开发人员通过JavaScript或其他脚本语言来访问和操作HTML和XML文档...

JavaScript 事件——“事件流和事件处理程序”的注意要点

事件流事件流描述的是从页面中接收事件的顺序。IE的事件流是事件冒泡流,而NetscapeCommunicator的事件流是事件捕获流。事件冒泡即事件开始时由最具体的元素接收,然后逐级向上传播到较为不...

探秘 Web 水印技术_水印制作网页

作者:fransli,腾讯PCG前端开发工程师Web水印技术在信息安全和版权保护等领域有着广泛的应用,对防止信息泄露或知识产品被侵犯有重要意义。水印根据可见性可分为可见水印和不可见水印(盲水印)...

国外顶流网红为流量拍摄性侵女学生?仅被封杀三月,回归仍爆火

曾经的油管之王,顶流网红DavidDobrik复出了。一切似乎都跟他因和成员灌酒性侵女学生被骂到退网之前一样:住在950万美元的豪宅,开着20万美元的阿斯顿马丁,每条视频都有数百万观看...人们仿佛...

JavaScript 内存泄漏排查方法_js内存泄漏及解决方法

一、概述本文主要介绍了如何通过Devtools的Memory内存工具排查JavaScript内存泄漏问题。先介绍了一些相关概念,说明了Memory内存工具的使用方式,然后介绍了堆快照的...

外贸独立站,网站优化的具体内容_外贸独立站,网站优化的具体内容有哪些

Wordpress网站优化,是通过优化代码、数据库、缓存、CSS/JS等内容,提升网站加载速度、交互性和稳定性。网站加载速度,是Google搜索引擎的第一权重,也是SEO优化的前提。1.优化渲染阻塞。...

这8个CSS工具可以提升编程速度_css用什么编译器

下面为大家推荐的这8个CSS工具,有提供函数的,有提供类的,有提取代码的,还有收集CSS的统计数据的……请花费两分钟的时间看完这篇文章,或许你会找到意外的惊喜,并且为你的编程之路打开了一扇新的大门。1...

vue的理解-vue源码 历史 简介 核心特性 和jquery区别 和 react对比

一、从历史说起Web是WorldWideWeb的简称,中文译为万维网我们可以将它规划成如下的几个时代来进行理解石器时代文明时代工业革命时代百花齐放时代石器时代石器时代指的就是我们的静态网页,可以欣...