构造函数&&原型(补充原型题目、原型链、 hasOwnProperty和 instanceof属性)

本文详细探讨了JavaScript中原型链的工作原理,包括原型属性__proto__的作用,如何通过构造函数创建对象,以及对象如何继承属性和方法。文章还介绍了原型链查找机制,hasOwnProperty和instanceof操作符的使用,以及Object.create方法的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

补充原型题目

第四题

        function Person(){
            //  __proto__这个属性记录person1的原始模型
            /*
              this -->{
                  __proto__:Person.prototype;
              }
              return this
            */
        };//工厂
        Person.prototype.name = "huasheng";//原始模型
        /*Person.prototype = {(1)给原始模型设置name属性
            name : "huasheng", --> name:"小明",
        }
          Person.prototype = {(2)
            name:  "oldsix",
          }
        */
        var person1 = new Person();//出厂
        Person.prototype = {
            name:"oldsix",
        }
        person1.__proto__.name = "小明";//修改 new Person()启动的构造函数
        // name = "huashneg" -- > name = "小明"
        console.log(Person.prototype.name);//打印oldsix

第五题

       function Person(){
            /* __proto__这个属性记录person1的原始模型
              this-->{
                  __proto__:Person.prototype;
              }return this
            */
        };
        Person.prototype = {
            name:"oldsix",
        };
        /*
         Person.prototype = {(1)
             name:"oldsix" -- > name:"huasheng" --> name = "小明"
         }
        */
        var person1 = new Person();
        Person.prototype.name = "hausheng";//修改Person.prototype的name属性
        person1.__proto__.name = "小明";//修改Person.prototype的name属性
        console.log(Person.prototype.name);

第六题

        function Person(){
            /*人为打乱__proto__的指向不让你指向原始模型,认你指向任何一个对象
              this-->{
                  __proto__:Person.prototype;(1)
                  __proto__:{
                      name:"我把你的指向给搞乱了"
                  }
              }return this
            */
        };
        /*
         Person.prototype = {(1)
             name:"oldsix",
         }
        */
        Person.prototype = {
            name:"oldsix",
        }
        var person1 = new Person();
        person1.__proto__ = {
            name:"我把你的指向给搞乱了",
        }//通过这种方式可以人为打乱__proto__的原始模型指向的
        console.log(person1.name);

第七题

		function Person(){
            /*
              this -->{
                  __proto__:Person.prototype; 
                  -->__proto__:Person.prototype.name = "xiaoming";(人为修改了原始模型)
              }return this
            */
        };
        Person.prototype.name = "hausheng";
        /*
          Person.prototype = {(1)
              name:"huasheng", --> name:"xiaoming",
          }
        */
        var person1 = new Person();
        person1.__proto__.name = "xiaoming";
        console.log(Person.prototype.name);//"xiaoming"

第八题

 		function Person(){
             /*
               this-->{
                   __proto__:Person.prototype;
                   __proto__:{//修改了person1上的原始模型
                       name: 'xiaoming',
                   }
               } return this
             */
         };
         Person.prototype.name = 'huasheng';
         /*
           Person.prototype = {(1)
               name:"huasheng",
           }
            Person.prototype = {(2)
               name:"oldsix",
           }
         */
         var person1 = new Person();
         Person.prototype = {
             name: 'oldsix'
         }
         person1.__proto__ = {
             name: 'xiaoming'
         }
        console.log(person1.name);//打印xiaoming

原型链

只要是对象就会有__proto__属性 指向对象的原型(爸爸)

如果想知道一个属性的原始模型是谁那么可以直接用__proto__这个属性

function Person(){}
       Person.prototype = {
           name:"huasheng",
       }
       var person1 = new Person();
       console.log(person1.__proto__)//打印person1的原型

在这里插入图片描述
person1的原型就是{name:"huasheng"}这个对象

我想看一下Person的初始的原始模型长什么样

function Person(){};
console.log(Person.prototype);//查看原始模型的初始样子

在这里插入图片描述
Person.prototype.constructor===Person吗??

function Person(){};
console.log(Person.prototype.constructor===Person);

在这里插入图片描述
结果是全等的是true

