什么是构造函数?什么是实例?为什么说属性在构造函数中声明,方法在原型中声明?

什么是构造函数,什么是实例

  1. 构造函数是对一个实例的一个描述
  2. 构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载
 function Person (name){
   this.name = name;
 }
 var xiaoming = new Person('小明');
 var xiaohong = new Person('小红');

 console.log(xiaoming);
 console.log(xiaohong);
  • 这里的Person就是一个类,也是一个构造函数
  • 这里的xiaoming,跟xiaohong 都是一个实例,通过new一个构造函数去实例化出来的对象
    在这里插入图片描述

构造函数是一个方法,所以,在new的过程中会执行

function Person (name){
    console.log(name+'在new的过程中执行了')
    this.name = name;
  }
  var xiaoming = new Person('小明');
  var xiaohong = new Person('小红');

  console.log(xiaoming);
  console.log(xiaohong);

在这里插入图片描述
this.name 就是在构造函数中,声明的一个属性

 function Person (name,age){
  //console.log(name+'在new的过程中执行了')
   this.name = name;
   this.age = age;
 }
 var xiaoming = new Person('小明',18);
 var xiaohong = new Person('小红',16);

 console.log(xiaoming);
 console.log(xiaohong);

在这里插入图片描述

以上是构造函数简单的介绍,接下来讲什么是原型

每个构造函数都有一个原型属性,prototype

这个原型属性怎么用?

其实,原型的属性,就是对构造函数的一个描述

我们可以尝试打印,在浏览器看看它是什么样子的

    function Person (name,age){
     //console.log(name+'在new的过程中执行了')
      this.name = name;
      this.age = age;
    }
    var xiaoming = new Person('小明',18);
    var xiaohong = new Person('小红',16);

    console.log(xiaoming);
    console.log(xiaohong);

    console.log(Person.prototype)

浏览器显示结果
在这里插入图片描述
可以发现它是一个对象
我们试着给这个Person类添加一些描述
例如一个人,它会说话

function Person (name,age){
     //console.log(name+'在new的过程中执行了')
      this.name = name;
      this.age = age;
    }


    Person.prototype.say = function() {
      console.log(this.name + 'say hello world')
    }


    var xiaoming = new Person('小明',18);
    var xiaohong = new Person('小红',16);

    xiaoming.say();

    console.log(xiaoming);
    console.log(xiaohong);

    console.log(Person.prototype)

在这里插入图片描述
说明,在构造函数的prototype里面的属性,实例都会拥有,并且能使用

那么这个prototype被写入了属性之后,它长什么样子

function Person (name,age){
     //console.log(name+'在new的过程中执行了')
      this.name = name;
      this.age = age;
    }


    Person.prototype.say = function() {
      console.log(this.name + 'say hello world')
    }

    Person.prototype.work = function() {
      if(this.age < 18){
        console.log('未成年')
      } else {
        console.log('已成年')
      }
    }

    console.log(Person.prototype)

浏览器显示结果
在这里插入图片描述
它是一个对象
然后,我们仔细看,实例里面的属性

function Person (name,age){
   //console.log(name+'在new的过程中执行了')
    this.name = name;
    this.age = age;
  }


  Person.prototype.say = function() {
    console.log(this.name + 'say hello world')
  }

  Person.prototype.work = function() {
    if(this.age < 18){
      console.log('未成年')
    } else {
      console.log('已成年')
    }
  }

  // console.log(Person.prototype)


  var xiaoming = new Person('小明',18);
  var xiaohong = new Person('小红',16);

  console.log(xiaoming)

这里,我们打印一下这个实例,浏览器显示结果
在这里插入图片描述

我们发现在实例的本身属性中,是没有say跟work这两个属性的
那它是怎么调用得到的呢
我们看到有个__proto__这个对象,我们展开它看到

在这里插入图片描述
这里,我们就猜测出了,在类的prototype的属性,被实例化后,都跑到了实例的__proto__里面了

因为实例化之后,它是一个对象,所以,我们可以对这个对象进行操作

我们修改一下小明的年龄

 function Person (name,age){
     //console.log(name+'在new的过程中执行了')
      this.name = name;
      this.age = age;
    }


    Person.prototype.say = function() {
      console.log(this.name + 'say hello world')
    }

    Person.prototype.work = function() {
      if(this.age < 18){
        console.log('未成年')
      } else {
        console.log('已成年')
      }
    }

    // console.log(Person.prototype)


    var xiaoming = new Person('小明',18);
    var xiaohong = new Person('小红',16);

    //我们修改一下小明的年龄
    xiaoming.age = 22;
    xiaoming.work();

    console.log(xiaoming);
    console.log(xiaohong);

在这里插入图片描述
可以看到,我们可以单独的去修改,每个实例的内容

我们再尝试修改一下实例的__proto__吧

我们给小明新增一个sleep的方法

//我们给小明新增一个sleep的方法
    var xiaoming = new Person('小明',18);
    var xiaohong = new Person('小红',16);

    //我们给小明新增一个sleep的方法
    xiaoming.__proto__.sleep = function(){
      console.log('go to sleep')
    }

    console.log(xiaoming);
    console.log(xiaohong);

在这里插入图片描述
你会发现小红也有了这个方法
于是,我们猜测
构造函数的prototype里的东西,是每个实例同时共享的

在这里插入图片描述
回到我们的问题上

问:为什么说属性在构造函数中声明,方法在原型中声明

答:因为在构造函数中声明后,通过new关键字实例化出来的实例都是单独享有,所以,属性在构造函数中声明因为方法大家都是共用的,而且不经常改变,所以,方法可以在prototype中声明

当然,方法也可以在构造函数中声明

只不过,如果可以使用共用资源,我们为啥还要单独的为每一个类都声明一次呢

所以

  • 在构造函数的prototype中声明,是为了实例能共享
  • 在构造函数内声明,是为了属性能单独享有

理解完这个,对于理解原型链有帮助

__proto__我们称隐性原型
prototype我们称显性原型

看完记得点赞嘻嘻

发布了227 篇原创文章 · 获赞 41 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_42554191/article/details/104468941