带你理解JavaScript 原型原型链

目录
  • 一、原型、原型链相等关系理解
  • 二:原型、原型链的意思何在

看完这篇文章,你会发现,原型、原型链原来如此简单!  上面经典的原型链相等图,根据下文的学习,你会轻易掌握。

一、原型、原型链相等关系理解

首先我们要清楚明白两个概念:

js分为函数对象和普通对象,每个对象都有__proto__属性,但是只有函数对象才有prototype属性
ObjectFunction都是js内置的函数, 类似的还有我们常用到的ArrayRegExpDateBooleanNumberString

这两个概念大家跟我一起读三遍并记住,后面会用到

那么__proto__prototype到底是什么,两个概念理解它们

  • 属性__proto__是一个对象,它有两个属性,constructor__proto__
  • 原型对象prototype有一个默认的constructor属性,用于记录实例是由哪个构造函数创建;

这两个概念大家跟我一起读三遍并记住,后面会用到

有以下构造函数Person,他的原型上有所属国属性motherland='China'

 function Person(name, age){
    this.name = name;
    this.age = age;
 }

 Person.prototype.motherland = 'China'

通过new Person()创建的person01实例

 let person01 = new Person('小明', 18);

js之父在设计js原型、原型链的时候遵从以下两个准则

 Person.prototype.constructor == Person // **准则1:原型对象(即Person.prototype)的constructor指向构造函数本身**
 person01.__proto__ == Person.prototype // **准则2:实例(即person01)的__proto__和原型对象指向同一个地方**

这两个准则大家跟我一起读三遍并记住,后面会用到

记住以上四个概念两个准则,任何原型链相等判断都能判断正确;

大家可以对照上图,看看自己概念准则是否弄清楚了,一定要对照上图哦

// 从上方 function Foo() 开始分析这一张经典之图
function Foo()
let f1 = new Foo();
let f2 = new Foo();

f1.__proto__ = Foo.prototype; // 准则2
f2.__proto__ = Foo.prototype; // 准则2
Foo.prototype.__proto__ = Object.prototype; // 准则2 (Foo.prototype本质也是普通对象,可适用准则2)
Object.prototype.__proto__ = null; // 原型链到此停止
Foo.prototype.constructor = Foo; // 准则1
Foo.__proto__ = Function.prototype; // 准则2
Function.prototype.__proto__  = Object.prototype; //  准则2 (Function.prototype本质也是普通对象,可适用准则2)
Object.prototype.__proto__ = null; // 原型链到此停止
// **此处注意Foo 和 Function的区别, Foo是 Function的实例**

// 从中间 Function Object()开始分析这一张经典之图
Function Object()
let o1 = new  Object();
let o2 = new  Object();

o1.__proto__ = Object.prototype; // 准则2
o2.__proto__ = Object.prototype; // 准则2
Object.prototype.__proto__ = null; // 原型链到此停止
Object.prototype.constructor = Object; // 准则1
Object.__proto__ = Function.prototype // 准则2 (Object本质也是函数);
// 此处有点绕,Object本质是函数,Function本质是对象
Function.prototype.__proto__ =  Object.prototype; // 准则2 (Function.prototype本质也是普通对象,可适用准则2)
Object.prototype.__proto__ = null; // 原型链到此停止

// 从下方 Function Function()开始分析这一张经典之图
Function Function()
Function.__proto__ = Function.prototype // 准则2
Function.prototype.constructor = Function; // 准则1

由此可以得出结论: 除了Object的原型对象(Object.prototype)的__proto__指向null,其他内置函数对象的原型对象(例如:Array.prototype)和自定义构造函数的 __proto__都指向Object.prototype, 因为原型对象本身是普通对象。 即:

Object.prototype.__proto__ = null;
Array.prototype.__proto__ = Object.prototype;
Foo.prototype.__proto__  = Object.prototype;

二:原型、原型链的意思何在

理解了这些相等关系之后,我们思考,原型、原型链的意思何在?原型对象的作用,是用来存放实例中共有的那部份属性、方法,可以大大减少内存消耗。

