美文网首页Web
JS中的原型和原型链,继承

JS中的原型和原型链,继承

作者: 追逐_chase | 来源:发表于2019-08-13 17:25 被阅读18次
    web.jpeg
    <script>
     //构造函数--
     function Person(name,age){
        this.name = name || "TT",
        this.age = age || 18;
     };
     console.dir(Person);
     var per = new Person("cc",15);
      console.dir(per);
    
    
    </script>
    
    image.png

    创建的构造函数 系统默认有一个prototype原型属性,指向 原型对象, 而原型对象有一个constructor属性 构造器 执行 构造函数, 我们通过 构造函数创建的实例对象有一个__proto__属性 指向构造函数的原型的原型对象

    image.png
    • 原型链:是实例对象和原型对象之间的关系,这个关系是通过实例对象的原型(__proto__)来联系的,__proto__指向 构造函数的原型对象
    1. 原型的指向是可以发生改变的
    //构造函数--
     function Person(name,age){
        this.name = name || "TT",
        this.age = age || 18;
     };
    
    
     console.dir(Person);
    
     var per = new Person("cc",15);
      console.dir(per);
    
      function Student(){
    
      };
    
      //原型对象的指向 发生变化
       Student.prototype = new Person();
    
       var stu = new Student();
    
       console.log(stu.name);
       
    
    2.继承

    上面我们知道,原型的指向是可以更改的,那么继承是说什么? 继承就是把共有的属性和方法,传递给其子类或者子构造函数

    2.1 原型继承
    <script>
        
            function Person(name,age){
                this.name = name;
                this.age = age;
            }
            Person.prototype.sayHi = function(){
                console.log("您好");
            };
            //构造函数
            function Student(){
            }
          //更改原型指向, 继承person的属性和方法
          //注意:Student的原型对象的constructor属性指向的也是 Person 需要更正
            Student.prototype = new Person("cc","15")
            var stu = new Student();
            stu.sayHi();
            console.log(stu.name,stu.age);
            
        
        </script>
    
    • 缺点:stu不能传值给父构造函数,属性值重复
    2.2 借用构造函数 ---解决上面的问题
    2.2.1 借用方法call,apply

    借用其他对象的属性或者方法,ES给我们提供了有2个这样的属性方法call,apply

    // call 和 apply 方法
    //借用其他对象的方法
    
    var obj = {
        name:"cc",
        show:function(name ){
            console.log("展示自己的方法" + name);
            
        }
    };
    
    var obj1 = {
        name:"tt",
        age:18
    };
    
     obj.show();
     // obj1借用obj的方法 
    //call借用其他对象的方法
    //参数一:要那个对象借用
    //参数二:借用对象方法的参数聊表
     obj.show.call(obj1,obj1.name);
    
     //apply方法借用
     //参数一:要那个对象借用
     //参数二:借用对象方法的参数数组成员,有几个参数,给这个数组传递几个变量
     obj.show.apply(obj1,[obj1.name]);
    
    2.2.2 借用构造函数
    <script>
    
        function Person(name,age){
            this.name = name;
            this.age = age;
        }
     //借用构造函数:构造函数名字.call(当前对象,属性,属性,属性....);
        //解决了属性继承,并且值不重复的问题
        //缺陷:父级类别中的方法不能继承
        function Student(name,age,score){
            Person.call(this,name,age);
            this.score = score;
          
     
        }
    
        var stu = new Student("cc",15,90);
        console.log(stu.name,stu.age,stu.score);
        
        
    
    </script>
    

    缺陷:父级类别中的方法不能继承

    2.3组合继承 = 原型 + 借用构造函数
    <script>
    
        //组合继承 = 原型继承 + 借用构造函数继承
    
        function Person(name,age,sex){
            this.name = name;
            this.age = age;
            this.sex = sex;
        };
    
        Person.prototype.sayHi = function(){
            console.log("hello,您好");
            
        };
    
        function Student (name,age,sex,score){
            //借用构造函数
            Person.call(this,name,age,sex);
            this.score = score;
        };
    
        //通过原型继承 访问方法
        Student.prototype = new Person();
    
        var stu = new Student("cc",15,"男",90);
        stu.sayHi();
        console.log(stu.name,stu.age,stu.sex,stu.score);
        
    </script>
    
    3.对象的小补充

    我们知道对象是一个 key-value的键值组合,在JS中key是一个字符串,如果key对应的是其他的对象的话,那么这个对象的内部就会调用toString()方法,转化为字符串

    <script>
    
      var a = {name:"cc"};
      console.log(a.toString());   // 转为字符串"[object object]";
      var c = {};
      c[a] = "test1"; // c[[object object]] =  "test1";
      console.log(c);
     // 打印结果:{[object Object]: "test1"}
    </script>
    
    
    打印结果.png
    <script>
    
      var a = {name:"cc"};
      var c = {};
      var b = {}; 
      c[a] = "test1"; 
      c[b] = "test2";
      console.log(c[a]);
      打印结果是:  test2 
    原因是: key的值相同,覆盖掉了原本的
    </script>
    
    
    4.拷贝
    4.1浅拷贝 :拷贝的是 地址,
    var obj = {name:"cc",age:"18",car:{
        type:"大众"
    }};
    
    var obj2 = {};
    
    for(var key in obj){
        obj2[key] = obj[key];
    }
    
    console.log(obj2);
    
    obj2.car.type = "TT";
    
    console.log(obj);
    
    image.png
    4.2深拷贝:拷贝的数据内容
    1. 先提供一个函数,这个函数有2个参数,一个是目标对象,一个要拷贝属性的对象
    2. 需要判断第一参数是否有值,如果没有,赋值为空对象
    3. for..in遍历第2参数, 判断属性值的类型
      1.如果是值类型(函数),直接赋值
      2.如果是引用类型,再调用一次这个方法,拷贝这个属性存储的内容
    <script>
    
    /*
     原理:
    
    
    */
    
    
        function deepCopy(targetObj,copyObj){
            targetObj = targetObj || {};
            for(var key in copyObj){
                //判断是不是实例属性
                if(copyObj.hasOwnProperty(key)){
                 //判断 对应的key的value是不是对象
                    if(typeof copyObj[key] == "object"){
                        //处理动态的添加属性
                        targetObj[key]  = Array.isArray(copyObj[key]) ? [] :{};
                        
                        deepCopy(targetObj[key],copyObj[key]);
    
                    }else{
                        targetObj[key] = copyObj[key];
                    }
    
                }
            }
    
        }
    
    
        var obj = {name:"cc",age:"18",car:{
        type:"大众"
       }};
    
    var obj2 = {};
    
    deepCopy(obj2,obj);
    
    obj2.car.type = "上海荣威";
    console.log(obj2);
    console.log(obj);
    
    
    
    
    
    
    </script>
    
    
    
    image.png

    相关文章

      网友评论

        本文标题:JS中的原型和原型链,继承

        本文链接:https://www.haomeiwen.com/subject/ydevjctx.html