一文完全理解JS原型链,实现完美继承

全文没有废话,需字斟句酌

需要理解的两个重要概念

  1. 原型链只是js搜索对象属性的机制,和继承没有本质上的关系,你需要先掌握js是如何在原型链里搜索对象属性的
  2. 继承的本质是复用父对象的属性,而这些属性分为两类:实例属性和原型属性(位于原型链上的属性)

继承的最终目标:

子对象的实例属性包括:父对象的实例属性+子对象自定义的实例属性

子对象的原型属性:父原型的属性(__proto__和constructor不同,这是重点后面解释) + 子原型自定义的属性

理解Object.create()方法:

// 解析Object.create(o) 以o为原型创建对象(o作为新对象原型链上一级 且o没有实例属性)
		function create(o) {
			function F() {}
			F.prototype = o;
			return new F();
		}
		

 要理解Object.create()又得先理解new操作符:

// 解析new操作符
		function myNew(Func) {
			var o = new Object(); // 创建一个新对象
			Func.apply(o); // 以新对象为环境执行构造函数
			o.__proto__ = Func.prototype; // 新对象[[Prototype]]指向构造函数的原型对象
			return o;
		}

 先说new操作符:

  1. Func.apply(o) 指定对象的实例属性 实例属性由new操作符的构造函数提供
  2. o.__proto__ = Func.prototype 建立原型链,指定对象的原型属性

接着就能看懂Object.create(o)的代码:

  1. 创建的对象以o为原型,o指定了对象的原型属性
  2. 以一个空函数定义实例属性 所以 新对象没有实例属性

最后再来看实现继承的逻辑就很清楚了:

  1. 子构造函数很简单 调用父构造函数就可以了
  2. 构造子原型对象sp是重点 sp要复用父原型的属性,然后sp.__proto__ = 父原型,sp.constructor = 子构造函数

复用父原型属性很简单,var sonPrototype = Object.create(Parent.prototype); 同时完成了原型链的连接

子构造函数本身复用了父构造函数,直接指定它即可 sonPrototype.constructor = Son;

具体代码如下,

// 定义对象 构造函数定义实例属性(一般是属性) 原型对象定义共享属性(一般是方法)
                // 定义父对象
		function Parent(name) {
			this.name = name;
			console.log('Parent');
		}
		Parent.prototype.sayName = function() {
			console.log(this.name);
		}

// 继承 借用父构造函数复用父实例属性 原型对象复用父原型属性 想要理解 必须理解Object.create()和new
		// 定义子对象
		function Son(name, age) {
			Parent.call(this, name); // 复用父实例属性
			this.age = age;
			console.log('Son');
		}
		// 两步构造子原型对象
		var sonPrototype = Object.create(Parent.prototype); // 提取出父原型属性 构造函数为空函数
		sonPrototype.constructor = Son; // 构造函数改为子构造函数 复用父实例属性
		Son.prototype = sonPrototype; // 将上面构造好的子原型对象赋给子原型

		// 创建子对象
		var s = new Son('mm', 18);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值