Open YvetteLau opened 5 years ago
原型式继承
function object(o){
function F(){}
F.prototype = o
return new F()
}
缺点:
就是将传入的对象作为创建对象的原型,模拟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 值。
优缺点: 优点: 缺点:和原型链继承一样,创建的对象会共享属性,彼此影响。
原型式继承
function object(obj) {
//定义了一个临时构造函数
function F() {}
//将这个临时构造函数的原型指向了传入进来的对象。
F.prototype = obj;
//返回这个构造函数的一个实例。该实例拥有obj的所有属性和方法。
//因为该实例的原型是obj对象。
return new F();
}
优点是这种继承借助原型并基于已有的对象创建新对象,同时还不必因此创建自定义类型 缺点是引用类型的对象属性会相互影响
原型式继承 将传入的对象 作为创建对象的原型
实现:
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)
基本思想是让一个原型对象指向另一个类型的实例 缺点:因为下面的所有实例都会共享这些属性,所以一个实例下修改某个引用类型值,也会反映到其余实例中 优点:每个新创建的实例可以共享属性,减少内存消耗
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里面的私有属性, 但同时他又是一个浅拷贝,复杂的数据类型,会被多个对象共用,毕竟复杂对象,栈中存放的是堆的地址
原型式继承的基本思想是:借助原型可以基于已有的对象创建新对象。其本质是执行对给定对象的浅拷贝。 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
缺点:包含引用类型值的属性始终都会共享相应的值。 优点:可以在不预先定义构造函数的情况下实现继承。
原型式继承 优点:这种方法并没有使用严格意义上的构造函数。借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。
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)
缺点:仍然和原型链继承的缺点一样,引用类型对于新的实例会跟着改变。
原型式继承 本质就是一个浅克隆,以一个对象为模板复制出新的对象。 优点:每个新创建的实例对象可以共享属性,减少内存消耗 缺点:共享属性,会影响到其它的实例。
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
原型式继承:先创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例``
原型式继承的思想是借用原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型. 在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" // 为实例添加自身属性以覆盖原型对象上的同名属性
优点:每个新创建的实例可以共享属性,减少内存消耗 缺点:和原型链继承一样,创建的对象会共享属性,彼此影响。
function object(o){
function F(){}
F.prototype = o;
return new F();
}
var dog = {
species: '比熊犬',
color: 'gold',
skills: ["jump","climb","catch","run"]
}
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); // 吉娃娃
思想: 借助原型基于已有的对象创建新的对象,同时不需要创建自定义类型。
从上面的代码可以看出来,如果传入inherit函数的对象包含一个引用类型的值,那么修改这个新创建的对象继承来的这个值会影响传入的这个对象,因此通过这个对象创建的其他的新对象也会受到影响。