Comments (19)
原型继承
-
优点:复用父级方法
-
缺点:子类没有自己的属性,所有属性方法只能复用父级,处理不好容易跟别的实例串数据
代码如下:
function object(o){
function F(){};
F.prototype = o;
return new F();
};
var Animal = {
叫声: '嘤嘤嘤',
名字: '',
走路: function (方式) {
return 方式;
}
};
var Dog = object(Animal);
Dog['名字'] = '鹍鹍';
Dog['走路'] = function (方式) {
return '唱,' + 方式 + ',rap,打篮球';
};
from step-by-step.
原型链继承
ECMAScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本**是利用原型让一个引用类型继承另一个引用类型的属性和方法。简单回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,加入我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念。 --- 《JavaScript 高级程序设计》 6.3.1 原型链
这是从《JavaScript 高级程序设计》中关于原型链的解释,简单说就是构造函数都有一个原型对象,实例包含原定对象的内部指针,如果让原型对象等于实例,就完成了原型链的继承。
// 构造函数
function Animal(name,six){
this.name = name;
this.six = six;
}
Animal.prototype.cry = function(){
return '嘤嘤嘤';
}
使用原型链继承,使原型对象等于实例。
function Dog(name,age){
this.name=name;
this.age = age;
}
Dog.prototype = new Animal('怪兽','未知');
Dog.prototype.run = function(){
return '鸭子类型';
}
// 完成实例化,检测继承
var erHa = new Dog('哈士奇', 5);
console.info(erHa.name); // => 哈士奇
console.info(erHa.six); // => 未知
console.info(erHa.age); // => 5
console.info(erHa.cry()); // => 嘤嘤嘤
console.info(erHa.run()); // => 鸭子类型
from step-by-step.
一楼的对象真好
from step-by-step.
原型链继承的优点:
1.引用类型的方法被所有实例共享,也就是说可以一个方法,写遍天下,哈哈。
原型链继承的缺点:
1.优点也是缺点,子类实例共享属性,造成实例之间的属性会互相影响。
上代码:
原型链继承
function Animal() {
this.name = ['cat', 'dog', 'person'];
}
Animal.prototype.getName = function (n) {
return this.name[n];
};
function Dog() {
}
Dog.prototype = new Animal();
let dog1 = new Dog();
console.log(dog1.getName(1));
这种实现方式还请大佬指正下算是哪种
function Animal() {
function getName() {
return this.name;
}
return {
getName: getName
}
}
let dog = new Animal();
dog.name = 'dog';
console.log(dog.getName());
from step-by-step.
原型链继承的优缺点?
-
在OO语言中,继承方式通常有两种接口继承和实现继承。
在JavaScript中无法实现接口继承(由于函数没有签名),只支持实现继承(通常依靠原型链来实现继承)。 -
原型链实现继承的基本**是利用原型让一个引用类型继承另一个引用类型的属性和方法。
原型链的缺点?
- 在通过原型链实现继承时,原型实际上会成为另一个类型的实例。所以父类的实例属性实际上会成为子类的原型属性。结果就是所有的子类的实例都会共享父类的实例属性(引用类型的)。
- 在创建子类型的实例时,没有办法在不影响所有实例的情况下,向父类型的构造函数传递参数。
原型链的优点?
- 由以上可知,通过原型链继承的方式,原先存在父类型的实例中的所有属性和方法,现在也能存在于子类型的原型中了。
实现原型链继承
必须基于一个已有对象来实现,即必须有一个对象可以作为另一个对象的基础。
function Animal(o) {
function F(){};
F.prototype = o;
return new F();
}
let dog = {
name: 'origin',
type: 'shiba',
friends: ['KUN', 'Kris'],
intr: function() {
console.log(`${this.name}的朋友有:${this.friends}`);
},
}
let otherDog = Animal(dog);
otherDog.name = '小白';
otherDog.friends.push('小新');
otherDog.intr(); // 小白的朋友有:KUN,Kris,小新
let anotherDog = Animal(dog);
anotherDog.name = '小智';
anotherDog.friends.push('皮卡丘');
anotherDog.intr(); // 小智的朋友有:KUN,Kris,小新,皮卡丘
otherDog.intr(); // 小白的朋友有:KUN,Kris,小新,皮卡丘
dog.intr(); // origin的朋友有:KUN,Kris,小新,皮卡丘
//dog的friends不仅属于dog自己所有,而且也会被otherDog 和 anotherDog 共享。
在没有必要兴师动众地创建构造函数,而只想让一个对象与另一个对象保持类似的情况,原型链继承是完全可以胜任的,不过要记得包含引用值的属性始终都会共享相应的值(就像上面的 friends
和 intr
)。
from step-by-step.
class Animal {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
class Dog extends Animal {
constructor(name, age, eat) {
super(name, age);
this.eat = eat;
}
showEat() {
alert(this.eat);
}
}
let huang = new Dog('阿黄', 2, '狗粮');
huang.showEat();
from step-by-step.
function Animal(name,class){
this.name = name
this.class = class
this.protetype.likeName=function(){
console.log(this.name)
}
this.protetype.likeClass=function(){
console.log(this.class)
}
}
function Dog(){
}
Dog.protetype = new Animal()
var dog = new Dog('燕子','鸟类')
dog.likeName()
from step-by-step.
原型链继承的优缺点?
优点:引用类型的方法被所有实例共享,也就是说一个方法,可以到处使用。
缺点:被所有子类实例共享属性,造成实例之前的属性会相互影响。
function Animal(name){
this.name = name;
}
Animal.prototype.getName=function(){
return this.name
}
function Dog(name,age){
Animal.call( this , name)
this.age = age;
}
Dog.prototype=new Animal()
let dog=new Dog('猫',10);
console.log(dog.getName()+'年龄:'+dog.age)
from step-by-step.
刚看完书想写,上面老哥直接搬出来就不复述了。
- 优点:父类的方法得到了复用。
- 缺点:子类实例共享属性,造成实例间的属性会相互影响
function Developer() {
this.name = "";
this.language = "i user javascript to ";
}
Developer.prototype.sayHello = function() {
return this.name + this.language;
};
function learner() {
this.name = "i'm a fontEndApe,";
this.hobby = "write bug";
}
function bigGod() {
this.hobby = "repair bug";
}
learner.prototype = new Developer();
bigGod.prototype = new Developer();
let cainiao = new learner();
let yutou = new learner();
console.log(cainiao.sayHello() + cainiao.hobby);
console.log(yutou.sayHello() + yutou.hobby); // 子类实例互相影响
from step-by-step.
原型链继承
eg:
function Animal () {
this.type =['origin']
}
Animal.prototype.tellOrigin = function () {
console.log(this.type)
}
Animal.prototype.setOrigin = function (type) {
this.type.push(type)
}
function Dog () {
this.ownType = 'dog'
}
Dog.prototype = new Animal()
Dog.prototype.tellOwnType = function () {
console.log(this.ownType)
}
const dog1 = new Dog()
dog1.setOrigin('evolve')
const dog = new Dog()
dog.tellOwnType() // 'dog'
dog.tellOrigin() // ['origin', 'evolve']
如上面代码所示:
- 优点 公用继承属性
- 缺点 父节点的引用类型属性,被所有子类共用
from step-by-step.
- 原型链继承
原型链继承的基本**是利用原型让一个引用类型继承另一个引用类型的属性和方法。
function Animal(name, age) {
this.name = name;
this.age = age;
}
Animal.prototype.say = function() {
return this.name;
}
function Dog() {
}
//Dog的原型对象是 Animal 的实例
//Dog的原型对象具有 Animal 实例的所有属性和方法,其内部还有一个指针指向Animal的原型
Dog.prototype = new Animal('dog', 2);
Dog.prototype.bark = function() {
console.log('汪汪汪');
}
let Jack = new Dog();
优点:
引用类型的方法被所有实例共享。
缺点:
- 通过原型来实现继承时,原型会变成另一个类型的实例,原先的实例属性变成了现在的原型属性,该原型的引用类型属性会被所有的实例共享。
- 在创建子类型的实例时,没有办法在不影响所有对象实例的情况下给超类型的构造函数中传递参数。
from step-by-step.
原型链是实现继承的主要方法,其基本**是利用原型让一个引用类型继承另一个引用类型的属性和方法。他的优点是可以实现对父级的复用,也正是因为子类间可以共享父类,因此属性间会相互影响。
function Animal(name,age){
This.name = name;
This.age = age;
}
Animal.prototype.sayName = function(){
Return this.name;
}
Function Dog(){
}
Dog.prototype = new Animal(‘yay ’,2);
Dog.protype.sayHi = function(){
Console.log(‘hi’);
}
Var dog = new Dog();
//不会徒手敲代码,几乎是看着楼上小姐姐写完的😩😩
from step-by-step.
原型链是实现继承的主要方法,其基本**是利用原型让一个引用类型继承另一个引用类型的属性和方法。他的优点是可以实现对父级的复用,也正是因为子类间可以共享父类,因此属性间会相互影响。
function Animal(name,age){
This.name = name;
This.age = age;
}
Animal.prototype.sayName = function(){
Return this.name;
}
Function Dog(){
}
Dog.prototype = new Animal(‘yay ’,2);
Dog.protype.sayHi = function(){
Console.log(‘hi’);
}
Var dog = new Dog();
//不会徒手敲代码,几乎是看着楼上小姐姐写完的😩😩
继承是重要的基础知识,本周一起巩固~
from step-by-step.
原型链继承
使用原型链继承实现Dog继承Animal
function Animal(name) {
this.name = name;
}
Animal.prototype.getName = function() {
console.log(this.name)
}
function Dog() {
}
Dog.prototype = new Animal('hashiqi')
let hashiqi= new Dog();
优缺点
优点:父类方法得到了复用
缺点:属性被所有子类实例共享,修改其中一个子类实例的属性,都会被影响。在创建子类实例的时候,不能向父类构造函数传参。
from step-by-step.
原型链继承:
利用原型让一个引用类型继承另一个引用类型的属性和方法。实现的本质是利用一个新类型的实例重写原型对象,让当前的类型的实例对象继承这个新类型实例对象上的属性和方法。
缺点
- 原型对象包含了引用类型的值,那么创建的所有实例都共享这个引用类型的值,会互相影响
- 在创建子类型的实例时,不能向超类型的构造函数传递参数
优点
- 可以代码复用
Dog继承Animal
function Animal(species) {
this.species = species;
}
Animal.prototype.getSpecies = function() {
return this.species;
}
function Dog() {
this.species = 'dog';
}
Dog.prototype = new Animal();
Dog.prototype.bark = function() {
console.log('waaaaaaaaa~');
}
let dog = new Dog();
console.log(dog.getSpecies()); // 'dog'
dog.bark(); // 'waaaaaaaaa~'
from step-by-step.
ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法。
其基本**是利用原型让一个引用类型继承另一个引用类型的属性和方法。
可以理解为原型对象prototype就是两个引用类型的中间媒介。
有三个重要的概念:构造函数,原型,实例
理解三者的关系对理解原型链至关重要。
每一个构造函数都有一个原型对象
原型对象都包含一个指向构造函数的指针
实例都包含一个指向原型对象的内部指针
function Animal(){
this.type='Animal'
}
Animal.prototype.getType = function(){
return this.type
}
function Dog(){
this.name='拉布拉多'
}
Dog.prototype=new Animal()
Dog.prototype.getName = function(){
return this.name
}
var labuladuo=new Dog()
console.log(labuladuo.getType())
原型链可以用来实现继承,但是也存在一些问题。
最主要就是,包含引用类型值的原型。
function SuperType(){
this.colors=["red","blue","green"]
}
function SubType(){}
SubType.prototype=new SuperType()
var instance1=new SubType()
instance1.colors.push("black")
console.log(instance1.colors)
var instance2=new SubType()
console.log(instance2.colors)
第二个问题,在创建子类型的实例时,不能向超类型的构造函数中传递参数。
没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数。
from step-by-step.
function Animal(name) {
this.info = {
name,
};
}
Animal.prototype.sayName = function() {
console.log(this.info.name);
};
function Cat() {}
Cat.prototype = new Animal('xx');
let cat1 = new `Cat();`
let cat2 = new Cat();
console.log(cat1.info.name, cat2.info.name); // xx xx
cat1.info.name = 'yy'
console.log(cat2.info.name) // yy
缺点:如果存在父类属性是引用类型的,所有子类继承后,会相互影响;在 new 子类的时候,不能向父类传递参数。
优点:可以复用父类的方法
from step-by-step.
原型链继承的优缺点是什么?
优点:子能继承父的方法和属性,不需要重新写一遍,能增加代码的服用
缺点:子类只能用父类的属性和方法
使用原型链继承实现Dog继承Animal
function Animal(type, name){
this.type = type
this.name = name
}
Animal.prototype.getNameAndType = function () {
console.log(`name: ${this.name} , type: ${this.type}`)
}
function Dog() {
}
Dog.prototype = new Animal('dog', '小黑')
var dog = new Dog()
dog.getNameAndType()
from step-by-step.
- 基本**:利用原型让一个引用类型继承另一个引用类型的数组和方法。
- 构造函数、原型对象和实例之间的关系:每个构造函数都有一个原型对象,每个原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。
- 优点: 实例会继承父类所有的属性和方法
- 缺点: 优点也是原型链继承的缺点,就有一旦其中某一个实例改变了其中一个属性或者是方法,那么其他的实例也会共享到,且不能向父类型传递参数
function Animal(){
this.species = '哈士奇'
}
Animal.prototype.getSpecies = function(){
return this.species
}
function Dog(){
this.species = '阿拉斯加犬'; // 在子类改变了父类的属性
}
Dog.prototype = new Animal(); // 继承了Animal的属性和方法
var dog1 = new Dog();
var dog2 = new Dog();
console.log(dog1.getSpecies()); // 阿拉斯加犬
console.log(dog2.getSpecies()); // 阿拉斯加犬,所有实例都被实例改变了
·
from step-by-step.
Related Issues (20)
- 寄生组合式继承的基本**是什么?有哪些优缺点? HOT 12
- 实现一个 JSON.stringify HOT 9
- 实现一个 JSON.parse HOT 9
- 实现一个观察者模式 HOT 10
- 使用CSS让一个元素水平垂直居中 HOT 11
- ES6模块和CommonJS模块有哪些差异? HOT 8
- 如何使用Proxy实现简单MVVM HOT 2
- 以下代码的输出的结果为: HOT 7
- 列举常见的JS和CSS兼容性问题
- 介绍下 Set、Map、WeakSet 和 WeakMap 的区别? HOT 1
- Vue组件间是怎么进行参数传递的? HOT 4
- 如果浏览器主线程一直被占据,那么setTimeout会什么时候执行
- rem、em、vh、vw 有什么区别
- flex-grow 与 flex-shrink 的计算规则
- while循环卡死和微任务卡死有什么区别
- sourcemap原理是什么
- 闭包会导致内存泄漏为什么还要使用?
- 前端怎么显示1G的图片甚至1T的图片
- 手写lodash的get方法
- setTimeout回调和fetch回调哪个先执行
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from step-by-step.