如何理解javascript的原型和原型链

     2022-04-04     253

关键词:

在现在的业务开发中,应该很少人在写原生JavaScript了,大家都一股脑地扑在各个框架上。本来,这些框架对于业务和开发者来说是一种福音,减少了各种各样的开发痛点,但是带来的负面问题就是对于开发者来说,越来越依赖框架,离原生JavaScript越来越远,对基础知识的记忆和理解慢慢地模糊、淡忘。

而原型、原型链就是其中之一。
每一个构造函数都有一个与之相关联的对象,该对象称之为原型对象。
每个实例对象都能共享其原型对象上的属性和方法。
原型对象的作用主要用来实现属性的继承,让实例对象能共享原型对象的属性,减少内存分配。
所以,在上一节中,我们想在每个Person对象中共享同一个say方法,可以这样来实现。

function Person(name, age) {
this.name = name;
this.age = age;
}//在原型对象上添加say函数,实例对象共享该函数
Person.prototype.say = function(){
console.log("say hello");
};var p = new Person("zs", 10, say);
p.say();var p2 = new Person("zs", 10, say);
p2.say();
在原型对象上添加成员的方法:
? 构造函数.prototype.成员名 = 成员值;
为Person原型对象添加say方法后,实现了在多个实例对象上共享该方法的功能。
获取原型对象的方法:
? 构造函数.prototype
? 实例对象. proto
在每个实例对象上都有一个 proto 的属性,也是用来获取该对象的原型对象。
Person.prototype == p. proto ;//true
下图详细说明了各对象之间的关系:

技术图片
面向对象中的核心概念
构造函数:Person,和new关键字一起创建对象
构造函数的原型对象:Person.prototype,
原型对象:和创建实例对象的构造函数相互关联的对象
实例对象:由构造器创建出来的对象称之为实例对象
实例化:由构造器创建实例对象的过程称之为实例化
对象的成员:属性+方法
实例成员:实例对象上的属性和方法,name,age,只能当前实例对象才能访问
原型成员:原型对象上的属性和方法,say(),使用该原型对象对应构造器创建出来的所有实例对象都能访问
静态成员:直接添加在构造函数上的属性和方法,只能使用构造函数才能访问

proto 属性介绍
该属性是在ES6之后才纳入规范,在这之前,只有部分浏览器实现。
该属性可以获取指定实例对象的原型对象,p. proto ,和Person.prototype获取的一样
我们也可以使用Object构造器上的getPrototypeOf(实例对象)方法获取指定实例对象的原型对象
以上提到的三种获取原型对象的方法所得到的结果是一样的。即:

Object.getPrototypeOf(p) == Person.prototype == p. proto

扩展内置对象

内置对象是JS中事先定义好的对象,可以直接拿来使用的对象,在这类对象中已经封装好了一堆的方法和属性,方便开发者完成基本的功能。

但是在实际开发中,这些属性或者方法不一定能够满足我们的需求,此时就需要对这些内置对象做功能扩展。

需求:为数组对象添加一个获取元素个数的方法

var arr1 = [1, 2, 3];var arr2 = ["A", "B", "C","D"];
arr1.getLength = function () {
return this.length;
}console.log(arr1.getLength());

上面为数组arr1添加了一个getLength()方法获取其元素个数,那么此时的arr2对象上有这个方法吗?相信大家心里都有答案。如果想要arr2拥有同样的功能,也需要同样的操作。

所以这种方式不可取,如果100个数组都想都需要这样的功能,操作起来就比较复杂了。
根据前面学过的知识点,我们完全可以使用原型来解决这个问题。

var arr1 = [1, 2, 3];var arr2 = ["A", "B", "C","D"];Array.prototype.getLength = function () {
return this.length;
}console.log(arr1.getLength());// 3console.log(arr2.getLength());// 4

我们直接在Array的原型对象上添加getLength()方法,之后创建的所有的数组对象都拥有了该方法,搞定!
这种方式能够解决我们的问题,但是还是存在问题的:

  1. 在多人开发的环境中,如果使用这种方式对内置对象做扩展,可能会对其他开发人员造成影响
  2. 如果在原型对象上添加了过多的成员,会降低对象成员的搜索效率。

安全的扩展内置对象

上面扩展内置对象的方法存在一定的问题,问题的关键其实在于我们是直接在内置对象的原型上进行拓展的,这样导致对其他使用该对象的开发人员造成影响。
所以,我们的解决思路就是,自定义一个对象,让该对象继承需要扩展的内置对象,然后只需要对自定的对象进行操作即可。

function MyArray() {
}//让MyArray的原型指向Array对象//即继承Array中的所有成员
MyArray.prototype= new Array();
MyArray.prototype.getLength=function () {
return this.length;
}var arr1 = new MyArray();
arr1.push("A","B","C","D","E");//内置对象的初始方法console.log(arr1.getLength());//扩展之后的方法

接下来,如果想要对数组做扩展,我们只需要操作MyArray即可,而不需要直接操作Array,如此,就不会对其他使用Array的开发人员操作影响了。看图理解:
技术图片
原型链的结构图
每个实例对象都是由构造函数创建出来的
每一个构造函数都有默认关联的原型对象
原型对象本身也是对象,所以它也有自己的构造函数
原型对象的构造函数也有默认关联的原型对象
以上就构成了一种链式访问结构,称之为原型链
下面画出了Person对象和Array对象的原型链:

技术图片
今天关于JS中原型和原型链的内容就先进行到这里。大家有什么疑问,可以在评论区评论。或者在JS方面有什么需要了解的也请大家积极评论。希望大家可以相互分享工作和学习中的知识和见识。

