javascript高级部分02----面向对象继承

1.原型的指向问题
1.1原型链最终指向问题:

 function Person(name, age) {
            this.name = name;
            this.age = age;
        }
        console.log(Person.prototype.constructor);
        // 构造函数Person的实例化对象的__proto__属性与构造函数的prototype属性指向同一对象,而构造函数的prototype属性也是一个对象,那么他也有__proto__属性,指向哪里?
        console.log(Person.prototype.__proto__.constructor); //打印结果是Object,Object也有prototype属性,Object的prototype属性也是一个对象,其上面也有__proto__属性
        console.log(Object.prototype.__proto__);  //打印结果为null,这说明这个属性是原型链的顶层

在这里插入图片描述
1.2给构造函数的prototype添加属性后,原型的指向问题

      原型的指向问题
        function Student(name, age) {
            this.name = name;
            this.age = age;
        }

        Student.prototype = {
            say: function() {
                console.log('说话');
            }
        }
        var stu1 = new Student('张三', 14);
        console.log(stu1);
        console.log(stu1.__proto__.constructor);  //打印结果为Object
        console.log(Student.prototype.constructor);  //打印结果为Object
在构造函数上面赋值方法,原型构造器指向Object,因为会改变指向问题,所以不推荐使用,常用的方法是在构造函数上面.属性就可以,不会改变原型的指向

        function Student(name, age) {
            this.name = name;
            this.age = age;
        }

        Student.prototype.say = function() {
            console.log('说话');
        }
        var stu1 = new Student('张三', 14);
        console.log(stu1);
        console.log(stu1.__proto__.constructor); //打印结果为Student
        console.log(Student.prototype.constructor); //打印结果为Student

2.原型继承问题:

 // 原型继承
        function Person(name, age) {
            this.name = name;
            this.age = age;
        }

        function Student(name, age) {
            this.name = name;
            this.age = age;
        }
        Student.prototype.className = '一班';
        Student.prototype.playLove = function() {
            console.log(this.name + '爱搞对象');
        }
        Student.prototype = new Person('小王', 18); //改变Student的原型
        console.log(Student.prototype.constructor == Person); //true  
        Student.playLove() //Student.playLove is not a function
        Student的原型被改变,此时指向的是Person,而Person中并没有playLove的方法,所以会报错,怎么解决这个问题?
        -->在Student原型中添加完属性后,把这一步骤放在改变Student原型指向的后面,这样,既可以获得最新指向的属性
        ,而能获取在Student原型中添加的属性

Student.prototype = new Person('lisi', 18); //改变Student的原型
        Student.prototype.className = '一班';
        Student.prototype.playLove = function() {
                console.log(this.name + '爱搞对象');
            } //在Student原型中添加属性,放在原型指向改变的后面,既可以得到Person中的属性,也可以得到,现在在原型中添加的属性
        var stu1 = new Student('小明', 19)
        console.log(Student.prototype.constructor == Person); //true  
        console.log(Student.prototype);
        Student.prototype.playLove()
        console.log(stu1);
        stu1.playLove() //小明爱搞对象

3.构造函数继承
call,apply和bind

  call方法的作用
  1.1 函数名.call()可以实现函数的调用
        function fn1() {
            console.log('我是函数1');
        }
        fn1();
        fn1.call()
 1.2 call() 可以改变this的指向
 var name = '张三';
        var obj1 = {
            name: '李四',
            age: '12',
            say: function() {
                console.log(this.name + '学习');
            }
        };
        obj1.say.call() //call里面不传递参数,this指向的是window
        obj1.say.call(obj1) //call里面传递的第一个参数可以改变this指向,此时this指向的是obj1;
1.3  call() 方法实现继承
     call会改变this的指向,如果有参数this指向该参数中的第一个参数,剩余的参数是一个参数列表
function Person(name, age) {
            this.name = name;
            this.age = age;
            console.log(this);  //Student {score: 100, name: "lilei", age: 13, study: ƒ}   通过Person.call()改变this指向,此时this指向的是实例化对象

        };

        function Student(score, name, age) {
            this.score = score;
            this.study = function() {
                console.log(this.name + '爱学习');
            }
            console.log(this);  //Student {score: 100, study: ƒ}
            Person.call(this, name, age);    //通过call方法,可以使Student继承Person里面的name和age的属性
            console.log(this);   //Student {score: 100, name: "lilei", age: 13, study: ƒ}
        }

        var stu1 = new Student(100, 'lilei', 13)
        console.log(stu1);
    apply方法的使用:apply可以改变this指向,但是apply方法里面只能传递两个参数,第一个是this的指向,第二个是数组
 function Person(name, age) {
            this.name = name;
            this.age = age;
            console.log(this);

        };
        function Student(score, name, age) {
            this.score = score;
            this.study = function() {
                console.log(this.name + '爱学习');
            }
            console.log(this);
            Person.apply(this, [name, age]);
            console.log(this);
        }
        var stu1 = new Student(100, 'lilei', 13)
        console.log(stu1);
   bind方法的使用:bind可以改变this指向,但是bind方法返回的是一个函数,不能立即执行,需要调用(call和apply都能够立即执行)
var name = 'lilei';
        var obj1 = {
            name: 'zhangsan',
            age: 15,
            say: function() {
                console.log(this.name + '说话');
            }
        };
        obj1.say.bind()
        var O1 = obj1.say.bind();
        var O2 = obj1.say.bind(obj1)
        console.log(O1);
        //ƒ () { console.log(this.name + '说话');}
        console.log(O2);
        //ƒ () { console.log(this.name + '说话');}

        // O1,和O2返回的都是一个函数
        O1(); //lilei说话
        O2(); //zhangsan说话
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值