4.2继承
**解决:**如果将来发现多个子对象都要使用相同的功能和属性值时,都可以用继承来实现
定义:对于父对象中的成员,子对象无需创建就可以直接使用
**如何实现:**js中的继承都是通过原型对象实现的
4.2.1原型对象
prototype _ proto_
构造函数 子对象
功能:替所有子对象集中保存共有的属性值和方法的特殊父对象
**何时使用:**只要发现多个子对象都需要使用相同的功能和属性值时,都可将相同的属性和方法保存在原型对象中。
如何:
【1】如何创建原型对象:不用自己创建。在定义构造函数时,程序会自动附赠我们一个空的原型对象
【2】如何找到原型对象:构造函数中都有一个自带的属性prototype,指向自己配对的原型对象,可通过 构造函数.prototype访问,如Student.prototype
【3】何时如何继承:new的第2步会自动让心创建的子对象继承构造函数的原型对象,,new会自动为子对象添加_ proto _属性,指向构造函数的原型对象。
【4】如何象原型对象中添加新的共有属性和方法
只能强行赋值
构造函数.prototype.共有方法=function(){ ... }
构造函数.prototype.共有属性=属性值
**原型链:**今后,用子对象.访问对象的成员时,js引擎会先在子对象内部查找自有的属性或方法。如果子对象没有,则js引擎就会自动沿着_ _proto__属性去父元素中国查找;如果在父元素中找到了想要的属性或方法,则和访问访问子对象的一样调用
a. 什么是: 由多级父对象逐级继承形成的链式结构
b. 保存着: 一个对象可用的所有属性和方法
c. 控制着: 属性和方法的使用顺序: 就近原则: 先子级后父级
注意事项:今后,构造函数中一定不要包含方法的定义。所有方法都应该集中定义到原型对象中,所有子对象共有一份
// 继承 原型对象
// 构造函数
function Student(name,age){
this.name=name;
this.age=age;
}
// 输出原型对象
console.log(Student.prototype);
console.log(Student);
// 为原型对象强行添加子对象共有的方法intr()
//将所有子对象共有的方法保存在构造函数里
Student.prototype.intr=function(){
console.log(`I'M ${this.name},age is ${this.age}`);
}
// 创建子对象
var ll=new Student("li lei",11);
var hmm=new Student("han ,meimei",12);
// 子对象中包含__proto__,其中有intr()方法
console.log(ll);
// 子对象可以使用原型对象中的方法
ll.intr();
console.log(hmm);
hmm.intr();
// 亲子鉴定
// 构造函数的prototype与子对象的__proto__是同一个吗
console.log(Student.prototype===ll.__proto__);
console.log(Student.prototype===hmm.__proto__);
console.log(hmm.__proto__===ll.__proto__);
// 修改属性值
Student.prototype.classname="初一2班";
console.log(ll.classname,hmm.classname);
// 错误修改原型对象中的属性
ll.classname="初二2班";
// 没有添加到prototype中的classname中,而是为ll添加了自有属性,自此与其他子对象分道扬镳
console.log(ll.classname);
// 正确修改prototype中的classname属性
Student.prototype.classname="初三2班";
// 发现ll和hmm的班级不再保持一致
console.log(ll.classname,hmm.classname);
4.2.2自有属性和共有属性
自有属性:保存在子对象内部,只归当前子对象自有的属性
共有属性:保存在父对象(原型对象)中,归多个子对象共有的属性
怎样获取:子对象.属性名
如果js引擎发现,要是用的属性不在子对象中,就会沿着_ _proto__属性向父对象继续查找要用的属性
修改属性值:
-
自有属性:子对象.属性名=属性值;
-
共有属性:
i.错误:子对象.共有属性=新值
后果:不会修改原型对象中共有属性,还会给当前子对象添加一个同名的自有属性。自此,这个子对象在这个属性的使用上与其他字对象再无法保持同步!
ii.正确:共有属性必须通过原型对象修改
构造函数.prototype.共有属性=新值
ll.classname="初二2班"; //错误
Student.prototype.classname="初一2班"; //正确
4.2.3内置类型
**定义:**ES5标准中规定的,浏览器已经实现的,我们可以直接使用的类型
**包含:**11种
{
tring, Number, Boolean
Array, Date, RegExp, Math(不是类型,已经是一个{}对象)
Error
Function Object
global(全局作用域对象,在浏览器中被window代替)
}
每种类型一定有2部分组成:
- 构造函数:负责创建该类型的子对象
- 原型对象:负责为该类型所有子对象集中保存共有的属性值和方法定义
添加:
如果经常使用一个功能,但是原型对象中没有提供,我么可以自定义一个函数保存在原型对象中,这样可以在任意处使用
构造函数.prototype.新方法=function(){…}
// 如果需要多次使用相同功能的函数,就将其添加至类型中的原型对象中的方法中
Array.prototype.sum=function(){
console.log(`调用一次自定义的sum函数`)
var res=0;
// this指的是将来调用这个共有函数的.前的某个子对象
for(var i=0;i<this.length;i++){
res+=this[i];
}
return res;
}
var arr1=[1,2,3];
console.log(arr1.sum());
/*
in关键字:
for in循环完成数组遍历会出现的问题:
因为 in的遍历,不但会遍历数组的下标,还会自动沿着继承关系去遍历父对象中的所有者子对象的可用成员
*/
Array.prototype.sum1=function(){
console.log(`111`);
var res=0;
for(var i in this){
res +=this[i];
}
return res;s
}
var arr2=[2,3,4];
console.log(arr2.sum1());