什么是原型与原型链

前言

此文参照了阮一峰大神在自己博客写的几篇关于JS继承原理的文章,在此直接放出连接:


JS一切皆是对象?

JS中一切皆是对象吗?这句话其实是错的,首先从设计语言上来考虑,如果一切皆是对象,那就不会分这么多基础类型了,那为什么非对象类型的其他类型值可以调用对象API呢,这里就引出了JS设计核心之一的原型与原型链


什么是原型(prototype)

1、
要解决这个问题,就得清楚会设计原型(prototype)这个属性。
首先带来一个自阮一峰博客的例子

  function DOG(name){
  
    this.name = name;
    
  }

这里我们把他改成我们能理解的样子(有关this,详细请参阅this的MDN docs)

  function 狗(名字){
  
    this.名字 = 名字;
    
  }

当我们运行new+“”,并填入“名字”时,我们就得到了一个狗对象的实例

   第一只狗 = new 狗(大黄);
   
   第一只狗.名字  //大黄

我们把“狗”称为“第一只狗”的构造函数(consturctor),而“第一只狗”称为"狗"对象的实例

所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

2、

但是,用构造函数生成实例对象,有一个缺点,那就是无法共享属性和方法。

比如,在“狗”对象的构造函数中,设置一个实例对象的共有属性“毛色”。

  function 狗(名字){
  
    this.名字 = 参数名字;
    this.毛色= "黄色"
    
  }

然后我们生成两个“狗”实例

 第一只狗 = new 狗(大黄);
 第二只狗 = new 狗(二黄);
	
  第一只狗.毛色  //黄色
  第二只狗.毛色  //黄色

这两个对象的“毛色”属性是独立的,修改其中一个,不会影响到另一个,每一个实例对象,都有自己的属性和方法的副本,这不仅无法做到数据共享,也是极大的资源浪费。

  //这里把第一只狗的毛色修改成黑色
  第一只狗.毛色= "黑色"
  
 console.log(第二只狗.毛色); //黄色
 //这里可以看到第二支狗的毛色依然是黄色

3、

根据这一点,才有了如今的prototype属性,prototype属性是一个对象,里面包含了所有需要共享的属性和方法,而不需要共享的属性和方法,则放在构造函数里。

实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是本地的,另一种是引用的。

下面通过设置“狗”.prototype属性来改写之前的例子

  function 狗(名字){
    this.名字 = 名字;
  }
  
  狗.prototype = {"毛色" = "黄色"}
 
   第一只狗 = new 狗(大黄);
   第二只狗 = new 狗(二黄);
   
  console.log(第一只狗.毛色) // 黄色
  console.log(第二只狗.毛色) // 黄色

如果现在对狗.prototype进行修改,则第一只狗和第二只狗的毛色会一起发生变化

	狗.prototype = {"毛色" = "黑色"}
	
  console.log(第一只狗.毛色) 
  // 黑色
  console.log(第二只狗.毛色) 
  // 黑色

什么是原型链

1、
无论是什么类型的值,在实例化之后都会带有一个"_ _ proto_ “的属性,该属性指向其继承而来的上一级的prototype,在此把” _ proto_ _"称为子原型,prototype称为父原型。

下面以实例化的数字“1”为例

var num = 1;   //
num.__proto__ === Number().prototype;
num.__proto__.__proto__  ===  Number().prototype.__proto__  ===  Object.prototype
num.__proto__.__proto__.__proto__ ===  
    Number().prototype.__proto__  ===  
      Object.prototype.__proto__  ===  null

从以上例子可以看出,由于Object.prototype.__ proto __ 的值为null,意味着Object.prototype没有相对的父原型来继承,所以Object.prototype可以认为是最顶级的父原型,所有的子原型都继承于Object.prototype,我们这种子原型引用父原型的关系,称之为原型链

因为Object.prototype是最顶级的父原型,所有类型的值都能调用或者临时调用其存储的方法和属性,所以才有“JS一切皆是对象”的说法,其实这种说法是完全错误的,比较严谨的说法应该是“JS内一切类型的数值都能视为对象”。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值