YvetteLau / Step-By-Step

不积跬步,无以至千里;
704 stars 66 forks source link

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

Open YvetteLau opened 5 years ago

KRISACHAN commented 5 years ago

原型继承

代码如下:

   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 commented 5 years ago

一楼的对象真好

clark-maybe commented 5 years ago

原型链继承的优点:

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 commented 5 years ago
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 commented 5 years ago
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 commented 5 years ago

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

  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 commented 5 years ago

原型链继承

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 commented 5 years ago

原型链继承的优缺点?

原型链的缺点?

原型链的优点?

  • 由以上可知,通过原型链继承的方式,原先存在父类型的实例中的所有属性和方法,现在也能存在于子类型的原型中了。

实现原型链继承

必须基于一个已有对象来实现,即必须有一个对象可以作为另一个对象的基础。

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 commented 5 years ago

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

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 commented 5 years ago

原型链继承

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 commented 5 years ago
  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 commented 5 years ago

原型链是实现继承的主要方法,其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。他的优点是可以实现对父级的复用,也正是因为子类间可以共享父类,因此属性间会相互影响。 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 commented 5 years ago

原型链是实现继承的主要方法,其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。他的优点是可以实现对父级的复用,也正是因为子类间可以共享父类,因此属性间会相互影响。 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 commented 5 years ago

原型链继承

使用原型链继承实现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 commented 5 years ago

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

缺点

  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 commented 5 years ago

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 commented 5 years ago
 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 commented 5 years ago

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

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

使用原型链继承实现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 commented 5 years ago
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());  // 阿拉斯加犬,所有实例都被实例改变了

·