摘要:因此,就会形成一个原型链对象到原型,再到原型的原型如果一层层地上溯,所有对象的原型最终都可以上溯到,即构造函数的属性。
对于很多前端开发者而言,JavaScript中原型与原型链是一个比较容易疑惑的点,所以本文记录了自己对应这方面的一点理解,以后有更深的理解再来更新。
对象想要了解原型与原型链,首先要了解什么是对象?面向对象编程(Object Oriented Programming,缩写为 OOP)是目前主流的编程范式,即把实际上各种复杂关系抽象为多个对象后对它们进行分工合作从而完成对现实环境的模拟。因此对象是单个实物的抽象,抽象所得的对象是一个容器,拥有属性(property)和方法(method)。例如,我们把学生抽象为student对象,那么属性就可以用来记录具体是哪一个年级的学生(如初一、高一等),用方法来表示学生的某种行为(如学习、玩耍等)。
构造函数(constructor)、实例对象与继承当我们想要使用面向对象编程时,首要任务是生成对象。在JavaScript中,构造函数(constructor)就是专门用来生成实例对象的。一个构造函数,可以生成多个实例对象,这些实例对象都有相同的结构。
var Student= function () { this.age= 18; }; var s = new Student(); s.age// 18
特别需要注意的是:
以上代码中,Student就是构造函数,但是为了与普通函数区分,其名字的首字母要大写。
函数体内部使用了this关键字,代表了所要生成的对象实例。
生成对象的时候,必须使用new命令。只有new了才会生成新的实例对象。
除了用new命令生成新的实例对象,我们还可以通过Object.create() 来创建,这种方法适用于我们没有办法拿到构造函数而只能拿到一个现有的对象。
var student1 = { name:"Solar", age:18, greeting:function(){ console.log("Hello!"); } }; var student2 = Object.create(student1); student2.name//Solar student2.greeting()//Hello!
上面代码中,Object.create方法以student1对象为原型,生成了student2对象。student2继承了student1的所有属性和方法。
原型对象(prototype)首先让我们来了解一下为什么会有原型对象(prototype)?
function Student(name, age) { this.name = name; this.age = age; this.greeting = function(){ console.log("Hello!"); } } var student1= new Student("Solar", "18"); var student2 = new Student("Moonbyul", "17"); student1.greeting=== student2.greeting // false
从以上代码可以看到,通过构造函数实例出的对象,虽然都具有greeting方法,但是因为这个方法是生成在自身的每个实例对象上,也就是每生成一个实例就会新建一个greeting方法。但是其实greeting方法都是同样的,没有必要多次生成造成资源浪费,于是JavaScript的原型对象就诞生了。JavaScript规定,每个函数都有一个prototype属性,指向一个对象。
function Animal(name) { this.name = name; } Animal.prototype.color = "white"; var cat1 = new Animal("大毛"); var cat2 = new Animal("二毛"); cat1.color // "white" cat2.color // "white"
上面代码中,构造函数Animal的prototype属性,就是实例对象cat1和cat2的原型对象。原型对象上添加一个color属性,结果,实例对象都共享了该属性。
原型对象的属性不是实例对象自身的属性。只要修改原型对象,变动就立刻会体现在所有实例对象上。
Animal.prototype.color = "yellow"; cat1.color // "yellow" cat2.color // "yellow"
如果实例对象自身就有某个属性或方法,它就不会再去原型对象寻找这个属性或方法。
cat1.color = "black"; cat1.color // "black" cat2.color // "yellow" Animal.prototype.color // "yellow";原型链(prototype chain)
JavaScript 规定,所有对象都有自己的原型对象(prototype)。一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。因此,就会形成一个“原型链”(prototype chain):对象到原型,再到原型的原型……
如果一层层地上溯,所有对象的原型最终都可以上溯到Object.prototype,即Object构造函数的prototype属性。也就是说,所有对象都继承了Object.prototype的属性。Object.prototype的原型是null。null没有任何属性和方法,也没有自己的原型。因此,原型链的尽头就是null。
总结记住下面几句话,这几句话能解释一切关于原型方面的问题:
当 new 一个函数的时候会创建一个对象,『函数.prototype』 等于 『被创建对象.__proto__』
一切函数都是由 Function 这个函数创建的,所以『Function.prototype === 被创建的函数.__proto__』
一切函数的原型对象都是由 Object 这个函数创建的,所以『Object.prototype === 一切函数.prototype.__proto__』
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/99101.html
摘要:每一个由构造函数创建的对象都会默认的连接到该神秘对象上。在构造方法中也具有类似的功能,因此也称其为类实例与对象实例一般是指某一个构造函数创建出来的对象,我们称为构造函数的实例实例就是对象。表示该原型是与什么构造函数联系起来的。 本文您将看到以下内容: 传统构造函数的问题 一些相关概念 认识原型 构造、原型、实例三角结构图 对象的原型链 函数的构造函数Function 一句话说明什么...
摘要:在构造函数中的中定义的属性和方法,会被创建的对象所继承下来。从上面的输出结果看出,指向了其构造函数的,而本身也是一个对象,其内部也有属性,其指向的是直到最后指向,这条原型链才结束。和都指向,说明原型链到终止。 prototype原型对象 每个函数都有一个默认的prototype属性,其实际上还是一个对象,如果被用在继承中,姑且叫做原型对象。 在构造函数中的prototype中定义的属性...
摘要:原型链与继承当谈到继承时,只有一种结构对象。如果对该图不怎么理解,不要着急,继续往下看基于原型链的继承对象是动态的属性包指其自己的属性。当使用操作符来作用这个函数时,它就可以被称为构造方法构造函数。 原型链与继承 当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object )都有一个私有属性(称之为proto)指向它的原型对象(prototype)。该原型对象也...
摘要:简单回顾一下构造函数原型和实例对象之间的关系每个构造函数都有一个原型对象。找到生成构造函数的原型对象的构造函数,搜索其原型对象,找到了。 JS面向对象的程序设计之继承的实现 - 原型链 前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。如有纰漏或错误,会非常感谢您的指出。文中绝大部分内容引用自《JavaS...
摘要:我们用一张图表示构造函数和实例原型之间的关系好了构造函数和实例原型之间的关系我们已经梳理清楚了,那我们怎么表示实例与实例原型,也就是或者和之间的关系呢。 开篇: 在Brendan Eich大神为JavaScript设计面向对象系统的时候,借鉴了Self 和Smalltalk这两门基于原型的语言,之所以选择基于原型的面向对象系统,并不是因为时间匆忙,它设计起来相对简单,而是因为从一开始B...
阅读 774·2019-08-30 14:05
阅读 1679·2019-08-30 11:08
阅读 3186·2019-08-29 15:41
阅读 3573·2019-08-23 18:31
阅读 1482·2019-08-23 18:29
阅读 520·2019-08-23 14:51
阅读 2078·2019-08-23 13:53
阅读 2103·2019-08-23 13:02