【JavaScript】深入理解JS中的原型与原型链

一、构造函数弊端

1、构造函数中的实例每调用一次方法,就会在内存中开辟一块空间,造成内存浪费。

// 创建一个构造函数
function Person(name, age){
       this.name = name; 
       this.age = age;
       this.sayHello = function(){
       console.log("大家好,我是"+this.name)
      }
}	
 
 // 实例化对象
 var p1 = new Person('张无忌',22);
 var p2 = new Person('赵敏',20);
 var p3 = new Person('周芷若',21);

 // 函数调用
 p1.sayHello();
 p2.sayHello();
 p3.sayHello();

 console.log(p1.sayHello === p2.sayHello, p2.sayHello === p3.sayHello);
//false
//flase

二、原型

1、简单来说

原型有两个,prototype显示原型和__proto__隐式原型。
(1)函数中必然有prototype,除内置对象、浏览器对象、闭包对象。
(2)产生于函数定义时,给函数对象添加prototype属性,显示原型,给原型对象添加constructor属性, 值为函数。

prototypefunction Fn(){}
console.dir(Fn)
var obj ={}
console.log(obj.__proto__===Object.prototype)
console.log(Fn.prototype.__proto__===Object.prototype)

(1)对象中必然有__proto__
(2)产生于实例化对象时,JS引擎自动给实例添加____proto__属性, 值为构造函数的 prototype属性的值。

this.__proto__ = Fn.prototype  // this是实例对象

2、总的来说

(1)原型:在构造函数中,有一个属性prototype,它指向了一个对象,这个对象就是原型对象,这个对象的所有属性和方法,都会被构造函数所拥有。

 function Person(name, age){
  }		
 console.log(Person.prototype)
 	
// {constructor: ƒ}
// constructor: ƒ Person(name, age)
// __proto__: Object

(1)普通函数调用,prototype没有任何作用,构造函数调用,该类所有实例有隐藏一个属性(proto)指向函数的prototype。(实例的隐式原型指向类的显示原型)

//实例的隐式原型指向构造函数的显示原型
 console.log(p1.__proto__ === Person.prototype);
//true

(3)原型就相当于一个公共区域,可以被类和该类的所有实例访问到。
在这里插入图片描述(4)所以我们在定义类时,公共属性定义到构造函数里面,公共的方法定义到构造函数外部的原型对象上

3、本质

普通object实例

4、优点

(1)资源共享,节省内存
(2)改变原型指向,实现继承

5、缺点

查找数据的时候有的时候不是在自身对象中查找

三、 constructor构造函数

对象原型(proto)和构造函数(prototype)里面都有一个属性叫做constructor。
constructor称为构造函数,因为他指回构造函数本身。
在这里插入图片描述

1、记录该对象引用哪个构造函数

console.log(p1.__proto__.constructor);
console.log(Person.prototype.constructor);		
/*ƒ Person(name, age){
            this.name = name; 
            this.age = age;
        }
		
ƒ Person(name, age){
			this.name = name; 
			this.age = age;
		}
  */

2、让原型对象重新指向原来的构造函数

//以对象形式进行赋值,修改原型对象方法,手动指会原来构造函数
Person.prototype = {
	//新添加的对象,把原来的对象覆盖掉了
	constructor:Person,
	sayhello:function(){
		console.log("大家好,我是"+this.name)
	},
	kongfu:function(){
		console.log("我会功夫");
	}
}		
   //实例化对象
var p1 = new Person('张无忌',22);
var p2 = new Person('赵敏',20);
var p3 = new Person('周芷若',21);
	
   console.log(p1.__proto__.constructor);
console.log(Person.prototype.constructor);
//指向object ----> 指向Person

四、原型链

1、原型链是什么

实际上是指隐式原型链,和显示原型关系不大,只和显示原型产生实例一瞬间起作用。

从对象的__proto__开始,连接所有的对象,就是对象查找属性或方法的过程。
隐式原型链

2、查找对象属性基本流程

(1)当访问一个对象属性时,先往实例化对象在自身中寻找,找到则是使用。
(2)找不到(通过_proto_属性)去它的原型对象中找,找到则是使用。
(3)没有找到再去原型对象的原型(Object原型对象)中寻找,
直到找到Object为止,如果依然没有找到,则返回undefined

五、终极原型链

(1)大写Function是生成构造函数的工具,Function创建了所有构造函数。大写Function自己生成了自己,隐式原型指向自己的显示原型
(2)所有的实例都是Object创建的
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值