龙空技术网

关于JS原型链的那点事

我是凯歌 336

前言:

现在大家对“js原型”大致比较关注,各位老铁们都想要分析一些“js原型”的相关知识。那么小编同时在网上汇集了一些关于“js原型””的相关内容,希望你们能喜欢,大家一起来学习一下吧!

在讲述原型链继承之前,我建议大家能够先去看看《详解JS中函数、函数原型和函数实例之间的关系》这篇文章,这样有助于大家理解JS原型链继承的原理,因为这篇文章是基于上篇文章来讲述的,如果你读完了,那么我们就来看看下面这张图:

原型链继承

如上图所示: Personal 对象想要继承 Main 对象,则通过将 Main 的实例赋值给 Personal 的原型对象 :

Personal.prototype = new Main () ;

如此 Personal 原型对象 就能通过 Main 对象的实例中的 [[Prototype]] 来访问到 Main 原型对象中的属性和方法了,而此时大家注意,Personal 原型对象 则与 Personal 函数 断开了联系,因为 Personal 原型对象被重新赋值了,所以还需要重新将 Personal 函数和 Personal原型对象 重新建立联系:

Personal.prototype.constructor = Personal ;
完整代码如下:
function Main () {}Main.prototype.sex = '男' ;Main.prototype.eat = function () {	console.log('Main eat ...')}function Personal () {}Personal.prototype.name = 'hwk';Personal.prototype.sayName = function () {	console.log('Personal name')}// 继承Personal.prototype = new Main();Personal.prototype.constructor = Personal;var p = new Personal();console.log(p.sex ) ; // 男console.log(p.name) ; // undefinedp.eat();			 // Main eat ...p.sayName ();		 // Uncaught TypeError:p.sayName is not a function 

运行如上代码你会发现 p.name 为 undefined , p.sayName 这个方法没找到,原因在于我们后面重新赋值了 Personal.prototype = new Main(); 因此找不到一开始定义在Personal.prototype 上的 name 属性和 sayName 方法,因此在使用原型链继承的时候,要在继承之后再去在原型对象上定义自己所需的属性和方法。

先继承,后添加属性和方法

// 先继承Personal.prototype = new Main();Personal.prototype.constructor = Personal;// 后定义属性和方法Personal.prototype.name = 'hwk';Personal.prototype.sayName = function () {	console.log('Personal name')}// 正确输出console.log(p.sex ) ; // 男console.log(p.name) ; // hwkp.eat();			 // Main eat ...p.sayName ();		 // Personal name

此时 Personal的实例 已经可以访问到父类Main原型对象 中的方法和属性了,这也就是原型链继承的方式,希望对大家有帮助!

PS:在原型对象上定义属性和方法,其所有的构造函数实例都能共享原型上的属性和方法,因此如果某一个构造函数实例对象修改了原型对象上的属性值和方法,则也会影响其他实例对象。

标签: #js原型