美文网首页工作生活
构造函数和原型的关系

构造函数和原型的关系

作者: 凌晨4点的简书 | 来源:发表于2019-07-03 23:52 被阅读0次

1. 基本概念:

“原型属性”也可以叫做“原型”(prototype):所有函数都有prototype,我觉得可以理解为python中的类属性,不需要通过实例,直接用类(es5就是函数名)可以调用,下面列举了三种创建函数的方法,函数创建后都有prototype属性,prototype指向“原型对象”。

// 函数声明

function F1() {

};

// 表达式定义

let F2 = function () {

};

// 函数构造

let F3 = new Function('n1', 'n2', 'return n1+n2');

console.info(F1.prototype)    //F1 {}

console.info(F2.prototype)    //F2 {}

console.info(F3.prototype)    //anonymous {}

原型对象(prototype所指向的对象):这玩意主要就是用来继承用的,包含实例的方法和属性。说白了也就是一个对象,用来定义函数对象的属性、方法,默认情况下它包含一个constructor属性,如果你重新定义可以覆盖constructor属性。

原型对象与构造函数配合一起,就形成一个类了,然后构造函数接收每次初始化对象的初始值,原型对象就提供类模板。而在其他java、python中都写在class中,当然es6也加入了class;以下的简单代码帮助理解上面说的,定义一个动物类,根据构造函数创造不同的动物,如果需要创建特殊动物,可以继承然后添加一些特殊属性、方法再创建。---------总结es5的类可以用“构造函数+构造函数的prototype”来定义,类的对象使用“new构造函数”来生成。

// 构造函数

let Animal = function (name) {

    this.name = name

}

// 原型对象定义

Animal.prototype.getAnimal = function () {

    return this.name

}

// 创建对象,会继承Animal.prototype

let dog = new Animal('dog')

let cat = new Animal('cat')

console.info(dog.getAnimal())

console.info(cat.getAnimal())

上图展示了构造函数、原型对象、具体对象的属性、方法及属性值。

普通对象与函数对象:通过函数对象 new一下可以得到普通对象,把函数对象理解为类,普通对象为实例。如下代码加强理解,可以看到函数对象new完以后生产的对象是object;函数对象中都有prototype前面已经说过了(为什么函数对象中会有这个属性以后读取更深以后再解答)

// Animal函数对象

let Animal = function (name) {

    this.name = name

}

// 原型对象

Animal.prototype.getAnimal = function () {

    return this.name

}

// 通过函数对象创建普通对象

let dog = new Animal('dog')

console.info(typeof dog)    //object

总结: 函数对象通过new Function()可以得到,Function对象可以构造函数对象。而函数对象又可以new一个普通对象出来。

__proto__:所有对象都有__proto__这个属性,这个属性指向对应“函数对象(就理解为类)”的prototype,这也是实现原型链的根本,在书中一般都用[[prototype]]。

构造函数和constructor属性:其实前面的图已经标注了,概念后续补上。

原型链:ES中的继承主要用原型链来实现,记住了这玩意主要用来实现继承。其基本思想是:利用原型让一个引用类型继承另一个引用类型的属性和方法(js高级程序设计说的),还是用以上的例子来说明

let Animal = function (name) {

    this.name = name

}

// 原型对象定义

Animal.prototype.getAnimal = function () {

    return this.name

}

// 创建对象,会继承Animal.prototype

let dog = new Animal('dog')

let cat = new Animal('cat')

console.info(dog.valueOf())

console.info(cat.valueOf())

跟上面例子就差了最后console打印部分,我们定义的Animal没有写valueof()为什么可以调用这个方法呢?到底是什么鬼?这就是原型链搞的鬼。我再把上面的图形完善一下

上图还有两个属性的指向没有画,第一、Animal的__proto__指向;第二、Animal.prototype的__proto__指向。

这个图把Animal.prototype的__proto__指向添加了,

图形说明:

1. Animal.prototype是个普通对象,ES中Object是所有对象的基础。所有引用类型都继承了Object;所有函数的默认原型是都Object的实例,因此Animal.prototype的__proto__指向Object.prototype,这个一定要理解。

2. 我们调用cat.valueOf()解释器会先找dog实例中有没有这个方法,没有就在Animal.prototype中查找,没有再去Object.prototype中查找。然后就有了cat.valueOf()的运行结果:Animal { name: 'cat' }。

3. Object构造函数的prototype也指向Object.prototype。

最后把Animal的__proto__指向补完基本就差不多了。

相关文章

  • JS继承与原型链

    构造函数,原型和实例的关系: 每个构造函数(constructor)都有一个原型对象(prototype),原型对...

  • 继承

    构造函数、原型和实例的关系: 每个构造函数都有其对应的原型对象;每个原型对象都有一个构造函数指针construct...

  • 继承的几种方式

    构造函数,原型和实例的关系每个构造函数都有一个原型对象prototype,原型对象中有个constructor属性...

  • JavaScript高级程序设计学习笔记之继承模式

    原型链 JavaScript的继承主要依靠原型链来实现的。我们知道,构造函数,原型,和实例之间的关系:每个构造函数...

  • 深入浅析js原型链和vue构造函数

    一、什么是原型链?简单回顾下构造函数,原型和实例的关系: 每个构造函数(constructor)都有一个原型对象(...

  • 原型链

    构造函数、原型、实例的关系 通过构造函数创建实例 每个构造函数都有一个原型对象 原型对象到包含一个指向构造函数的指...

  • 原型链

    简单回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例...

  • JavaScript 继承 1 原型链

    简单回顾一下构造函数、原型和实例之间的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而...

  • JS继承的相关问题

    构造函数、原型对象和实例之间的关系? 每个构造函数都有一个 prototype 属性指向原型对象,原型对象中有一个...

  • JS中的继承方案(含深浅拷贝)

    ES5继承 构造函数、原型和实例的关系:每一个构造函数(函数对象)都有一个prototype属性,指向函数的原型对...

网友评论

    本文标题:构造函数和原型的关系

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