js高级

复习....创建对象的三种方式:

<script>
    /*
    *
    * 创建对象的三种方式:
    * 1.new Object()----内置构造函数创建
    * 2.字面量方式创建
    * 3.自定义构造函数创建
    *
    * 对象:特指的某个事务,有属性和方法
    * 小明:
    *       姓名,年龄,身高,体重,---特征,属性
    *       吃饭,唱歌,逛街,打球----行为,方法
    *
    *
    * */
    // 1.系统内置构造函数创建
    var obj = new Object();
    obj.name = "小明";
    obj.age = 12;
    obj.sayHi = function () {
        console.log("你好,我叫小明");
    };
    console.log(obj.name);
    obj.sayHi();

    //2.字面量方式创建
    var obj1 = {
        name: "小黄",
        age: 16,
        eat: function () {
            console.log("恰饭");
        },
        sleep: function () {
            console.log("小黄爱睡觉!");
        }
    }
    console.log(obj1.name);
    obj1.eat();
    // console.log(obj1 instanceof Object);

    //3.自定义构造函数创建
    // ①创建自定义构造函数
    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.play = function () {
            console.log("打豆豆");
        }
    }

    //② 实例化对象
    var obj2 = new Person("小明", 16);
    console.log(obj2.name);

    var obj3 = new Person("小黄", 16);
    console.log(obj3.name);

    console.log(obj3 instanceof Person);

    /*
    *
    * 自定义构造函数做了四件事:
    * 1.在内存中开辟空间,存储对象
    * 2.将this指向当前对象
    * 3.设置属性和方法的值
    * 4.把this对象返回。
    *
    *
    * */


    /* 使用工厂函数批量创建对象*/
    function createObjs(name, age) {
        var obj = new Object();
        obj.name = name;
        obj.age = age;
        obj.sayHi = function () {
            console.log("你好,我叫" + this.name + ",很高兴认识你!")
        }
        return obj;
    }

    var obj4 = createObjs("小绿", 18);
    console.log(obj4.name);
    obj4.sayHi();
</script>

 

原型:用原型来解决数据共享的问题

原型链:

<script>
    //创建对象:第一步,添加自定义构造函数----构造函数首字母大写,普通函数驼峰命名法
    function Person(name,age) {
        this.name=name;
        this.age=age;
        this.eat=function () {
            console.log("吃饭");
        };
    };
    //原型的作用之一:数据共享,节省内存空间
    Person.prototype.height=180;
    Person.prototype.sleep=function () {
        console.log("每天都要睡够八小时");
    };
    //实例化对象
    var obj=new Person("小明",12);
    console.dir(Person);
    console.dir(obj);

    //构造函数中的原型对象(prototype)和实例对象中的原型对象(__proto__)是相同的.
    //实例对象中的原型对象(__proto__)指向构造函数中的原型对象(prototype)
    console.log(Person.prototype==obj.__proto__);

</script>

原型对象最终指向了哪里:

<div id="dv"></div>
<script>
    function Person() {

    }
    Person.prototype.eat=function () {
        console.log("盘他");
    };
    var obj =new Person();

    console.dir(obj);
    console.dir(Person);

//实例对象中__proto__指向原型对象中 prototype
console.log(obj.__proto__==Person.prototype);
//原型对象是一个对象,有一个__proto__指向Object这个构造函数中的原型对象prototype,最终指向null.
    console.log(Person.prototype.__proto__==Object.prototype);

    console.log(Object.prototype.__proto__);//null
    //实例对象中的__proto__--->Person.prototype ----->Object.prototype,最终指向null

    console.log(Person.prototype.__proto__==Object.prototype);
    console.log(Object.prototype.__proto__)//null

    //实例对象中的__proto__ ---->Person.prototype ----->Object.prototype---->null;

    var dvObj = document.getElementById("dv");
    console.dir(dvObj);

    //dvObj.__proto__--->HTMLDivElement.prototype的__proto__ ---->HTMLElement---->Element---> Node----->EventTarget----->Object---null///最终都指向null;
</script>

原型指向发生改变如何添加属性和方法:

    //人的构造函数
    function Person(age) {
        this.age=age;
    }
    //学生的构造函数
    function Student(score) {
        this.score=score;
    }
    //原型的指向可以发生改变,指向人的实例对象------先一步改变指向
    Student.prototype=new Person(12);

    //通过原型对象添加eat方法----实现方法共享,节省内存空间
    Student.prototype.study=function () {
        console.log("敲代码敲代码");
    }
    Student.prototype.weight=180;

    //实例化学生
    var stu = new Student(80);
    stu.study();
    console.log(stu.weight);

    //总结:如果原型的指向发生了改变,但是又需要用原型对象中的方法和属性,可以将指向发生改变的放在最前面,发生改变后,再添加属性和方法,这样就可以使用了.

</script>

继承:

//使用修改原型对象的指向来实现继承
//人的构造函数
function Person(name,age,sex) {
    this.name=name;
    this.age=age;
    this.sex=sex;
}
Person.prototype.eat=function () {
    console.log("吃饭");
};

//学生的构造函数
function Student(score) {
    this.score=score;
}
//改变原型指向
Student.prototype=new Person("小红",18,"女");

//通过原型添加study方法
Student.prototype.study=function () {
    console.log("打代码,敲代码");
}

//实例化学生对象
var hhh = new Student(80);
console.log(hhh.name);
console.log(hhh.age);
console.log(hhh.sex);
hhh.eat();
console.log("学生对象下自己的属性=======");
console.log(hhh.score);
hhh.study();

var hhh1 = new Student(50);
console.log(hhh1.name,hhh1.age,hhh1.sex,hhh1.score);
var hhh2 = new Student(50);
console.log(hhh2.name, hhh2.age, hhh2.sex, hhh2.score);

//缺陷:因为改变了原型指向的同时实现的继承,直接初始化了属性,继承过来的属性的值都是一样的.
</script>

借用构造函数继承:

//人的构造函数
    function  Person(name,age) {
        this.name=name;//this指的是当前的实例对象
        this.age=age;
    }
    //通过原型对象添加eat方法
    Person.prototype.eat=function () {
        console.log("吃饭");
    }
    //学生的构造函数
    function Student(score,name,age) {
        Person.call(this,name,age);
        this.score=score;
    }
    Student.prototype.study=function () {
        console.log("敲代码");
    };
    var stu1=new Student(80,"小明",18);
    console.log(stu1.name,stu1.age,stu1.score);

    var stu1=new Student(90,"小白",19);
    console.log(stu1.name,stu1.age,stu1.score);

    var stu1=new Student(100,"小红",20);
    console.log(stu1.name,stu1.age,stu1.score);
</script>

组合继承:

<script>
//添加人的构造函数
    function Person(name,age) {
        this.name=name;
        this.age=age;
    }
    Person.prototype.eat=function () {
        console.log("吃饭");
    }

    //创建学生的构造函数
    function Student(name,age,score) {
        Person.call(this,name,age);
        this.score=score;
    }
    //修改原型指向
    Student.prototype=new Person();//不传值
    Student.prototype.study=function () {
        console.log(this.name+"敲代码,敲到老");
    };
    var stu1=new Student("小红",16,100);
    console.log(stu1.name,stu1.age,stu1.score);
    stu1.study();
    stu1.eat();

    var stu2=new Student("小白",17,90);
    console.log(stu2.name,stu2.age,stu2.score);
    stu2.study();
    stu2.eat();
</script>

拷贝继承:

<script>
  
    // var obj1={
    //     name:"李靖",
    //     age:18,
    //     sex:"nan",
    //     tuoTa:function () {
    //         console.log("托塔李天王");
    //     }
    // }
    // //改变了
    // var obj2 =obj1;
    // console.log(obj2.name,obj2.age,obj2.sex);
    // obj2.tuoTa();

    function Person() {

    }
    Person.prototype.name="李靖";
    Person.prototype.age=18;
    Person.prototype.sex="男";
    Person.prototype.tuoTa=function () {
        console.log("托塔李天王");
    }
    var obj2={};
    for(var key in Person.prototype) {
        obj2[key]=Person.prototype[key];
    }
    console.dir(obj2);

    var key="name属性";
    var key="age属性";
    var key="sex属性";
    var key="tuota方法名";
//获取对象的属性 对象.属性名  对象["属性"]
    for(var key in Person.prototype){
        console.log(key+"======="+Person.prototype[key]);
    }
</script>

总结:

/* * 继承

* 1.修改原型对象的指向实现继承 * 缺陷:属性重复

* 2.借用构造函数实现继承 * 要继承的子构造函数:父构造函数.call,(this属性1,属性2) * 缺陷:方法不能继承

* 3.组合继承:原型对象+构造函数

* 属性可以不重复,方法也可以继承

* 4.拷贝继承:把一个对象中的属性和方法直接拷贝到另一个对象中

* 使用 for-in循环,将一个对象中的所有属性和方法赋值给另一个对象 * */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值