JS面向对象高级


JS面向对象高级
思考如下问题
function Person(){
    this.foot = 2;
        this.head=1;
}
“人类”对象的构造函数
function Man(name){
    this.name=name;
}
“男人”对象的构造函数
问题:如何使“男人”继承“人”呢?
原型链继承-prototype属性
常见的方法
Man.prototype = new Person();
Man的prototype指向一个Person的实例,所有"男人"的实例,就能继承Person了
注意
如果替换了prototype对象:o.prototype = {};
要为新的prototype对象加上constructor属性,并将这个属性指回原来的构造函数:o.prototype.constructor = o;
function Person(){
        this.foot = 2;
        this.head=1;
}
function Man(name){
        this.name=name;
}
Man.prototype = new Person();
Man.prototype.constructor = Man;
var man = new Man("张三");
原型链继承-直接继承prototype(new一个父类的实例)
对上一种方法的改进
由于Person对象中,不变的属性都可以直接写入Person.prototype。所以,可以让Man()跳过 Person(),直接继承Person.prototype
经验
优点:效率比较高(不用执行和建立Person的实例了)
缺点:Man.prototype和Person.prototype现在指向了同一个对象,任何对Man.prototype的修改,都会反映到Person.prototype,父子集会会互相影响.
function Person(){
}
Person.prototype.foot = 2;
Person.prototype.head = 1;
function Man(name){
        this.name=name;
}
Man.prototype = Person.prototype;
Man.prototype.constructor = Man;
var man1= new Man("张三");
利用空对象作为中介(不影响父集)
利用空对象作为中介
空对象,几乎不占内存
修改Student的prototype对象,不会影响到Person的prototype对象
function Person(){}
Person.prototype.foot = 2;
Person.prototype.head = 1;
function Man(name){
        this.name=name;
}
var F= function(){};
F.prototype = Person.prototype;
Man.prototype = new F();
Man.prototype.constructor = Man;
var man1= new Man("张三");
利用空对象作为中介-封装为函数(可以解决重复的事情,封装完毕,我们在使用,只需要调用就可以了)
function Person(){}
Person.prototype.foot = 2;
Person.prototype.head = 1;
function Man(name){
        this.name=name;
}
function extend(Child(子集),Parent(父集)){
        var F= function(){};
        F.prototype = Parent.prototype;
        Child.prototype = new F();
        Child.prototype.constructor = Child;
    }
extend(Man,Person);
var man1 = new Man("张三");
构造函数绑定
掌握构造函数绑定实现继承
且必须在函数里调动
他们的作用都是用来改变this的指向
call(一个一个的传参)
apply(需要使用数组来传参)
call和apply方法的异同
function.call(thisObj[, arg1[, arg2[, [,...argN]]]])调用一个对象的一个方法,以另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法
function.apply(thisObj[, argArray])应用某一对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法
call和apply方法调用示例:
两方法产生的作用相同,传参不同
function Person(address,sex){
        this.foot = 2;
        this.head = 1;
        this.address = address;
        this.sex = sex;
}
function Man(name){
        //使用call或apply实现继承
        //Person.call(this,"北京","女");
        Person.apply(this,["北京","女"]);
        this.name = name;
}
var man1 = new Man("张三");
bind方法
执行完返回的是一个函数
第一个参数也是需要改变this的指向对象
call和apply的区别是执行完返回的是一个函数
传参的第一种方式:
obj.fn.bind(obj2,"爱爬山","爱看书")();//必须在加()调用函数
传参的第二种方式:
obj.fn.bind(obj2)("爱爬山","爱看书");
组合继承
也叫伪经典继承
将原型链继承和构造函数继承组合在一块
原型链实现对原型属性和方法的继承
借用构造函数实现对实例属性的继承
function Person(){
        this.foot = 2;
        this.head=1;
         this.color="red";
}
Person.prototype.sayColor=function(){
         alert("我爱的颜色是:"+this.color);
}
function Man(name){
        Person.call(this);
        this.name=name;
}
Man.prototype = new Person();
Man.prototype.constructor = Man;
var man1= new Student("张三");
var man2= new Student("李四");
拷贝继承
把父对象的所有属性和方法,拷贝进子对象
将父对象的prototype对象中的属性,一一拷贝给Child对象的prototype对象
function Person(){}
Person.prototype.foot = 2;
Person.prototype.head = 1;
Person.prototype.saySelf=function(){
        alert("我有:"+this.foot+"只脚和"+this.head+"个头");
}
function Man(name){
        this.name = name;
}
function extend2(Child,Parent){
        var p = Parent.prototype;
        var c = Child.prototype;
        for(var i in p){
            c[i] =p[i];
        }
}
extend2(Man,Person);
var man1 = new Man("张三");
man1 .saySelf();
练习题:
创建构造函数Person,添加属性姓名(name)、语文成绩(chinese)、数学成绩(math);添加三个方法,分别返回姓名、语文和数学成绩
创建构函数Student,继承Person的属性和方法,并添加属于自己的属性年龄(age),添加属于自己的方法,返回年龄
创建Student的对象,并在页面上输出实例的姓名、语文、数学成绩和年龄

<body>

    <p>姓名: <span class="name"></span></p>

    <p>语文: <span class="chinese"></span></p>

    <p>数学: <span class="math"></span></p>

    <p>身高: <span class="height"></span></p>

    <script>

        var myname = document.getElementsByClassName("name")[0];

        var chinese = document.getElementsByClassName("chinese")[0];

        var math = document.getElementsByClassName("math")[0];

        var height = document.getElementsByClassName("height")[0];

        function Person() {

        }

        Person.prototype.name = name;

        Person.prototype.chinese = chinese;

        Person.prototype.math = math;

        Person.prototype.names = function () {

            return this.name;

        }

        Person.prototype.chineses = function () {

            return this.chinese;

        }

        Person.prototype.maths = function () {

            return this.math;

        }

        function Man(height) {

            this.height = height;

        }

        var F = function () { };

        F.prototype = Person.prototype;

        Man.prototype = new F()

        console.log(Man.prototype);

        Man.prototype.constructor = Man;

        Man.prototype.heights = function () {

            return this.height;

        }

        var all = new Man(170)

        all.name = "鹏莉"

        all.chinese = "80"

        all.math = "80"

        all.height = "180"

        myname.innerHTML = all.names();

        chinese.innerHTML = all.chineses();

        math.innerHTML = all.maths();

        height.innerHTML = all.heights();

    </script>

</body>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值