YvetteLau / Step-By-Step

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

原型式继承的基本思想是什么?有什么优缺点? #36

Open YvetteLau opened 5 years ago

AILINGANGEL commented 5 years ago

思想: 借助原型基于已有的对象创建新的对象,同时不需要创建自定义类型。

function inherit(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

从上面的代码可以看出来,如果传入inherit函数的对象包含一个引用类型的值,那么修改这个新创建的对象继承来的这个值会影响传入的这个对象,因此通过这个对象创建的其他的新对象也会受到影响。

function inherit(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

let o = {
    name: 'test',
    friends: ['a', 'b']
}

let a = inherit(o);
let b = inherit(o);
a.friends.push('c');
console.log(a.friends); // [ 'a', 'b', 'c' ]
console.log(b.friends); // [ 'a', 'b', 'c' ]
mdchun commented 5 years ago

原型式继承

function object(o){
  function F(){}
  F.prototype = o
  return new F()
}

缺点:

  1. 属性值包含引用类型值时,会影响所有实例的属性值
  2. 创建子类型实例时,不能向超类型的构造函数中传递参数
riluocanyang commented 5 years ago

原型式继承

就是将传入的对象作为创建对象的原型,模拟Object.create()实现。

function createObj(o) {
  function F(){}
  F.prototype = o;
  return new F()
}
var obj = {
  name: 'zhangsan',
  colors: ['red', 'blue']
}
let o1 = createObj(o);
o1.name = 'lisi';
o1.colors.push('green');
let o2 = createObj(o);
console.log(o1.name, o1.colors);  // 'lisi', ['red', 'blue', 'green']
console.log(o2.name, o2.colors);  //  'zhangsan', ['red', 'blue', 'green']

修改o1.name的值,o2.name的值并未发生改变,并不是因为o1和o2有独立的 name 值,而是因为o1.name = 'lisi' 是给o1添加了 name 值,并非修改了原型上的 name 值。

优缺点: 优点: 缺点:和原型链继承一样,创建的对象会共享属性,彼此影响。

sinaine commented 5 years ago

原型式继承

   function object(obj) {
         //定义了一个临时构造函数
         function F() {}
         //将这个临时构造函数的原型指向了传入进来的对象。
         F.prototype = obj;
         //返回这个构造函数的一个实例。该实例拥有obj的所有属性和方法。
         //因为该实例的原型是obj对象。
         return new F();
     }

优点是这种继承借助原型并基于已有的对象创建新对象,同时还不必因此创建自定义类型 缺点是引用类型的对象属性会相互影响

chongyangwang commented 5 years ago

原型式继承 将传入的对象 作为创建对象的原型

实现:

function createObj(obj){
 function F(){};
 F.prototype= obj;
 return new  F()
}

var obj ={
   age:25,
   like:['唱',‘跳‘,‘rap‘]
}

var a1 = createObj(obj)
a1.age =30
a1.like.push('篮球')
var a2 = createObj(obj)
console.log(a1.like)
console.log(a2.like)

image

angelbeatsying commented 5 years ago

基本思想是让一个原型对象指向另一个类型的实例 缺点:因为下面的所有实例都会共享这些属性,所以一个实例下修改某个引用类型值,也会反映到其余实例中 优点:每个新创建的实例可以共享属性,减少内存消耗

yelin1994 commented 5 years ago
function Dog (obj) {
     function Animal () {}
     Animal.prototype = obj
    return new Animal()
}
const obj = {
    name: 'animal',
    age: [12, 13, 132]
}
var dog = Dog(obj)
var dog1 = Dog(obj)
dog.name = 'hello'
dog.age.push(99)
console.log(dog.name) // hello
console.log(dog1.name) // animal
console.log(dog1.age) // [12, 13, 132, 99]

其大致是用Dog 返回一个包装,对象。Dog 以 obj 为模板,定义一个Animal的函数,使Animal 指向模板,这样就能使 new Animal的对象,能够使用obj里面的私有属性, 但同时他又是一个浅拷贝,复杂的数据类型,会被多个对象共用,毕竟复杂对象,栈中存放的是堆的地址

yangyiqiqia commented 5 years ago

原型式继承的基本思想是:借助原型可以基于已有的对象创建新对象。其本质是执行对给定对象的浅拷贝。 function object(o){ Function F(); F.prototype = o; Return new F(); } 在object()函数内部先创建了一个临时的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回了这个临时类型的一个新实例。 vat person = { Name:’yay’, Friends:[‘Shelby’,’court’,’van’] }; Var anotherPerson = object(person); AnotherPerson.name = ‘Greg ’; AnotherPerson.friends.push(‘rob’); Var yetAnotherPerson = object(person); YetAnotherPerson.name = ‘Linda’; YetAnotherPerson.friends.push(‘Barbie’);

Console.log(person.friends);//Shelby,court,van,Rob,Barbie

缺点:包含引用类型值的属性始终都会共享相应的值。 优点:可以在不预先定义构造函数的情况下实现继承。

jodiezhang commented 5 years ago

原型式继承 优点:这种方法并没有使用严格意义上的构造函数。借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。

function object(o){
  function F(){}
  F.prototype = o
  return new F()
}

var person={
    name:'Jodie',
    friends: ["Jack","Jim","Van"]
}

var anotherPerson=object(person)
anotherPerson.name="Linda"
anotherPerson.friends.push("Rob")

console.log(person.name)
console.log(person.friends)
Jodie
[ 'Jack', 'Jim', 'Van', 'Rob' ]

相当于创建了person对象的副本。 或者换成

var person={
    name:'Jodie',
    friends: ["Jack","Jim","Van"]
}

var anotherPerson=Object.create(person)
anotherPerson.name="Linda"
anotherPerson.friends.push("Rob")

console.log(person.name)
console.log(person.friends)

缺点:仍然和原型链继承的缺点一样,引用类型对于新的实例会跟着改变。

Cain-kz commented 5 years ago

原型式继承 本质就是一个浅克隆,以一个对象为模板复制出新的对象。 优点:每个新创建的实例对象可以共享属性,减少内存消耗 缺点:共享属性,会影响到其它的实例。

function qtclone(o){
    var F=function(){}
    F.prototype = o;
    return new F();
  }
  var obj = {
    name:'ghost',
    age:22,
    show:function(){
      return this.name +','+this.age;
    }
  }
  let obj2 =qtclone(obj)
  let obj3 =qtclone(obj)
  obj2.__proto__.hosts='8080';
  console.log(obj2.name,obj.age,obj.show(),obj3.hosts) //ghost 22 ghost,22,8080
lawrence998 commented 5 years ago

原型式继承:先创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例``

ZadaWu commented 5 years ago

原型式继承

原型式继承的思想是借用原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型. 在object()函数内部,先创建一个临时性的构造函数,将传入的对象作为这个构造函数的原型,最后返回这个函数的新函数。

function object(o) {
    function F() {}
    F.prototype = o
    return new F();
}

var person = {
    name: 'Nico',
    friends: ['shlby', 'huu']
}

var anotherPerson = object(person)
anotherPerson.name = "Greg" // 为实例添加自身属性以覆盖原型对象上的同名属性

优点:每个新创建的实例可以共享属性,减少内存消耗 缺点:和原型链继承一样,创建的对象会共享属性,彼此影响。

MissNanLan commented 5 years ago

var dog1 = Object(dog); //  dog 对象作为dog1 对象的基础,在ES5当中,这里可以写成Object.create dog1.species = ' 泰迪'; dog1.color = 'brown'; dog1.skills.push('acting');

var dog2 = Object(dog); dog2.species = ' 吉娃娃'; dog2.color = 'grey'; dog2.skills.push('show'); skills: ["jump","climb","catch","run"];

console.log(dog.skills); // ["jump", "climb", "catch", "run", "acting", "show"] console.log(dog.species); // 吉娃娃