Skip to content
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

原型链继承的优缺点是什么?使用原型链继承实现 Dog 继承 Animal #34

Open
YvetteLau opened this issue Jun 24, 2019 · 19 comments

Comments

@YvetteLau
Copy link
Owner

No description provided.

@KRISACHAN
Copy link

KRISACHAN commented Jun 24, 2019

原型继承

  • 优点:复用父级方法

  • 缺点:子类没有自己的属性,所有属性方法只能复用父级,处理不好容易跟别的实例串数据

代码如下:

   function object(o){
      function F(){};
      F.prototype = o;
      return new F();
    };
   var Animal = {
      叫声: '嘤嘤嘤',
      名字: '',
      走路: function (方式) {
         return 方式;
     }
   };
  var Dog = object(Animal);
  Dog['名字'] = '鹍鹍';
  Dog['走路'] = function (方式) {
      return '唱,' + 方式 + ',rap,打篮球';
   };

@nwjf
Copy link

nwjf commented Jun 24, 2019

一楼的对象真好

@clark-maybe
Copy link

原型链继承的优点:

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());

@Vailee
Copy link

Vailee commented Jun 24, 2019

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();

@chongyangwang
Copy link

chongyangwang commented Jun 24, 2019

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()

@Cain-kz
Copy link

Cain-kz commented Jun 24, 2019

原型链继承的优缺点?
优点:引用类型的方法被所有实例共享,也就是说一个方法,可以到处使用。
缺点:被所有子类实例共享属性,造成实例之前的属性会相互影响。

 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)

@woyiweita
Copy link

woyiweita commented Jun 24, 2019

原型链继承

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()); // => 鸭子类型

@Sakura-pgh
Copy link

原型链继承的优缺点?

  • 在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 共享。

在没有必要兴师动众地创建构造函数,而只想让一个对象与另一个对象保持类似的情况,原型链继承是完全可以胜任的,不过要记得包含引用值的属性始终都会共享相应的值(就像上面的 friendsintr)。

@into-piece
Copy link

into-piece commented Jun 24, 2019

刚看完书想写,上面老哥直接搬出来就不复述了。

  • 优点:父类的方法得到了复用。
  • 缺点:子类实例共享属性,造成实例间的属性会相互影响
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); // 子类实例互相影响

@yelin1994
Copy link

原型链继承

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']

如上面代码所示:

  • 优点 公用继承属性
  • 缺点 父节点的引用类型属性,被所有子类共用

@YvetteLau
Copy link
Owner Author

  1. 原型链继承

原型链继承的基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。

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();

优点:

引用类型的方法被所有实例共享。

缺点:

  1. 通过原型来实现继承时,原型会变成另一个类型的实例,原先的实例属性变成了现在的原型属性,该原型的引用类型属性会被所有的实例共享。
  2. 在创建子类型的实例时,没有办法在不影响所有对象实例的情况下给超类型的构造函数中传递参数。

@yangyiqiqia
Copy link

原型链是实现继承的主要方法,其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。他的优点是可以实现对父级的复用,也正是因为子类间可以共享父类,因此属性间会相互影响。
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();
//不会徒手敲代码,几乎是看着楼上小姐姐写完的😩😩

@YvetteLau
Copy link
Owner Author

原型链是实现继承的主要方法,其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。他的优点是可以实现对父级的复用,也正是因为子类间可以共享父类,因此属性间会相互影响。
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();
//不会徒手敲代码,几乎是看着楼上小姐姐写完的😩😩

继承是重要的基础知识,本周一起巩固~

@riluocanyang
Copy link

riluocanyang commented Jun 26, 2019

原型链继承

使用原型链继承实现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();

优缺点

优点:父类方法得到了复用
缺点:属性被所有子类实例共享,修改其中一个子类实例的属性,都会被影响。在创建子类实例的时候,不能向父类构造函数传参。

@AILINGANGEL
Copy link

原型链继承:
利用原型让一个引用类型继承另一个引用类型的属性和方法。实现的本质是利用一个新类型的实例重写原型对象,让当前的类型的实例对象继承这个新类型实例对象上的属性和方法。

缺点

  1. 原型对象包含了引用类型的值,那么创建的所有实例都共享这个引用类型的值,会互相影响
  2. 在创建子类型的实例时,不能向超类型的构造函数传递参数

优点

  1. 可以代码复用

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~'

@jodiezhang
Copy link

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)

第二个问题,在创建子类型的实例时,不能向超类型的构造函数中传递参数。
没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数。

@wuzhong1030
Copy link

 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 子类的时候,不能向父类传递参数。
优点:可以复用父类的方法

@ZadaWu
Copy link

ZadaWu commented Jul 4, 2019

原型链继承的优缺点是什么?

优点:子能继承父的方法和属性,不需要重新写一遍,能增加代码的服用
缺点:子类只能用父类的属性和方法

使用原型链继承实现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()

@MissNanLan
Copy link

  • 基本思想:利用原型让一个引用类型继承另一个引用类型的数组和方法。
  • 构造函数、原型对象和实例之间的关系:每个构造函数都有一个原型对象,每个原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。
  • 优点: 实例会继承父类所有的属性和方法
  • 缺点: 优点也是原型链继承的缺点,就有一旦其中某一个实例改变了其中一个属性或者是方法,那么其他的实例也会共享到,且不能向父类型传递参数
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());  // 阿拉斯加犬,所有实例都被实例改变了

·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests