原型和原型链

Posted 前端纸飞机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原型和原型链相关的知识,希望对你有一定的参考价值。

原型:

实例对象通过构造函数(经过new调用)创建。

函数的原型prototype: 每个函数默认有一个prototype属性(指针),其值指向一个对象,这个对象就是我们所说的原型(或叫原型对象)。原型内有一个constructor属性指向构造函数本身。

实例对象的原型__proto__: 每个实例对象都有一个内置属性 __ proto__ , 指向创建这个实例的构造函数的prototype原型对象。每一个实例对象都能从该原型中“继承”属性和方法。所以构造函数的原型被其创建的每个实例对象共享,因此也是每个实例对象的原型。

function Person() ;//构造函数 Person
var p = new Person();//通过new创建的(实例对象) p
p.__proto__  === Person.prototype; //true (这是一个面试点,见下面)

//构造函数Person的prototype 和通过 Person构造函数new出来的实例对象的__proto__ 是否相等?
//函数的原型和实例对象的原型是否相等?
//大概有这些问法

上图来看,有个prototype(原型),内部有一个constructor的属性,它都指向了自己本身(应该不难看出它每一层constructor下都长的一模一样)。

function Person() ;
Person.prototype.name ='xiao';
var p1 = new Person();
var p2 = new Person();
console.log(p1.name) //xiao
console.log(p2.name) //xiao

//备注:虽然实例对象可以访问原型中的值,但无法通过实例去重写原型中的值(可以对原型中引用类型值中的项进行增删改,但无法改写整个引用值)。
//如在实例中添加一个与原型中同名的属性,会在实例中创建自己的属性,原型中不受影响,访问时会屏蔽掉原型中的值。
p1.name = 'lulu';
console.log(p1.name) //lulu
console.log(p2.name) //xiao

下面是面试点: 

虽然实例对象可以访问原型中的值,但无法通过实例去重写原型中的值(可以对原型中引用类型值中的项进行增删改,但无法改写整个引用值)。
在实例中添加一个与原型中同名的属性会在实例中创建自己的属性,原型中不受影响,访问时会屏蔽掉原型中的值。 可见下图:

原型链:(面试会问,答案如下)

什么是原型链?

每个实例对象都有一个原型__proto__,这个原型对象还可以有它自己的原型 __proto__( 该原型对象也是由构造函数创建,该构造函数也有prototype属性),以此类推 , 形成一个实例与原型的 __proto__链条,即原型链。查找属性时,先在当前对象里找,如果没有则去它的原型对象里找,再没有的话就去原型对象的原型对象里找,这个操作被委托在整个原型链上,链的最终端是null。

原型链继承:(面试会问,答案如下)

什么是原型链继承?

可以让子类型构造函数的原型prototype等于父类型构造函数的实例对象,这样,子类型函数的实 例对象就添加到了原型链上,可以访问父类型的实例对象及其链上所有的属性和方法,即实现了继承。

实际上大部分都是概念上的东西,这两张图基本囊括了所有的原型链面试题,也不会细问,大部分都是根据图背一下,说一层一层往上查,然后终点是null。

以上是关于原型和原型链的主要内容,如果未能解决你的问题,请参考以下文章

js奥义:原型与原型链

strcasecmp函数和strncasecmp函数原型

原型模式(Prototype Pattern)

JavaScript之原型

《你不知道的JavaScript》 原型

Java必学设计模式3:原型