继承、原型继承、prototype、call和apply的继承、原型链继承、原型继承中的注意事项、深浅拷贝、

继承

j

子类获得父类已有的方法和属性;
作用:子类可以实用父类的属性和方法,并且可以添加自己新的
属性和方法,从而提高代码的复用性。
* 基类  派生类

原型继承

案例

function Animal(name){
    this.name=name;
}
Animal.prototype.eat=function(){
   console.log("Animal eat");
}
//原型继承实现的方法:用子类的原型对象指向父类的实例化
  对象
Human.prototype=new Animal("凡凡");
function Human(id){
     this.id=id;
}  
Human.prototype.makeTools=function(){
    console.log("Human makeTools");
}
let h=new Human("007");
h.name="jj";
console.log(h.name);
h.eat();
console.log(h.id);
h.makeTools();
//对象instanceof 类型:判断该对象是否为该类型,返回布尔值
console.log("h instanceof Human");//true  人是人
console.log("h instanceof Animal");//true 人是动物
let a =new Animal("jj");
console.log("a instanceof Human");//false 动物不是人
console.log("a instanceof Animal");//true 动物是动物

prototype

prototype属性:
         对于类而言,prototype保存着所有实例的方法,即
所有的实例方法都是在prototype中保存着,平时我们在使用实
例方法时,虽然用对象直接调用,但是真正的保存是在
prototype中。在继承中prototype的作用更加明显;
        我们创建的每个函数都有一个属性是prototype(原型)
,这是属性是一个指针,指向一个对象,该对象的用途是包含所
有实例共享的属性和方法。        
         

案例1,原型方法的调用


function Student(newId,newName,newAge){
     this.Id=newId;
     this.Name=newName;
     this.Age=newAge;
}
Student.prototype.sleep=function(){
    console.log("晚上睡不着,上课睡最香")
};
let s=new Student(1,"大黄",18);
let s1=new Student(2,"小黄",19);
s.sleep();
//晚上睡不着,上课睡最香
s1.sleep();
//晚上睡不着,上课睡最香
console.log(s.Id,s.Nmae,s.Age);
//1,"大黄",18
console.log(s1.Id,s1.Nmae,s1.Age);
//2,"小黄",19

prototype 案例2
多个原型属性的区别

接着上个prototype案例
function Student(newId,newName,newAge){
       this.Id=newId;
       this.Nmae=newName;
       this.newAge;
}
Student.prototype.tall="180";
Student.prototype.sleep=function(){
  "晚上睡不着,上课睡最香"
};
let s=new Student(1,"大黄",18);
let s1=new Student(2,"小黄",19);
console.log(s.tall)//输出为180
s.tall="666";//相当给S的实例对象添加了新tall方法
               属于个人行为不影响原型属性tall=180;
console.log(s.tall);//此时输出的是666;
delete s.tall;
console.log(s1.tall);//输出180;               

prototype.案例3
给官方函数添加方法

依旧利用prototype;
Array.prototype.max=function(){
   //求数组最大值;
   let t=this[0];
   for(var i=0;i<this,length;i++){
   if(t<this[i]){
      t=this[i];}
   }
  return t;
}

apply()和call()

每个函数dui都有两个非继承而来的方法apply()和call(),这
两个方法的用途都是来调用函数(在特定的作用域中),实际上
等于设置函数体内的this对象的值。调用函数实际上就是调用
该函数对象的call内部方法;

案例

function Monkey(newId,newName){
     this.Id=newId;
     this.Name=newName;
}
function Snake(newId,newName){
    this.Id=newId;
    this.Name=new Name;
}
function eat(str,str1){
consloe.log(this.Name+"吃"+str+"和"+str1);
}
let m=New Monkey(1,"泰山");
let s=New Snake(2,"小可爱");
eat.call(m,"香蕉","牛奶");
eat.call(s,"老鼠","青蛙");
eat.apply(m,["香蕉","牛奶"]);
eat.apply(s,["老鼠","青蛙"]);
//call()和apply()区别:apply的第二个参数得用[]括起来;
function fun(){
    let m=New Monkey(1,"泰山");
    eat.apply(m,arguments);
}
fun("香蕉","牛奶")

原型链继承

让子对象的原型指向父对象的实例,父对象的原型指向爷爷对
象的实例,依次类推,就形成了原型链

案例

 <script>
    function Animal(name){
        this.name=name;
    }
    Animal.prototype.eat=function(){
        console.log("Animal eat")
    };
    Human.prototype=new Animal("凡凡");
    function Human(id){
        this.id=id;
    }
    Human.prototype.makeTools=function(){
        console.log("Human makeTools")
    };
    Student.prototype=new Human("007");
    function Student(score){
        this.score=score;
    }
    Student.prototype.study=function(){
        console.log("Student study");  
    }
         //原型链继承:访问属性的原理,现在自己的类中
         查找属性或者方法,找不到就去找父类(向上查找)
         let s=new Student(100);
    console.log(s.name,s.id,s.score);
    //输出为 凡凡 007 100
    s.eat(); //输出Animal eat
    s.makeTools();//输出Human makeTools
    s.study();//输出Student study

原型链继承中的注意事项

//注意事项:
//1.无法在构造子类对象时,初始化由父类派生给子类的属性
//2.实现继承关系,必须在添加子类方法之前
//3.继承关系实现后,子类的原型对象不能再修改

深浅拷贝

内置类型与引用类型在内存中村春的区别
//内置基本类型:只有一块栈空间,保存的是变量的数值;
//引用类型:有两块空间,一块栈空间保存地址,一块堆
空间保存内容
---------------------------------------------
引用类型才有深拷贝和浅拷贝的概念
//浅拷贝:只拷贝内容但不开辟空间,两个变量共享一块堆空间
let arr1=[1,2,3];
let arr2=arr1;
arr1[0]="凡凡";
arr2[1]="潘玮柏"
console.log(arr1,arr2);
// 都是 凡凡 潘玮柏  3;

深拷贝

//深拷贝:开辟空间且赋值
let arr1=[1,2,3];
let arr2=[];
for(var i=0;i<arr1.length;i++){
   arr2.push(arr1[i])
}
console.log(arr2);//输出结果为[1,2,3];




//..扩展运算符:赋值的是引用类型的内容,不再是地址
arr2=[...arr1];
arr1[0]="凡凡";
console.log(arr1,arr2);
//输出结果是 凡凡 ,2,3;
             1,2,3;





function Student(name,id){
this.name=name;
this.id=id;
}
Student.protitype.copy=function(){
let item=new Student (this.name,this.id);
return item;
}
let s1=new Student("凡凡",1);
let s2=s1.copy();
s1.name="黄黄";
console.log(s1,s2);
// 黄黄,1;s1 修改了参数,生效
   凡凡, 1;
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值