You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functionFather(name,friends){this.name=name;this.friends=friends;}Father.prototype.getName=function(){returnthis.name;};functionSon(name){// 注意: 为了确保 Father 构造函数不会重写 Son 构造函数的属性,请将调用 Father 构造函数的代码放在 Son 中定义的属性的前面。Father.call(this,name,['aaa','bbb']);this.age=22;}vars1=newSon('son1');vars2=newSon('son2');console.log(s1.name);// son1console.log(s2.name);// son2s1.friends.push('ccc','ddd');console.log(s1.friends);// ["aaa", "bbb", "ccc", "ddd"]console.log(s2.friends);// ["aaa", "bbb"]// 子类实例无法访问父类原型中的方法s1.getName();// TypeError: s1.getName is not a functions2.getName();// TypeError: s2.getName is not a function
继承与原型链
什么是原型?
原型(prototype)的定义:给其它对象提供共享属性的对象
哪些数据类型有原型?
只有函数才有 prototype 属性。
基本概念
1. 获取属性的查找规则
如果访问一个对象的属性,首先检查对象是否含有对应的属性,如果含有即得结果;
如果不含有该属性, 则去其原型中查找, 如果原型中含有该属性, 既得结果;
如果原型中依旧没有属性, 就到其原型中的原型去查找, 直到
Object.prototype
。最后还没有则返回 undefined2.修改对象属性
如果修改一个对象的属性, 那么会检查当前对象是否存在该属性, 如果存在即修改, 如果不存在则会给其添加属性.
3.值类型和引用类型的区别
在使用数组赋值的时候,数组是引用类型,存的是一个指针指向,在实例操作后会改变原型中的引用类型。从而影响所有的实例成员
如果实例对象"修改了"原型中的值类型, 那么其实并没有影响到其他的对象
构造函数 new 一个对象
new 命令简化的内部流程,可以用下面的代码表示。
从构造函数到原型对象
构造函数与其原型对象使用
prototype
属性连接,而原型对象中的 constructor 属性指向构造函数。实例对象与两者的连接
实例对象的
__proto__
指向其该对象的原型,这是每一个 JavaScript 对象(除了 null )都具有的一个属性。原型链
对象的
__proto__
指向自己构造函数的prototype
。obj.__proto__.__proto__
...的原型链由此产生,包括我们的操作符 instanceof 正是通过探测obj.__proto__.__proto__
===constructor.prototype
来验证 obj 是否是constructor
的实例。透过一个例子查看
完整的原型链结构上溯
相互关联的原型组成的链状结构就是原型链,也就是
__proto__
的这条线。在下面的结构中,
__proto__
将实例对象,实例对象的原型,实例对象的原型的原型向上连接,直至 `Object.prototype'的上一级null,原型链上溯结束。原型链
【很少单独来使用】
缺点
1.引用类型值的原型属性会被实例共享
2.在创建子类型的实例时,不能向超类型的构造函数中传递参数【很少单独来使用】
借用构造函数
【很少单独来使用】
实现方法
在子类型构造函数的内部调用超类型构造函数(使用 apply 和 call 方法)
优点
解决了原型中引用类型属性的问题,并且子类可以向超类中传参
缺点
子类实例无法访问父类(超类)原型中定义的方法,所以函数的复用就无从谈起了
组合继承
【最常用的继承模式】
又叫伪经典继承,结合原型链继承和构造函数式继承,使用原型链实现对原型属性和方法的继承(函数的复用),又使用构造函数实现对实例属性的继承(每个实例拥有自己的属性)。
优点
避免了原型链继承和构造函数继承的缺点,融合了他们的优点
缺点
无论在什么情况下,都会调用两次超类型构造函数,一次是构造子类型原型,一次是在子类型构造函数内部,解决方法查看
寄生组合式继承
原型式继承
想要保证一个对象与另一个对象
保持类似
的工作可以胜任缺点
包含引用类型值的属性始终会共享相应的属性,无法保证单个实例拥有自己的引用类型属性,这点与原型链模式存在的问题一样
Object.create API
第一个参数是用作新对象的原型对象(可选的),第二个参数是用来扩展新对象属相的另外的对象,在一个参数的情况下,与
object()
方法相同寄生式继承
【有用的模式】
缺点
使用寄生继承为对象添加函数,由于不能做到函数的复用性而降低效率。这一点与构造函数类似
寄生组合式继承
【最理想的继承模式】
优点
istanceof
和isPrototypeOf()
参考文章
The text was updated successfully, but these errors were encountered: