JavaScript高级 构造函数与原型篇

2023-12-22 21:27:11

构造函数与原型

1、构造函数

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

//  定义学生构造函数
 function Student() {
//   // 添加属性
   this.school = '好好好学院'
   this.age = 18
 }
 // 基于Student构造函数创建对象
 const s1 = new Student()
 const s2 = new Student()

在JS中,使用构造函数时需要注意以下两点:

??????? 1.构造函数用于创建某一类对象,其首字母要大写

??????? 2.构造函数要和new一起使用才有意义

new 在执行时会做四件事情:

??????? 1.在内存中创建一个新的空对象

??????? 2.让this指向这个新的对象

??????? 3.执行构造函数里面的代码,给这个新对象添加属性和方法

??????? 4.返回这个新对象所以构造函数里面不需要(return)

JavaScript 的构造函数中可以添加一些成员,可以在构造函数本身上添加,也可以在构造函数内部的 this 上添加。通过这两种方式添加的成员,就分别称为静态成员和实例成员。
实例成员:在构造函数内部创建的对象成员称为实例成员,只能由实例化的对象来访问。
静态成员:在构造函数本上添加的成员称为静态成员,只能由构造函数本身来访问 。

 function A(uname,age){
    this.uname = uname;
    this.age  = age;
    this.say = function() {
        console.log(this.uname+'你好');
    }
}

var zs = new A('张三',18);
var ls = new A('李四',18);

在上述代码中,构造函数中通过this添加的name,age,say方法都是实例成员。只能由实例化的对象来访问。在构造函数本身上添加的成员叫静态成员

例如:

A.sex = '女'

2、构造函数原型

构造函数通过原型分配的函数是所有对象共享的。JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象。需要注意的是,这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。

function Student(age,name){
    this.age = age;
    this.name = name;
    this.score = function(){
        console.log('孩子们成绩都很好!');
    }
}

console.dir(Student);

打印该构造函数里面所有的方法,浏览器控制台:

可以找到prototype对象。

可以把一些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法了。

可以自己尝试打印一下下面的结果。

function Student(age,name){
    this.age = age;
    this.name = name;
}

Student.prototype.score = function(){
    console.log('孩子们成绩都很好!');
}

console.dir(Student);
var xl = new Student(18,'小熊');
var wh = new Student(17,'王欢');
xl.score();
wh.score();
console.log(xl.score === wh.score);

需要注意的一点是:一般情况下,公共属性定义到构造函数里面,公共方法定义到原型对象身上。

3、对象原型 __proto__

对象都会有一个属性__proto__指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在。

function Student(age,name){
    this.age = age;
    this.name = name;
}

 Student.prototype.score = function(){
     console.log('孩子们成绩都很好!');
 }

// console.dir(Student);

 var xl = new Student(18,'小熊');
 var wh = new Student(17,'王欢');
 console.log(xl);

尝试打印实例对象查看它的原型(__proto__)

console.log(xl);//对象身上系统自己添加一个__proto__属性指向构造函数的原型对象

那么对象原型(__proto__)和原型对象(prototype)是否等价

我们不妨做个测试

 console.log(xl.__proto__ === Student.prototype);

打印结果为:true
故:__proto__对象原型和原型对象prototype是等价的

4、constructor构造函数

我们来尝试分别打印一下原型对象和对象原型

console.log(Student.prototype);
console.log(xl.__proto__);

不难发现,它们都有一个属性叫constructor属性,这个属性指向构造函数本身。constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。


?一般情况下,对象的方法都在构造函数的原型对象中设置。当给构造函数添加多个方法时,可以采用对象的方式。

5、构造函数、实例、原型对象三者之间的关系

6、原型链(JavaScript的成员查找机制)

  1. 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
  2. 如果没有就查找它的原型(也就是 __proto__指向的 prototype原型对象)。
  3. 如果还没有就查找原型对象的原型(Object的原型对象)。
  4. 依此类推一直找到 Object 为止(null)。

__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。

针对原型链的练习,加深印象

<!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>原型链</title>
  </head>
  <body>
    <script>

      console.log(f.__proto__ === Function.prototype)         // true

      console.log(Function.__proto__ === Function.prototype)     // true

      console.log(Function.__proto__.__proto__ === Object.prototype)
         // Object.prototype

      console.log([].__proto__.__proto__ === Object.prototype) //  true

      console.log(Function.__proto__.__proto__ === [].__proto__.__proto__)
        // const f = new Function('a', 'b', 'return a + b') 


    </script>
  </body>
</html>

文章来源:https://blog.csdn.net/qq_57162921/article/details/135157789
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。