-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JavaScript常见的六种继承方式 #20
Labels
JavaScript
javaScript
Comments
Open
细细看 各种联系才能摸清楚,感谢分享 |
这里可以直接 |
这样只是把子类原型和父类原型指向了同一个对象,子类只能继承父类的原型方法,但不能继承实例属性和方法,不能完全实现继承 |
方式五: 组合继承优化2我认为也可以这样写:
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
前言
面向对象编程很重要的一个方面,就是对象的继承。A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法。这对于代码的复用是非常有用的。
大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承。传统上,JavaScript 语言的继承不通过 class(ES6 引入了class 语法),而是通过“原型对象”(prototype)实现。那么在JS中常见的继承方式有几种呢?
如需本文源码,请猛戳 常见的六种继承方式
如果觉得文章对你有些许帮助,欢迎在我的GitHub博客点赞和关注,感激不尽!
方式一、原型链继承
这种方式关键在于:子类型的原型为父类型的一个实例对象。
但这种方式实现的本质是通过将子类的原型指向了父类的实例,所以子类的实例就可以通过__proto__访问到 Student.prototype 也就是Person的实例,这样就可以访问到父类的私有方法,然后再通过__proto__指向父类的prototype就可以获得到父类原型上的方法。于是做到了将父类的私有、公有方法和属性都当做子类的公有属性
子类继承父类的属性和方法是将父类的私有属性和公有方法都作为自己的公有属性和方法,我们都知道在操作基本数据类型的时候操作的是值,在操作引用数据类型的时候操作的是地址,如果说父类的私有属性中有引用类型的属性,那它被子类继承的时候会作为公有属性,这样子类1操作这个属性的时候,就会影响到子类2。
s1中play属性发生变化,与此同时,s2中play属性也会跟着变化。
另外注意一点的是,我们需要在子类中添加新的方法或者是重写父类的方法时候,切记一定要放到替换原型的语句之后
特点:
缺点:
Student.prototype = new Person()
之后执行,不能放到构造器中方式二: 借用构造函数继承
这种方式关键在于:在子类型构造函数中通用call()调用父类型构造函数
这种方式只是实现部分的继承,如果父类的原型还有方法和属性,子类是拿不到这些方法和属性的。
特点:
缺点:
方式三: 原型链+借用构造函数的组合继承
这种方式关键在于:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用。
这种方式融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。不过也存在缺点就是无论在什么情况下,都会调用两次构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数的内部,子类型最终会包含父类型对象的全部实例属性,但我们不得不在调用子类构造函数时重写这些属性。
优点:
缺点:
方式四: 组合继承优化1
这种方式通过父类原型和子类原型指向同一对象,子类可以继承到父类的公有方法当做自己的公有方法,而且不会初始化两次实例方法/属性,避免的组合继承的缺点。
但这种方式没办法辨别是对象是子类还是父类实例化
优点:
缺点:
方式五: 组合继承优化2
借助原型可以基于已有的对象来创建对象,
var B = Object.create(A)
以A对象为原型,生成了B对象。B继承了A的所有属性和方法。同样的,Student继承了所有的Person原型对象的属性和方法。目前来说,最完美的继承方法!
方式六:ES6中class 的继承
ES6中引入了class关键字,class可以通过extends关键字实现继承,还可以通过static关键字定义类的静态方法,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。
ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。
需要注意的是,class关键字只是原型的语法糖,JavaScript继承仍然是基于原型实现的。
优点:
缺点:
参考文章
The text was updated successfully, but these errors were encountered: