Javascript:面向对象三大特征、原型链

489 阅读4分钟

1.面向对象三大特征

1.封装:将某个具体的功能封装在对象中,只对外部暴露指定接口,外界在使用的时候,只考虑接口怎么用,不用考虑内部怎么实现(函数的封装,api)

2.继承:一个函数拥有其他对象的属性和方法

3.多态:一个对象在不同情况下的多种状态

 //示例:饲养员给动物喂食物
    
    //动物
    function Animal ( name ) {
        this.name = name;
    };

    //猫
    let cat = new Animal('猫咪');
    cat.eat = function ( food ) {
        console.log ( "喵喵猫" + "我吃了" + food );
    };

    //狗
    let dog = new Animal('小狗狗');
    dog.eat = function ( food ) {
        console.log ( "汪汪汪" + "我吃了" + food );
    };

    //饲养员
    function Person (  name ) {
        this.name = name;
    };
    Person.prototype.work = function (animal,food ) {
        //animal接收一个由Anmiaml构造函数生成的实例化对象,调用它的eat方法
        //同一对象表现出来不同的状态,就叫做多态
        animal.eat(food);
    };

    let p1 = new Person('酸奶');
    p1.work(cat, '饼干');
    p1.work(dog, '翔');

  //继承:让一个对象拥有另一个对象的属性和方法
       //父对象
       let father = {
           house : {
               address:'武汉天地',
               price : 10000000
           },
           car:{
               brand:'劳斯莱斯幻影',
               price:8000000
           }
       }

       //子对象构造函数
       function Son(name,age){
        this.name = name
        this.age = age
       }

       //默认原型
       Son.prototype.eat = function(){
           console.log('吃东西')     
       }
       /* 替换原型继承: 把父对象作为子对象构造函数的原型*/
       Son.prototype = father

       let son1 = new Son('大哥',30)
       let son2 = new Son('二哥',20)
       console.log(son1,son2)


2.原型链

1.原型链:每一个对象都有原型,原型本身又是对象,所以原型又有原型,以此类推形成一个链式结构,称为原型链

2.对象访问原型链中的成员规则:就近原则

  • 当访问一个对象的成员变量时,会首先访问它自身的成员变量,如果有则访问。没有则在原型中寻找,能找到就访问,不能找到则继续往原型的原型中寻找,以此类推,如果找到原型链的顶端还是找不到,则程序报错:xxx is not a function

1559053096356.png


        
        //1.构造函数
        function Person(name,age){
            this.name = name;
            this.age = age;
        };

        //2.原型对象
        Person.prototype.sayHi = function(){
            console.log('人生若只如初见,何事秋风悲画扇');
        };

        Person.prototype.type = '哺乳动物';

        //3.实例化对象
        let p1 = new Person('又又',18);
        console.log(p1);

        //请说出以下代码执行结果
        console.log(p1.name);//又又      p1自己有name属性
        console.log(p1.type);//哺乳动物   p1自己没有type,但是p1的原型有
        console.log(p1.hobby);//undefined p1自己没有hobby,原型也没有
        p1.sayHi();// 人生若只如初见,何事秋风悲画扇   p1自己没有这个方法,原型有
       // p1.eat();//报错 xxx is not defined    p1自己没有这个方法,原型也没有

       //为什么不报错?  p1自己没有这个方法,原型也没有这个方法,但是原型的原型有
        p1.toString();

        //查看p1的原型链
        console.log(p1.__proto__.constructor);//Person
        console.log(p1.__proto__ === Person.prototype);//true

        //查看p1的原型的原型
        console.log(p1.__proto__.__proto__.constructor);//Object
        console.log(p1.__proto__.__proto__ === Object.prototype);//true

        //查看p1的原型的原型的原型
        console.log(p1.__proto__.__proto__.__proto__);//null

3.原型链详解

  • 1.通过查看Array的原型链

    • 了解构造函数的原型本身是一个对象,只要是对象就有原型
  • 2.通过查看Date的原型链

    • 学会举一反三,所有的内置对象(Math Array 基本包装类型等)的原型链都是一样的,最终都指向Object
  • 3.通过查看String的原型链:了解这里的String值得是内置对象String(是一个基本包装类型),其他的Number、Boolean原型链和String是一样的

    • 只有对象才有原型,这里一定要把基本数据类型string、number、boolean,和基本包装类型(特殊的引用类型对象)String、Number、Boolean区分开来,不要搞混淆

    1.Array的原型链

1559054224736.png

2.Date的原型链

1559057319055.png

3.String对象原型链

1559057483874.png

4.Dom数对象原型链

1559057534710.png

1559057590648.png

5.instanceof运算符

  • nstanceof语法: 对象 instanceof 构造函数
  • 作用:检测构造函数的原型prototype在不在这个对象的原型链上
//1.示例
    let arr = [10,20,30];
    //数组原型链  arr->Arr.prototype->Object.prototype->null
    console.log ( arr instanceof Array );//true
    console.log ( arr instanceof Object );//true

    //2.示例
    //根据instanceof语法:左边Function表示对象,右边Function表示构造函数
    //Function原型链  Function对象->Function.prototype->Object.prototype->null
    console.log ( Function instanceof Function );//true
    console.log ( Function instanceof Object );//true

    //3.示例
    //根据instanceof语法:左边Object表示对象,右边Object表示构造函数
    //Object原型链 Object对象->Function.prototype->Object.prototype->null
    console.log ( Object instanceof Object );//true
    console.log ( Object instanceof Function );//true