摘要:前记在维基百科中继承的含义是使子类别具有父类别的属性和方法,或者说子类构造的对象直接拥有父类对象的属性。但是在中并没有子类和父类的概念,也没有类和实例的区分,的继承是靠原型链来实现的。
前记
在维基百科中继承的含义是使子类别具有父类别的属性和方法,或者说子类构造的对象直接拥有父类对象的属性。
但是在JavaScript中并没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,JavaScript的继承是靠prototype(原型链)来实现的。
prototype继承实现我曾写过一篇名为原型和原型链的文章,那时候说明了原型和原型链是什么,那继承只要在它的原型链中添加公有属性就可以了
假如我们写一个构造函数Human
function Human(name){ this.name = name//构造函数可以生成新对象,this就是这个新对象 }
然后在Human的原型链上添加函数run
Human.prototype.run = function (){ console.log(this.name + "在跑") return undefined }
这样当我们用Human构造一个对象时候
let a = new Human("lgm") //Human {name: "lgm"} // name: "lgm"/ // __proto__: // run: ƒ () // constructor: ƒ Human(name) // __proto__: Object
现在我们再写一个构造函数Man
function Man(name){ this.name = name//this新生成的对象 this.gender: "男"//this新生成的对象 }
然后在Man的原型链上添加函数fight
Man.prototype.fight = function (){ console.log(this.name + "会打架") }
这样用Man构造一个对象就是
let b = new Man("lgm") //Man {name: "lgm"} // name: "lgm"/ // gender: "男" // __proto__: // fight: ƒ () // constructor: ƒ Man(name) // __proto__: Object
当我们想要Man继承Human的属性的时候,就可以知道,只要
Man.prototype.__proto__ = Human.prototype
修改Man
function Man(name){ Human.call(this, name) this.gender: "男"//this新生成的对象 }
就可以完成继承了,让我们来试一下
再次构造一个Man对象
let lgm = new Man("lgm") //Man {name: "lgm", gender: "男"} // gender: "男" // name: "lgm"/ // __proto__: Human // fight: ƒ () // constructor: ƒ Man(name) // __proto__: // run: ƒ () // constructor: ƒ Human(name) // __proto__: Object
由此我们可以看到,Man继承了Human中的run()函数,但是有一个问题
直接操作__proto__是不属于ECMA规范的,在IE中直接操作并不可行,我们需要换一种写法
var f = function(){} f.prototype = Human.prototype Man.prototype = new f()
这样是使用了new的特性,让我们来试一下,然后再次构造一个Man对象
let lgm = new Man("lgm") //Man {name: "lgm", gender: "男"} // gender: "男" // name: "lgm"/ // __proto__: Human // fight: ƒ () // __proto__: // run: ƒ () // constructor: ƒ Human(name) // __proto__: Object
可以看到,效果是一样的
class语法糖在ES6语法中,新增了一个叫做class的语法,专门用来实现继承,上面代码通过class改写如下
class Human { constructor(name) { this.name = name } run() { console.log("我叫" + this.name + ",我在跑") return undefined } } class Man extends Human {//Man.prototype.__proto__ = Human.prototype constructor(name) { super(name)//Human.call(this, name) this.gender = "男" } fight() { console.log(this.name + "会打架") } }两种方法的优劣
prototype继承写法麻烦,但是简单易懂,而class继承的写法虽然简单,但难以理解
并且,原型链继承添加继承属性的话会会非常简单,只需
Human.prototype.headNumber = "1"
而class继承如果需要添加继承属性会非常麻烦
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/97590.html
摘要:此用来定义通过构造器构造出来的对象的原型,构造器内部的代码用来给对象初始化。 对象继承 VS 类继承 在 class-based 的面向对象的世界里,要出现对象,必须先有类。类之间可以继承,类再使用 new 操作创建出实体,父子对象之间的继承体现在父类和子类上。你不能说 对象 a 继承了对象 b,只能说 class A 继承了 class B,然后他们各自有一个实例a、b。 JS中实现...
摘要:首先捋清楚类和对象的关系类比如人类,指的是一个范围对象比如某个人,指的是这个范围中具体的对象中的作为构造函数时,就是一个类,通过操作符,可以返回一个对象。 JS中的类与类的继承 我们知道,JS中没有类或接口的概念,即不能直接定义抽象的类,也不能直接实现继承。不过,为了编程的方便,我们可以在 JS 中模拟类和继承的行为。首先捋清楚类和对象的关系: 类:比如人类,指的是一个范围; ...
摘要:的继承方式属于原型式继承,非常灵活。当使用关键字执行类的构造函数时,系统首先创建一个新对象,这个对象会继承自构造函数的原型对象新对象的原型就是构造函数的属性。也就是说,构造函数用来对生成的新对象进行一些处理,使这个新对象具有某些特定的属性。 继承这个东西在Javascript中尤其复杂,我掌握得也不好,找工作面试的时候在这个问题上栽过跟头。Javascript的继承方式属于原型式继承,...
摘要:对象经典对象创建与继承模式组合模式创建对象中创建一个对象的方式多种多样,每种方式都有自己缺点或者优点,具体的可以参考而组合使用构造函数模式和原型模式来创建自定义类型算是最常见的方式了。 title: JS对象(3)经典对象创建与继承模式 date: 2016-09-28 tags: JavaScript 0x01 组合模式创建对象 JS 中创建一个对象的方式多种多样,...
摘要:原型对象是由创建的,因此原型对象的构造函数是构造函数也可以是称为对象,原型对象也就继承了其生父构造函数中的数据,也同时继承了原型对象的数据。当然这条原型链中的数据,会被还是还是这类构造函数继承,但是不会被这些继承,他们不处于同一个链条上。 js中,Function的本质是什么?Object的本质又是什么?js中有几条原型链? showImg(https://segmentfault.c...
阅读 828·2021-11-22 11:59
阅读 3234·2021-11-17 09:33
阅读 2309·2021-09-29 09:34
阅读 1942·2021-09-22 15:25
阅读 1957·2019-08-30 15:55
阅读 1323·2019-08-30 15:55
阅读 532·2019-08-30 15:53
阅读 3348·2019-08-29 13:55