关于混合继承的一些笔记和总结

本文深入探讨了JavaScript中的混合继承,包括原型链继承和借用构造函数继承的局限性,以及如何通过组合继承克服这些局限,实现属性的复用和独立。通过具体代码示例,解释了Animal如何继承Person的属性和方法,同时重写特定方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 什么是混合继承?

原型链继承和借用构造函数继承。这两种模式都存在各自的缺点,所以组合继承是将二者结合到一起,从而发挥二者之长。即在继承过程中,既可以保证每个实例都有它自己的属性,又能做到对一些属性和方法的复用.

案例

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

		Person.prototype.saySex = function() {
			console.log("性别分为男女")
		}

		Person.prototype.sayName = function() {
			console.log(this.name)
		}

		function Animal(name) {
			//通过call 使Person的this指向Animal的this
			Person.call(this,name);
		}

		Animal.prototype = Object.create(Person.prototype)

		//因为 动物性别不是男女 所以我们需要改写 saySex
		Animal.prototype.saySex = function() {
			console.log("性别分为公母")
		}
		var dog = new Animal("狗")
		dog.sayName()
		dog.saySex()              复制代码

结果如下:


总结:

为什么 Animal.prototype = Object.create(Person.prototype)  而不是 Animal.prototype = new Person()

Object.create

        function Person(name) {
    		this.name = name;
    	}
    	Person.prototype.saySex = function() {
    		console.log("男")
    	}
    	var person1 = Object.create(Person);
    	console.log(person1.saySex) // undefined
    	console.log(person1.name) // "Person"复制代码

为什么会出现这样的结果?

首先看看 Object.create到底干了啥?

                Object.create =  function (o) {
		    var F = function () {};
		    F.prototype = o;
		    return new F();
		};复制代码

通过代码我们知道 

1)因为Object.create内部的新对象是new F()创建的,跟Person构造函数没有关系,所以不能访问到Person中的属性

2)调用person1.saySex 时首先判断person1对象有没有相应的方法,如果没有,则查找person1的原型链上有没有该方法,person1的原型属性是Person构造函数(可以通过person1.__proto__来证明), 构造函数没有saySex方法,自然也就是undefined了。

3) return new F()后F被销毁,Object.create创建对象是创建一个拥有指定原型和若干个指定属性的对象,也就是说可以任意指定原型,甚至是null。所以在上述中像o.prototype添加属性不被继承

如果换成  Object.create(Person.prototype); 会是什么情况呢?

        function Person(name) {
    		this.name = name;
    	}
    	Person.prototype.saySex = function() {
    		console.log("男")
    	}
    	var person1 = Object.create(Person.prototype);
    	console.log(person1.saySex)
    	console.log(person1.name) 复制代码

输出结果如下:


new方法创建对象

new Object()方法的实质是,使用引用类型Object的构造函数创建了一个新的实例,这个实例拥有Object默认的方法如toString、toLocaleString等。经历了以下四个步骤:

1) 创建一个新对象; 

2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象) ; 

3) 执行构造函数中的代码(为这个新对象添加属性) ; 

4) 返回新对象。

当我们执行:

        function Person() {
    		
    	} 
        var person1 = new Person();
复制代码

实际上是按照如下过程执行的:

                var person1  = {};
		person1.__proto__ = Person.prototype;
		Person.call(person1);复制代码

其实在new 的过程中 我们执行了构造函数的方法,而在create 过程中我们并没有执行构造函数的方法

Object.create()兼容性写法

            function create(obj) {
		  	if (Object.prototype.toString.call(obj) !== '[object Object]') {
		    	throw new Error('need an object type');
		  	}
		  	function CreatePrototype() {

		  	}
		  	CreatePrototype.prototype = obj;
		  	return new CreatePrototype();
		}复制代码

使用:

Animal.prototype = create(Person.prototype)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值