javascript原型链理解

  javascript原型和原型链的引入,最初的目的是属性和方法的共享。没有原型,我们使用同一个构造函数新建的一系列对象,就都拥有一组完全相互独立的属性和方法,但是方法和一些属性我们不需要所有对象都各自有一个,... 查看详情

原型和原型链的理解(代码片段)

原型链是一种机制,指的是JavaScript每个对象都有一个内置的 __proto__ 属性指向创建它的构造函数的 prototype(原型)属性。原型链的作用是为了实现对象的继承,要理解原型链,需要先从函数对象、constructor、new、protot... 查看详情

javascript原型及原型链的初步理解

最近折腾了好久,终于是把js里面的原型和原型链做了个初步的理解;在这里,我打个比喻:我(child),我妈constructor(构造函数)生了我;别人问我老妈跟谁生的我,于是此时我妈会指向我爸爸(father),即constructor.prototype=father... 查看详情

问答式理解javascript的原型及其原型链

简言简语1、什么是原型?原型指的是javascript里面对象的prototype属性,称为原型对象,js原生对象都有prototype属性。2、prototype是怎么来的?在我们以函数式声明一个函数时,js引擎会为我们分配prototype这个属性,在js中所有的对象都... 查看详情

深入理解js继承和原型链

...于类的面向对象语言(Java或者C++)的开发者来说,JavaScript的语法是比较怪异的,这是由于JavaScript是一门动态语言,而且它没有类的概念( ES6新增了class关键字,但只是语法糖,JavaScript仍旧是基于原型)。涉及到继承... 查看详情

javascript-我对作用链闭包原型及原型链的理解

Javascript-基础概念总结(2)    最近学习一些javascript基础知识,也解决了很多之前的疑惑,记得第一次被问及怎样理解闭包时,我的回答是:就是类似于封装吧!现在想想是有多白痴,学习技术是需要逻辑性很强... 查看详情

javascript原型原型链神图

理解下面的神图,理解js原型、原型链1、每个对象都有自己的原型对象,每个对象都有一个prototype属性,该属性是一个指针,指向该对象的原型对象,原型对象中存放了一堆特定类型的实例所共享的属性和方法,原型对象也有自... 查看详情

javascript中的原型链和继承

理解原型链在JavaScript的世界中,函数是一等公民。上面这句话在很多地方都看到过。用我自己的话来理解就是:函数既当爹又当妈。“当爹”是因为我们用函数去处理各种“粗活累活”(各种工具函数、页面交互、业务逻辑等... 查看详情

javascript——对象属性原型与原型链

对象属性、原型与原型链 哈哈哈,我的第二篇博客哟,说的是对象属性、原型与原型链。可能这些只是某些小点串联起来的,逻辑性没有很强。所以会对文章的可读性和理解性带来一些困扰。不过,今天我又前进了那么一小... 查看详情

js原型原型链深入理解

原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有”prototype”属性,函数对象有”prototype”属性,原型对象有”constructor”属性。一、初识原型在JavaScript中,原型也是一个对象,通过... 查看详情

原型链的理解

###原型链的理解####概念+javascript每一个对象**包括原型对象**都有一个内置的`proto`属性指向创建他的函数对象的原型对象,即`prototype`属性####作用+实现对象的继承###理解1.函数对象+在javascript中,函数就是对象2.原型对象+当定义... 查看详情

好文要顶之---简单粗暴地理解javascript原型链

原型链理解起来有点绕了,网上资料也是很多,每次晚上睡不着的时候总喜欢在网上找点原型链和闭包的文章看,效果极好。不要纠结于那一堆术语了,那除了让你脑筋拧成麻花,真的不能帮你什么。简单粗暴点看原型链吧,想... 查看详情

好文要顶之---简单粗暴地理解javascript原型链

原型链理解起来有点绕了,网上资料也是很多,每次晚上睡不着的时候总喜欢在网上找点原型链和闭包的文章看,效果极好。不要纠结于那一堆术语了,那除了让你脑筋拧成麻花,真的不能帮你什么。简单粗暴点看原型链吧,想... 查看详情

深入理解javascript原型和闭包(转)

说明:  该教程绕开了javascript的一些基本的语法知识,直接讲解javascript中最难理解的两个部分,也是和其他主流面向对象语言区别最大的两个部分——原型和闭包,当然,肯定少不了原型链和作用域链。帮你揭开javascri... 查看详情

javascript之彻底理解原型与原型链(代码片段)

1.前言原型与原型链知识历来都是面试中考察的重点,说难不算太难,但要完全理解还是得下一定的功夫。先来看一道面试题开开胃口吧:functionUser()User.prototype.sayHello=function()varu1=newUser();varu2=newUser();console.log... 查看详情

javascript之彻底理解原型与原型链(代码片段)

1.前言原型与原型链知识历来都是面试中考察的重点,说难不算太难,但要完全理解还是得下一定的功夫。先来看一道面试题开开胃口吧:functionUser()User.prototype.sayHello=function()varu1=newUser();varu2=newUser();console.log... 查看详情

javascript之彻底理解原型与原型链(代码片段)

1.前言原型与原型链知识历来都是面试中考察的重点,说难不算太难,但要完全理解还是得下一定的功夫。先来看一道面试题开开胃口吧:functionUser()User.prototype.sayHello=function()varu1=newUser();varu2=newUser();console.log... 查看详情

原型和原型链的理解

谈谈你对JS原型和原型链的理解?候选人:JS原型是指为其它对象提供共享属性访问的对象。在创建对象时,每个对象都包含一个隐式引用指向它的原型对象或者null。原型也是对象,因此它也有自己的原型。这样构成一个原型链... 查看详情