那么可不可以把constructor的原始模型的构造函数的构造函数给人为的修改呢吗??

function Person() { }
        Person.prototype = {
            name: "huasheng",
        }
        var person1 = new Person();
        console.log(Person.prototype.constructor = Number);
        //修改construction的构造函数也能改原始值但是没有任何意义

在这里插入图片描述

Person.prototype原型

  • 初始存在constructor这个属性,该属性记录了原始模型的构造函数(所在工厂)
  • 还存储了__proto__属性

普通函数和构造函数没有任何的区别,只要一个函数前面加上new启动了这个函数,那么这个函数就是构造函数(每一个函数都有做构造函数的潜质)

那么通过new关键词,实例化的函数有没有constructor这个属性

       function Person(){
            /*
              this-->{
                  __proto__:Person.prototype;
              }return this
            */
        };
        var person1 = new Person();
        console.log(person1.constructor);

在这里插入图片描述
那么所有对象的最终点是什么

function Person(){};
        var person1 = new Person();
        console.log(Person.prototype.__proto__);

在这里插入图片描述

如果一个对象上没有__proto__属性的话他就是Object.prototype

 function Person(){};
        var person1 = new Person();
        console.log(Person.prototype.__proto__===Object.prototype);

在这里插入图片描述
true表示完全相等

person1他是是个产品,那么这个产品的模子是Person.prototype,那么这个产品的模子的模子是Object.prototypeObject是JS内置的构造函数他可以构造一个对象。Object.prototype是所有对象的最终点是没有__proto__属性的。

以下代码的输出结果是什么

    function Grand(){
          /*
            this-->{
                __proto__:Grand.prototype;
            } return this
          */
      };
      Grand.prototype.sex = "male";
      /*
        Grand.prototype = {
            sex = "male",
             __proto__:Object.prototype 原型链的终端
        }
      */
      var grand = new Grand();

      function Father(){
          this.age = 50;
          /*
            this-->{
                __proto__:Father.prototype,
            } return this
          */
      }
      Father.prototype = grand;
      /*
        Father.prototype = {
            sex = "male",
        }
      */
      var father = new Father();

      function Son(){
          this.name = "huasheng";
          /*
            this-->{
                __porto__:Son.prototype;
            }return this
          */
      }
      Son.prototype = father;
      /*
        Son.prototype = {
            age = 50,
        }
      */
      var son = new Son();
      console.log(son.name);//从自身上自动name = "huasheng"
      console.log(son.age);//从Father身上找到 age = 50
      console.log(son.sex);//从Grand身上找到 sex = "male"

那么Object.prototype 原型链的终端有没有toString()这个函数呢

console.log(son.toString)

在这里插入图片描述
son上是有toString的,他是个函数,他会顺着原型链查找如果有就打印出来,如果在原型链上都没有找到就返回undefined

原型链的终端的原始模型是什么???

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

在这里插入图片描述
原型链的终端的原始模型是null
Object.prototype.__proto__===null判断结果是全等的是true

在对象上查找属性的步骤(原型链查找步骤)

  • 先从自身查找属性,如果自身没有找到这个属性,那就从自身的__proto__上查找,
  • 如果还是没有找到这个属性,那就继续往沿着__proto__上查找,我们把这种查找规则称为原型链查找
  • 如果在Object.prototype(原型链终端)上没有找到指定属性 则结果是undefined
  • 把由__proto__组成的链式结构称为原型链

hasOwnPropertyinstanceof属性

属性可以分两种:

  • 自身属性(自己身上本来就有的属性叫自身属性)
  • 原型链上面的属性(自己身上没有,通过原型链的方法查找到了就叫做原型链上面的属性)

obj.hasOwnProperty("属性名")

  • obj.hasOwnProperty("属性名")判断属性是否是自身属性
  • 如果是自身属性 就返回true
  • 如果不是自身属性 就返回false
      function Person(){
           this.name = "hausheng";
           this.age = 28;
       }
       Person.prototype.sex = "male";
       var person1 = new Person();
       console.log(person1.hasOwnProperty("name"));
       console.log(person1.hasOwnProperty("sex"));

在这里插入图片描述
A instanceof Binstanceof)他是一个操作符

