美文网首页IT修真院-前端
简述JS中的原型链

简述JS中的原型链

作者: 自娱自楽 | 来源:发表于2017-11-20 15:36 被阅读11次

Javascript语言的继承机制一直很难被人理解。

它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain)模式,来实现继承。

Brendan Eich设计javascript之初是为了实现网页与浏览器之间交互的一种简单的脚本语言

如果真的是一种简易的脚本语言,其实不需要有"继承"机制。但是,Javascript里面都是对象,必须有一种机制,将所有对象联系起来。所以,Brendan Eich最后还是设计了"继承"。


javascript实现继承的方式

C++和Java语言都使用new命令,生成实例。

C++

ClassName*object=new ClassName(param);

java

Foo foo=new Foo();

JavaScript引入了new命令,但由于它没有"类"的概念。考虑到C++和Java使用new命令时,都会调用"类"的构造函数(constructor)。于是,Brendan Eich在设计JavaScript时做了一个简化,new命令后面跟的不是类,而是构造函数。

构造函数和prototype对象之间的关系

function DOG(name){

this.name=name;

this.species='犬科';

}

var dogA=new DOG('大毛');

var dogB=new DOG('二毛');

dogA.species='猫科';

alert(dogB.species);// 显示"犬科

用构造函数生成的每一个实例对象都有自己的属性和方法的副本,这不仅无法做到数据共享,也是极大的资源浪费。

考虑到这一点,Brendan Eich为构造函数设置一个prototype属性。这个属性包含一个对象(以下简称"prototype对象")

prototype对象和实例对象的关系

function DOG(name){

this.name=name;

}

DOG.prototype={

species:'犬科'

};

var dogA=new DOG('大毛');

var dogB=new DOG('二毛');

alert(dogA.species);// 犬科

alert(dogB.species);// 犬科

实例对象的属性和方法继承prototype对象

实例对象的_proto_属性的值就是它所对应的原型对象

当你创建函数时,JS会为这个函数自动添加prototype属性,值是空对象。而一旦你把这个函数当作构造函数(constructor)调用(即通过new关键字调用),那么JS就会帮你创建该构造函数的实例,实例继承构造函数prototype的所有属性和方法(实例通过设置自己的__proto__指向承构造函数的prototype来实现这种继承)。



若想访问一个对象的原型,应该使用什么方法?

1、使用_proto_属性

每个JS对象一定对应一个原型对象,并从原型对象继承属性和方法。

对象__proto__属性的值就是它所对应的原型对象;

function DOG(name){

this.name=name;

}

DOG.prototype={

species:'犬科'

};

var dogA = new DOG('大毛');     

var dog B = new DOG('二毛');

dogA.__proto__==DOG.prototype;//true

dogB.__proto__==DOG.prototype;//true

对象的__proto__指向自己构造函数的prototype。obj.__proto__.__proto__...的原型链由此产生,包括我们的操作符instanceof正是通过探测obj.__proto__.__proto__... === Constructor.prototype来验证obj是否是Constructor的实例。

2、使用Object.getPrototypeOf()

Object.getPrototypeOf(dogA)==DOG.prototype;//true

Object.getPrototypeOf(dogB)==DOG.prototype;//true

使用__proto__是有争议的,而且是不鼓励的。 它从来没有被包括在EcmaScript语言规范中,但是现代浏览器实现了它, 无论如何。__proto__属性已在ECMAScript 6语言规范中标准化,用于确保Web浏览器的兼容性,因此它未来将被支持。它已被不推荐使用, 赞成使用Object.getPrototypeOf。


我们知道JS是单继承的,Object.prototype是原型链的顶端,所有对象从它继承了包括toString等等方法和属性。

Object本身是构造函数,继承了Function.prototype;Function也是对象,继承了Object.prototype。这里就有一个_鸡和蛋_的问题:

Object instanceof Function// true

Function instanceof Object// true

Function本身就是函数,Function.__proto__是标准的内置对象Function.prototype。

Function.prototype.__proto__是标准的内置对象Object.prototype。


参考文献:

Javascript继承机制的设计思想

从__proto__和prototype来深入理解JS对象和原型链

相关文章

  • 简述JS中的原型链

    Javascript语言的继承机制一直很难被人理解。 它没有"子类"和"父类"的概念,也没有"类"(class)和...

  • ES5之面向对象

    1、 请简述一下js原型链 原型链是Javascript实现类的底层原理,是一种继承机制。说到继承,这起源于J...

  • 在nodejs中面向对象:Bearcat

    JS中的面向对象 最最最开始,我们先来说说JS中的面向对象。 原型链 参考文章:图解Javascript原型链 J...

  • 廖雪峰JS小记

    (function(){})() 原型,原型链 浅谈Js原型的理解JS 原型与原型链终极详解 对象 对象:一种无序...

  • JS闭包问题(一)

    之前我写过一篇JavaScript原型与原型链的文章,此属于JS中的重难点。 而闭包,是JS中除了原型链之外又一个...

  • javascript中的原型链与继承

    javascript中的原型链与继承javascipt中的原型链和继承机制是这门语言所特有的,但js中的原型机制也...

  • 2022前端高频面试题

    JS相关 1.原型和原型链是什么 原型和原型链都是来源于对象而服务于对象的概念js中引用类型都是对象,对象就是属性...

  • JS的__proto__和prototype

    最近在回顾JS的原型和原型链的知识,熟悉JS的同学都知道JS的继承是靠原型链实现的,那跟原型链相关的属性__pro...

  • Javascript(三)之原型继承理解

    进阶路线 3 原型继承 3.1 优秀文章 最详尽的 JS 原型与原型链终极详解 一 最详尽的 JS 原型与原型链终...

  • JavaScript原型对象与原型链

    一、前言 原型和原型链是 JavaScript中不可避免需要碰到的知识点,在刚开始学习 JS 时,原型和原型链都是...

网友评论

    本文标题:简述JS中的原型链

    本文链接:https://www.haomeiwen.com/subject/tahvvxtx.html