用我们文章开始的Person构造函数和person01实例举例说:

console.log(person01)

打印person01, 他有自己属性 name = '小明',age = 18; 同时通过原型链关系,他有属性motherland = 'China';

我们再创建person2实例

let person02 = new Person('小花', 20);
console.log(person02)

打印person02, 他有自己属性 name = '小花',age = 20; 同时通过原型链关系,他有属性motherland = 'China'; 看出来了没有,原型对象存放了person01person02共有的属性所属国motherland = 'China'. 我们不用在每个实例上添加motherland 属性,而是将这一属性存在他们的构造函数原型对象上,对于人类Person这样的构造函数。相同的属性、方法还有很多很多,比如我们是黑头发,我们都有吃,睡这样一个方法,当相同的属性、方法越多,原型、原型链的意义越大。 那我们可以这样操作

Person.prototype.hairColor = 'black';
Person.prototype.eat = function(){
    console.log('We usually eat three meals a day.')
}
console.log(person01)
console.log(person02)

此时我们再打印person01person02,我们惊喜的发现,他们有了属性hairColoreat方法;实例们动态的获得了Person构造函数之后添加的属性、方法,这是就是原型、原型链的意义所在!可以动态获取,可以节省内存。

另外我们还要注意:如果person01将头发染成了黄色,那么hairColor会是什么呢?

person01,hairColor = 'yellow';
console.log(person01)
console.log(person02)

可以看到,person01hairColor = 'yellow', 而person02hairColor = 'black'; 实例对象重写原型上继承的属相、方法,相当于“属性覆盖、属性屏蔽”,这一操作不会改变原型上的属性、方法,自然也不会改变由统一构造函数创建的其他实例,只有修改原型对象上的属性、方法,才能改变其他实例通过原型链获得的属性、方法。

