原型链

2022-02-25 19:27:51 浏览数 (2)

原型链

这里只是通过一些案例补充之前对原型,原型链,instanceof的细节。

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // // 函数构造器
        // console.log(Function); //ƒ Function() { [native code] }

        // // 对象构造器
        // console.log(Object); //ƒ Object() { [native code] }

        // // 数组构造器
        // console.log(Array); //ƒ Array() { [native code] }

        // // 字符串构造器
        // console.log(String); //ƒ String() { [native code] }

        // // 数字构造器
        // console.log(Number); //ƒ Number() { [native code] }

        // // 布尔构造器
        // console.log(Boolean); //ƒ Boolean() { [native code] }



        // 定义一个函数(构造函数)Father
        function Father() { }
        // 使用构造函数创建对象father
        var father = new Father()

        // 使用字面量形式创建对象
        var car = {}

        // 使用Object构造器创建对象
        var home = new Object()

        // 使用字面量形式创建一个数组arr
        var arr = [1, 2, 3]


        /**
         * prototype原型对象,即原型对象也是对象,是对象就可以通过原型链继承其原型上的属性和方法,
         * prototype是对象,所以prototype也可通过原型链继承其原型上的属性和方法
        */

        /**
         * 每个对象都可以通过原型链访问(或者说继承)其原型链上的属性和方法
         * 使用构造函数创建的对象,可以通过原型链继承这个构造函数上的属性和方法(说白了就是这个构造函数的原型)
         * */
        console.log(father.__proto__ === Father.prototype); //true

        /**
         * 这个构造函数的原型对象,即Father.prototype,也可通过原型链继续继承它(Father.prototype)原型链上的属性和方法
        */
        console.log(Father.prototype.__proto__);   //true
        console.log(Father.prototype.__proto__ === Object.prototype);   //true
        console.log(Father.prototype.constructor === Father);   //true
        // 通过构造函数创建的对象,可以通过原型链访问其原型
        console.log(father.__proto__) //true
        // 通过字面量形式创建的对象,其本身就继承Object.prototype
        console.log(car.__proto__.constructor === Object);
        console.log(arr.__proto__ === Array.prototype); //true

        // 同理,函数实际也是一个对象,因此,函数也可以通过其原型链访问其原型
        console.log(Function.__proto__ === Function.prototype);//true
        console.log(Function.__proto__ === Function.prototype);//true
        console.log(Function);




        console.log(Function.prototype); //ƒ () { [native code] }
        /**
         * 所有函数都有自己的prototype
         */
        console.log(Object.prototype); //{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
        console.log(Array.prototype); //[constructor: ƒ, concat: ƒ, copyWithin: ƒ, fill: ƒ, find: ƒ, …]
        console.log(String.prototype); //String {"", constructor: ƒ, anchor: ƒ, big: ƒ, blink: ƒ, …}
        console.log(Number.prototype); //Number {0, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, toPrecision: ƒ, …}
        console.log(Boolean.prototype); //Boolean {false, constructor: ƒ, toString: ƒ, valueOf: ƒ}


        console.log(Array.prototype === Function.prototype); //false
        console.log(String.prototype === Function.prototype); //false
        console.log(Number.prototype === Function.prototype); //false

        console.log(Object.__proto__ === Function.prototype);  //true
        console.log(Array.__proto__ === Function.prototype);   //true
        console.log(Function.__proto__ === Function.prototype);//true
        console.log(String.__proto__ === Function.prototype);  //true
        console.log(Number.__proto__ === Function.prototype);  //true
        console.log(Boolean.__proto__ === Function.prototype); //true
        /**
         * Object.protype是原型链的顶端,它在往上就是null
         * 其余所有对象(Array,String,Number...)会通过原型链继承Object.prototype
         */
        console.log(Object.prototype
            .__proto__
        ); //null
        console.log(Array.prototype
            .__proto__
        ); //{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
        console.log(String.prototype
            .__proto__
        ); //{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
        console.log(Number.prototype
            .__proto__
        ); //{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
        console.log(Boolean.prototype
            .__proto__
        ); //{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
        console.log(Array.prototype.__proto__ === Object.prototype); //true
        console.log(String.prototype.__proto__ === Object.prototype); //true
        console.log(Number.prototype.__proto__ === Object.prototype); //true
        console.log(Boolean.prototype.__proto__ === Object.prototype); //true
        console.log(Array);         //ƒ Array() { [native code] }
        console.log(Array.prototype); //prototype是原型对象,对象就有__proto__。它还有constructor保存本身,还有本身的属性以及方法
        console.log(Array.prototype.constructor === Array); //true
        console.log(Array.__proto__ === Function.prototype); //true
        console.log(Array.prototype.__proto__);     //{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
        console.log('--------------');



        /**
         * 所有对象都可以通过new创建,比如数组:new Array();对象:new Object();函数:new Function();字符串:new String()....
         * new后面的叫构造函数,即Array();Object();Function();String()...都是构造函数
         * 构造函数也是函数,那么就有一个问题,js所有东西都是对象的话,是先有对象还是现有构造函数?(因为对象也是new出来的)
         * 如果是先有函数,再通过函数new产生的对象,那么函数又是怎么来的?所以就类似:先有鸡还是现有鸡蛋的问题。
         * 所以,函数是怎么来的?这个解释了就说的通了
         * */

        /**
         * 函数有prototype,对象有__proto__
         * 函数可以通过prototype.constructor访问自己构造它的函数
         * 对象可以通过__proto__继承上层的prototype
        */
        console.log(Function instanceof Object);                         //true
        // 函数就有prototype
        console.log(Function.prototype instanceof Object);               //true
        console.log(Function.prototype.__proto__ instanceof Object);     //fasle
        // 函数也是一个对象,对象就有__proto__,所以函数有__proto__
        console.log(Function.__proto__ instanceof Object);               //true
        console.log(Function.__proto__ instanceof Object);               //true
        console.log(Function.__proto__.__proto__ instanceof Object);     //false
        console.log(Function.__proto__.__proto__ instanceof Object);     //false

        console.log(Function.constructor === Function);                  //true
        console.log('-----------------------');

        var cat = {}
        function Dog() { }
        var dog = new Dog()

        console.log(cat.__proto__ === Function.prototype);      //false
        console.log(dog.__proto__ === Function.prototype);    //false
        console.log(cat.__proto__ === Object.prototype);         //true
        console.log(dog.__proto__ === Object.prototype);          //false
        console.log(cat.__proto__ === dog.__proto__);             //false
        console.log(dog.__proto__ === Dog.prototype);             //true

    </script>
</body>

</html>

图解

这里引用网上的图,个人也认为这张图很具体很全面。

0 人点赞