原型链的介绍

124 阅读2分钟

-原型链

==1.1-原型链介绍==

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

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

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

image.png

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
​
        /* 
        1.原型链 :每一个对象,都有__proto__指向自身的原型。 而原型也是对象,也有自己的
        __proto__指向原型的原型,以此类推形成链式结构,称之为原型链。
​
        2.对象访问原型链中成员的规则 :就近原则
            当访问对象的成员,先看自己有没有。有则访问,没有则看原型有没有。原型有则访问,
            没有则访问原型的原型,没有则继续往上找。以此类推,一直找到原型链终点 : null.
            还没有, 如果是属性 : 则获取undefined  如果是方法 ,则报错xxx is not defined 
         */
        
        //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
​
    </script>
</body>
</html>

1.2-原型链详解:内置对象的原型链

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

    -   了解构造函数的原型本身是一个对象,只要是对象就有原型

-   2.通过查看Date的原型链

    -   学会举一反三,所有的内置对象(Math Array 基本包装类型等)的原型链都是一样的,最终都指向Object

-   3.通过查看String的原型链:了解这里的String值得是内置对象String(是一个基本包装类型),其他的NumberBoolean原型链和String是一样的

    -   只有对象才有原型,这里一定要把基本数据类型stringnumberboolean,和基本包装类型(特殊的引用类型对象)StringNumberBoolean区分开来,不要搞混淆
  • 思考题:为什么arr.toString()方法和对象的toString()方法得到的结果不同

1.Array的原型链

//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

image.png

2-Date的原型链

//2.Date
    let date1 = new Date();
    //细节:日期对象直接console.log会转成string,查看对象需要使用console.dir打印
    console.dir(date1);
    console.log ( date1.__proto__ === Date.prototype );//true
    console.log ( date1.__proto__.__proto__.constructor );//Object
    console.log ( date1.__proto__.__proto__ === Object.prototype );//true

image.png

3-String对象原型链

//3.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

image.png

4-DOM对象原型链

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

image.png

image.png

  • 完整代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body><div id="div1"></div>
<p id="p1"></p><script>
    /*查看内置对象的原型链*/
​
    //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
​
    //2.Date
    let date1 = new Date();
    //细节:日期对象直接console.log会转成string,查看对象需要使用console.dir打印
    console.dir(date1);
    console.log ( date1.__proto__ === Date.prototype );//true
    console.log ( date1.__proto__.__proto__.constructor );//Object
    console.log ( date1.__proto__.__proto__ === Object.prototype );//true
​
    //3.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
​
    //4.界面元素
    let div1 = document.getElementById('div1');
    let p1 = document.getElementById('p1');
​
</script>
</body>
</html>