理解JavaScript中的原型、原型链、五条原型规则

1、原型的定义

每个JavaScript对象都有一个原型对象(简称原型),这个原型是由该对象的构造函数所定义的(JavaScript自动创建),并且对象继承原型的所有属性和方法。

原型,准确叫法是“原型对象”,也就说说“原型本身也是一个对象”来的; 我们创建的每个构造函数都有一个prototype属性,这个属性是一个指针,这个指针指向“原型对象”。也就是说“构造函数名.prototype”是一个对象。
我们要记住这一点:原型其实就是对象来的。

2、原型的五条重要规则及其示例

  1. 所有的引用类型(数组、对象、函数)都具有对象特性,即可以自由扩展属性(除了 “null” 以外)

例如:可以自由扩展a属性,以及扩展更多的属性

//json对象扩展属性
var obj = {};
obj.a = 100;
//数组扩展属性
var arr = [];
arr.a = 100;
//函数扩展属性
function fn(){}
fn.a = 100;
  1. 所有的引用类型(数组、对象、函数)都有一个隐式原型(__proto__)属性,它也是一个对象。

例如:默认存在(打印出来看下)

console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);
  1. 所有函数都有一个显式原型(prototype)属性,这个属性也是一个对象。

例如:默认存在(打印出来看下)

console.log(fn.prototype)
  1. 所有的引用类型(数组、对象、函数)的__prpto__属性值指向它自身的构造函数的prototype属性值

例如:obj是一个对象,它的构造函数是Object

console.log(obj.__proto__ === Object.prototype); // true

在这里插入图片描述

  1. 当试图去获取一个对象的属性时,如果这个对象本身没有这个属性,那么就会去它的__proto__(即它的构造函数的prototype属性)中寻找。

例如:存在原型链的情况下属性的查找顺序

// 定义构造函数
function Foo(name,age){
	this.name = name;
	this.age = age;
}
Foo.prototype.alertAge = function (){
	alert(this.age);
}
// 创建一个实例对象
var f = new Foo("winne",22);
// 在实例对象下面添加个方法
f.consoleName = function (){
	console.log(this.name);
}

// 测试访问属性
f.name;            // 对象自身下就可以找到
f.alertAge();     // 在 f.__proto__下找到
f.consoleName();  // 对象自身下就可以找到
f.toString();     // 去f.__proto__.__proto__ 下面找

实例对象f下面本身有name和age这两个属性,后面又在自身下面扩展了consoleName属性,所以f.consoleName()直接在自身对象下就能找到这个属性了。
f.alertAge()在自身下找不到这个属性,而需要通过它的__proto__(它的构造函数的prototype属性(Foo.prototype))下面去寻找。
f.toString() 需要去f.__proto__.__proto__下面寻找。f.__proto__其实就是Foo.prototype ,找不到就会继续往Foo.prototype的隐式原型下面找,因为Foo.prototype也是个对象,是对象的话它的构造函数就是Object,所以就是往 Object.prototype下面寻找。

原型链的最外层是:Object.prototype
原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链。

在这里插入图片描述

注意查找顺序是,先在自身下面寻找看是否有找到,如果找不到再通过原型链进行往上查找,查找的最顶层是Object.prototype。
当为实例对象本身有这个属性时,这个属性就会“屏蔽”(注意是屏蔽,而不是覆盖)原型对象中保存的同名属性。

为什么要使用原型?
如果不使用原型对象,每次使用构造函数创建对象时,每创建一个对象都会实例化一次,都会开辟一个新的内存空间,极大浪费内存和降低效率。使用原型对象,可以共享属性和方法(即共享内存)。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值