A instanceof B 判断对象A的原型链上有没有构造函数B的原型

      function Person(){
           this.name = "hausheng";
           this.age = 28;
       }
       Person.prototype.sex = "male";
       var person1 = new Person();
       console.log(person1 instanceof Person);
       //instanceof 前面的参数是一个对象,后面的参数是构造函数

在这里插入图片描述
那么person1的原型链上没有用构造函数Object呢??

console.log(person1 instanceof Object);

在这里插入图片描述
person1对象上面的原型链是有Object的,是因为Object.prototype是所有对象的终端是对象就有终端,是原型链上面的终端都是Object.prototype

JS中所有对象中的原型链上的终端都是Object.prototype

JS中内置的构造函数

  1. Number构造数字对象
  2. String构造字符串对象
  3. Boolean构造布尔对象
  4. Object构造对象
  5. Function构造函数对象
  6. RegExp构造正则对象
  7. Math构造数学对象
  8. Date构造时间对象

一般情况下都喜欢用字面量形式声明一个数据var a = 2方便简洁,如果通过构造函数的形式构造了一个数据var num = Number(2)这做的的话很麻烦,除非想要用构造函数构造自定的功能方法时要使用构造函数。

       var num = new Number(2);
       console.log(num instanceof Object);
       var str = new String("huasheng");
       console.log(str instanceof Object);
       var bool = new Boolean(false);
       console.log(bool instanceof Object);
       var obj = new Object;
       console.log(obj instanceof Object);
       var fn = new Function;
       console.log(fn instanceof Object);
       var reg = new RegExp(/2/);
       console.log(reg instanceof Object);
       var math = Math;
       console.log(math instanceof Object);
       var date = new Date(2019,5,25,7);
       console.log(date instanceof Object)

结论instanceof前面写的一个对象,后面写的是一个Object,那么返回值一定是true
在这里插入图片描述
in操作符

我希望不管是自身属性和原型链上面的属性都返回的是true 那该怎么办??

function Person() {
           this.name = 'heaven';
           this.age = 28;
        }
        Person.prototype.sex = 'male';
        var person1 = new Person();
        console.log("sex" in person1);

in操作符,是不管你是自身属性还是原型链上面的属性返回还的结果都是true,只要是能从person1找到sex这个属性那么返回会来的结果就是true

补充for in循环

        function Person() {
           this.name = 'heaven';
           this.age = 28;
        }
        Person.prototype.sex = 'male';
        var person1 = new Person();
        for(key in person1){//遍历对象 for in 循环 可以遍历到原型链上的属性
            console.log(key);
        }

for in循环是遍历对象用的,及其原理就是他的in关键词他可以顺着对象中的__proto__这个属性去找要遍历的对象,只要你的对象在要遍历原型链上他都能遍历到
在这里插入图片描述
所有的对象的原型链终端都是Object.prototype??

Object.create(原型) 用自己定义原型来创建对象

       var obj = Object.create({
            //这个属性可以人为的填写一些对象作为原始模型的
            name:"huasheng",
        })
        console.log(obj);
        console.log(obj.__proto__);

在这里插入图片描述在这里插入图片描述
create这个函数执行的时候,可以传递一个对象作为原始模型,这个函数的结果是一个新的对象,新的对象的原始模型就是在create函数中传递的对象

		var person = {
                name: "huasheng",
        }
        var obj = Object.create(person)
        console.log(obj.__proto__=== person);

在这里插入图片描述
查询obj的原始模型和person做全等比较是true,表示自己定义的create属性和obj的原始模型是一致的,就是用create属性指定自己的原始模型

create这个函数不仅仅可以传一个对象,还有可以传null

var obj = Object.create(null)
        console.log(obj);

在这里插入图片描述
No properties表示没有属性,就是没有原型

 var obj = Object.create(null)
        console.log(obj instanceof Object);

在这里插入图片描述
现在obj是一个对象,本来obj这个变量中就没有原型,那他怎么用Object找到原型链的终端呢结果就是false

并不是所有的对象的原型链终端都是Object.prototype,在用create函数定义并且括号里的值是null他的原型链终端就不是Object.prototype

Object.create(null) 这个对象的原型链终端不是Object.prototype

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值