到此这篇关于带你了解JS 原型原型链的文章就介绍到这了,更多相关JS 原型原型链内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Javascript原型链及instanceof原理详解

    instanceof:用来判断实例是否是属于某个对象,这个判断依据是什么呢? 首先,了解一下javascript中的原型继承的基础知识: javascript中的对象都有一个__proto__属性,这个是对象的隐式原型,指向该对象的父对象的原型(prototype).显式的原型对象使用prototype,但是Object.prototype.proto=null; 判断某个对象a是否属于某个类A的实例,可以通过搜索原型链. 实例对象属性查找顺序是:实例对象内部---->构造函数原型链---->

  • 五句话帮你轻松搞定js原型链

    原型链是一种机制,指的是JavaScript每个对象包括原型对象都有一个内置的[[proto]]属性指向创建它的函数对象的原型对象,即prototype属性. 作用:原型链的存在,主要是为了实现对象的继承. 一. 记住以下5句话,轻松搞定js原型链 Function 和 Object 都是构造函数 所有的构造函数都是Function new出来的(Function自己new了自己):所有的原型对象都是Object new出来的(Object new了自己的原型对象) 每一个构造函数都有一个pro

  • JavaScript对象原型链原理解析

    这篇文章主要介绍了JavaScript对象原型链原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一个js对象,除了自己设置的属性外,还会自动生成proto.class.extensible属性,其中,proto属性指向对象的原型. 对象的属性也有writable.enumerable.configurable.value和get/set的配置方法. 对象的创建方式有三种: 一.使用字面量直接创建. 二.基于原型链创建. 分析上图,要点如

  • JS原形与原型链深入详解

    本文实例讲述了JS原形与原型链.分享给大家供大家参考,具体如下: 前言 在JS中,我们经常会遇到原型.字面上的意思会让我们认为,是某个对象的原型,可用来继承.但是其实这样的理解是片面的,下面通过本文来了解原型与原型链的细节,再顺便谈谈继承的几种方式. 原型 在讲到原型之前,我们先来回顾一下JS中的对象.在JS中,万物皆对象,就像字符串.数值.布尔.数组等.ECMA-262把对象定义为:无序属性的集合,其属性可包含基本值.对象或函数.对象是拥有属性和方法的数据,为了描述这些事物,便有了原型的概念.

  • javascript 原型与原型链的理解及应用实例分析

    本文实例讲述了javascript 原型与原型链的理解及应用.分享给大家供大家参考,具体如下: javascript中一切皆对象,但是由于没有Class类的概念,所以就无法很好的表达对象与对象之间的关系了. 比如对象A与对象B之间,它们两个是相对独立的个体,互不干扰,对象A修改自身的属性不会影响到对象B. 虽然这很好,但是有一个问题,如果对象A与对象B都有一个方法 run() ,并且代码也一样,那对象A与对象B各自都独立拥有一份 run() 方法的完整代码,这是需要资源去保存的. 一旦我们程序中

  • 浅谈JS的原型和原型链

    1.原型prototype javascript中所有函数都具有这个属性,所有具有prototype属性的对象都是一个函数.prototype的作用是向对象添加一个方法/属性. function persion(){} persion.prototype.name = "xiaoming" console.log(persion.prototype)//{name: "xiaoming", constructor: ƒ} 2.原型指针:__proto__ 如果将上面

  • javascript 原型与原型链的理解及实例分析

    本文实例讲述了javascript 原型与原型链的理解.分享给大家供大家参考,具体如下: javascript中一切皆对象,但是由于没有Class类的概念,所以就无法很好的表达对象与对象之间的关系了. 比如对象A与对象B之间,它们两个是相对独立的个体,互不干扰,对象A修改自身的属性不会影响到对象B. 虽然这很好,但是有一个问题,如果对象A与对象B都有一个方法 run() ,并且代码也一样,那对象A与对象B各自都独立拥有一份 run() 方法的完整代码,这是需要资源去保存的. 一旦我们程序中应用的

  • JavaScript原型继承和原型链原理详解

    这篇文章主要介绍了JavaScript原型继承和原型链原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在讨论原型继承之前,先回顾一下关于创建自定义类型的方式,这里推荐将构造函数和原型模式组合使用,通过构造函数来定义实例自己的属性,再通过原型来定义公共的方法和属性. 这样一来,每个实例都有自己的实例属性副本,又能共享同一个方法,这样的好处就是可以极大的节省内存空间.同时还可以向构造函数传递参数,十分的方便. 这里还要再讲一下两种特色的构造

  • 详解js中的原型,原型对象,原型链

    理解原型 我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法.看如下例子: function Person(){ } Person.prototype.name = 'ccc' Person.prototype.age = 18 Person.prototype.sayName = function (){ console.log(this.name); } var person1 = ne

  • JavaScript对象原型链原理详解

    这篇文章主要介绍了JavaScript对象原型链原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一个js对象,除了自己设置的属性外,还会自动生成proto.class.extensible属性,其中,proto属性指向对象的原型. 对象的属性也有writable.enumerable.configurable.value和get/set的配置方法. 对象的创建方式有三种: 一.使用字面量直接创建. 二.基于原型链创建. 分析上图,要点如

  • JS原型和原型链原理与用法实例详解

    本文实例讲述了JS原型和原型链原理与用法.分享给大家供大家参考,具体如下: Javascript语言的继承机制一直很难被人理解. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain)模式,来实现继承. Brendan Eich设计javascript之初是为了实现网页与浏览器之间交互的一种简单的脚本语言

  • 一篇文章让你搞懂JavaScript 原型和原型链

    本文由葡萄城技术团队原创并首发 转载请注明出处:葡萄城官网 与多数面向对象的开发语言有所不同,虽然JavaScript没有引入类似类的概念(ES6已经引入了class语法糖),但它仍然能够大量的使用对象,那么如何将所有对象联系起来就成了问题.于是就有了本文中我们要讲到的原型和原型链的概念. 原型和原型链作为深入学习JavaScript最重要的概念之一,如果掌握它了后,弄清楚例如:JavaScript的继承,new关键字的原来.封装及优化等概念将变得不在话下,那么下面我们开始关于原型和原型链的介绍

随机推荐