面向对象的特征和原型链,instanceof运算符

66 阅读2分钟

1.面对对象的三大特征

  • 封装:将某个具体功能封装在对象中,只对外部暴露指定的接口,外界在使用的时候,只考虑接口怎么用,不用考虑内部怎么实现(前面学习的api其实就是一种封装思想)

  • 继承:一个对象拥有其他对象的属性和方法

  • 多态:一个对象在不同情况下的多种状态(java语言使用较多,js语言基本不涉及)

<script>
        /* 
        1.继承 :  一个对象(子对象)拥有另一个对象(父对象)所有成员
        2.原型继承 :把父对象最为子对象构造函数的原型
        */
        //    父对象
        let obj = {
            element: '水系',
            place: 18
        }
        // 子对象构造函数
        function Fun(uname, age) {
            this.uanme = uname,
                this.age = age
        }
        // 继承父对象成员
        Fun.prototype = obj
        let p1 = new Fun('公子', '至东')
        let p2 = new Fun('莫娜', '蒙德')
        console.log(p1, p2);
    </script>

2.原型链

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

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

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

snipaste20220429_102740.jpg

 //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.内置对象原型链

3.1Array的原型链

    //1.Array
    let arr = new Array(10,20,30);
    console.log ( arr );
    //查看arr的原型
    console.log ( arr.__proto__.constructor );//Array
    console.log ( arr.__proto__ === Array.prototype );
    //查看arr的原型的原型
    console.log ( arr.__proto__.__proto__.constructor );//Object
    console.log ( arr.__proto__.__proto__ === Object.prototype );//true

snipaste20220429_104748.jpg

3.2String对象原型链

String
    let str = new String('123');
    console.log ( str );
    console.log ( str.__proto__ === String.prototype );//true
    console.log ( str.__proto__.__proto__.constructor );//Object
    console.log ( str.__proto__.__proto__ === Object.prototype );//true

snipaste20220429_105608.jpg

3.3DOM对象原型链

    //界面元素
    let div1 = document.getElementById('div1');
    let p1 = document.getElementById('p1');

snipaste20220429_111610.jpg

4.instanceof运算符

  • nstanceof语法: 对象 instanceof 构造函数
  • 作用:检测构造函数的原型prototype在不在这个对象的原型链上
<script>
        /* 
        1. instanceof(关键字): 运算符。 用于检测 构造函数的prototype在不在实例对象的原型链中
            说人话: 亲子鉴定,鉴定两个对象之间有没有血缘关系
        2.  实例对象 instanceof 构造函数
            检测 右边构造函数的prototype 在不在 左边实例对象的原型链中
        
        3. 应用 :  某些函数为了限制你的数据类型,在内部需要用instanceof进行判断是否是正确的数据类型
        */    

        let arr = [10,20,30]
        // arr-> Array.prototype -> Object.prototype -> null
        console.log( arr instanceof Array )//true
        console.log( arr instanceof Object )//true
        console.log( arr instanceof String )//false

        //封装一个函数,要求这个函数必须要传数组类型、 传其他类型不可以
        function fn(arr){
            if( arr instanceof Array){
                console.log( arr.reverse() )
            }else{
                console.log('数据类型错误')
            }
        }

        fn( [10,20,30] )
        fn( 'abc' )


        
    </script>