我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JavaScript知识:构造函数也是函数

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JavaScript知识:构造函数也是函数

首先要明确的是构造函数也是函数

我经常使用构造函数来创建实例对象,例如对象和数组的实例化可以通过相应的构造函数Object()和Array()完成。

构造函数与普通函数在语法的定义上没有任何区别,主要的区别体现在以下3点。

(1)构造函数的函数名的第一个字母通常会大写。按照惯例,构造函数名称的首字母都是要大写的,非构造函数则以小写字母开头。这是从面向对象编程语言那里借鉴的,有助于在ECMAScript中区分构造函数和普通函数。

(2)在函数体内部使用this关键字,表示要生成的对象实例,构造函数并不会显式地返回任何值,而是默认返回“this”。在下面的代码段中,Person()函数并没有使用return关键字返回任何信息,但是输出的变量person1是一个具有name、age属性值的Person实例。


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
      //1.定义构造函数
      function Person(name,age){
        this.age = age;
        this.name = name;
        this.sayName = function(){
            console.log(this.name);
        } 
      }
      // 2.生成实例对象
      var person1 = new Person('小苏','18');
      // 3.打印实例对象
      console.log(person1);
  </script>
</body>
</html>

显示效果如下


(3)作为构造函数调用时,必须与new操作符配合使用。这一点非常重要,任何函数只要使用new操作符调用就是构造函数,而不使用new操作符调用的函数就是普通函数。

1、构造函数的定义与调用

构造函数又称为自定义函数,以函数的形式为自己的对象类型定义属性和方法。

举例:


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
      //1.定义构造函数
      function Person(name,age){
        this.age = age;
        this.name = name;
        this.sayName = function(){
            console.log(this.name);
        } 
      }
      // 2.生成实例对象
      var person1 = new Person('小苏','18');
      // 3.调用方法
      person1.sayName();
  </script>
</body>
</html>

2、new关键字的用途

构造函数在执行时,会执行以下4步:

  • 通过new关键字(操作符)创建实例对象,会在内存中创建一个新的地址。
  • 为构造函数中的this确定指向,指向实例的本身。
  • 执行构造函数代码,为实例添加属性。
  • 返回这个新创建的对象。

以前面生成person1实例的代码为例。

第一步:为person1实例在内存中创建一个新的地址。

第二步:确定person1实例的this指向,指向person本身。

第三步:为person1实例添加name、age和sayName属性,其中sayName属性值是一个函数。

第四步:返回这个person1实例。

举个实例


var person1 = new Person("Bob", 18);

这行代码,等价于


// 演示 new 的功能
function Person(name,age) {
  // 1.创建一个新对象
  var instance = new Object();
  // 2.将函数内部的 this 指向了这个新对象
  this = instance;
  // 3.执行构造函数内部的代码
  this.name = name;
  this.age = age;
  this.sayName = function () {
    console.log(this.name);
  };
  // 4.将新对象作为返回值
  return instance;
}

这就意味着,将instance 赋值给 person1,即person1 = instance。实际上又是这样的:


// 演示 new 的功能
function Person(name,age) {
  // 1.创建一个新对象
  var person1 = new Object();
  // 2.将函数内部的 this 指向了这个新对象
  this = person1;
  // 3.执行构造函数内部的代码
  this.name = name;
  this.age = age;
  this.sayName = function () {
    console.log(this.name);
  };
  // 4.将新对象作为返回值
  return person1;
}

3、构造函数的问题:浪费内存

基本事实:不同实例中的sayName属性是不同的。举个例子:


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // 1.自定义构造函数
    function Person(name,age) {
      this.name = name;
      this.age = age;
      // this 内部的 type 属性值是不变的
      this.type = "human";
      // 每个对象的 sayName 方法也是一样的
      this.sayName = function () {
        console.log(this.name);
      };
    }
    
    var person1 = new Person('Bob',18);
    var person2 = new Person('Mike',20);
    // 2,判断各自的方法是否是同一个函数
    console.log(person1.sayName === person2.sayName); // false
  </script>
</body>
</html>

解释:通过console.log(person1.sayName === person2.sayName)方法可判断两个函数是否是是同一个,显然这不是同一个函数,那么两个函数就占用了两个内存空间,就会造成内存的浪费。

那如何解决函数占用内存的办法呢?答案是将对象内部函数提取出来作为公共函数


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // 解决方法1: 将公共的函数提取到构造函数之外
    function sayName() {
      console.log(this.name);
    }
    function sayAge() {
      console.log(this.age);
    }
    //1.自定义对象
    function Person(name,age) {
      this.name = name;
      this.age = age;
      // this 内部的 type 属性值是不变的
      this.type = "human";
      // 每个对象的 sayName 方法也是一样的
      this.sayName = sayName;
      this.sayAge = sayAge;
    }
    //2.实例化对象
    var person1 = new Person('Bob',18);
    var person2 = new Person('Mike',20);
    console.log(person1.sayName === person2.sayName); // true
    </script>
</body>
</html>

此时,也存在一个问题,如果有多个公共函数,需要在外部创建多个函数,可能会造成命名冲突

解决办法,将多个公共的函数封装到一个对象


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // 3.将多个公共的函数封装到一个对象
    var fns = {
      sayName : function () {
        console.log(this.name);
      },
      sayAge : function () {
        console.log(this.age);
      }      
    };    
    // 1.自定义对象
    function Person(name,age) {
      this.name = name;
      this.age = age;
      this.type = "human";
      this.sayName = fns.sayName;
      this.sayAge = fns.sayAge;
    }
    // 2.生成对象实例
    var person1 = new Person("Bob",18);
    var person2 = new Person("Mike",20);

    // person1.sayName();
    console.log(person1.sayName === person2.sayName);
    console.log(person1.sayAge === person2.sayAge);
  </script>
</body>
</html>

解释:将多个函数封装成一个对象即可解决函数名可能冲突的问题。

通过这种设置全局访问的函数,这样就可以被所有实例访问到,而不用重复创建。

但是这样也会存在一个问题,如果为一个对象添加的所有函数都处理成全局函数,这样并无法完成对一个自定义类型对象的属性封装(言外之意。指的是全局函数只可以封装函数,但无法封装属性,因为属性封装在函数外面,要定义为全局变量,才可以去调用,这反而会污染全局变量),因此这不是一个好的解决办法。

此时,便引用原型的概念,使用原型概念可以很好解决这个问题,可以很好解决这个问题。

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注编程网的更多内容!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JavaScript知识:构造函数也是函数

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C++的构造函数和析构函数是什么

本篇内容主要讲解“C++的构造函数和析构函数是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++的构造函数和析构函数是什么”吧!目录一、构造函数二、C++类的内存模型2.1、只定义成员函数
2023-06-20

javascript构造函数怎么借用

本篇内容主要讲解“javascript构造函数怎么借用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript构造函数怎么借用”吧!说明1、调用子类构造函数中的父类构造函数。采用app
2023-06-20

JavaScript构造函数举例详解

Javascript构造函数是非常强大的,它可能也是Javascript能被充分利用的特点之一,文中通过实例代码介绍的非常详细,这篇文章主要给大家介绍了关于JavaScript构造函数的相关资料,需要的朋友可以参考下
2023-05-14

C++ 函数重载是否适用于构造函数和析构函数?

c++++ 构造函数支持重载,而析构函数不支持。构造函数可具有不同的参数列表,而析构函数只能有一个空参数列表,因为它在销毁类实例时自动调用,不需输入参数。C++ 中函数重载是否适用于构造函数和析构函数?引言函数重载允许函数在名称相同的情
C++ 函数重载是否适用于构造函数和析构函数?
2024-04-14

快速入门:JavaScript 构造函数模式,小白也能秒懂!

JavaScript 构造函数模式是一种创建对象的强大方法。通过使用构造函数,您可以创建具有相同属性和方法的对象实例。这是一篇关于 JavaScript 构造函数模式的快速入门指南,旨在帮助您快速掌握这种模式。
快速入门:JavaScript 构造函数模式,小白也能秒懂!
2024-02-23

什么是java构造函数

构造函数是面向对象中的一员,构造函数可以叫做构造器,它的函数名与类名相同,不用定义返回值类型,也没有具体的返回值。构造函数是在构建创造时对象时调用函数,作用是可以给对象进行初始化,创建对象都必须要通过构造函数初始化。一个类中如果没有定义过构造函数,那么该类会有
什么是java构造函数
2021-05-19

javascript new怎么调用构造函数

本篇内容主要讲解“javascript new怎么调用构造函数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript new怎么调用构造函数”吧!说明1、在内存中创建新对象。2、新对
2023-06-20

EasyC++,构造函数

在C++当中,这种用来构造类的函数,被称为类构造函数。构造函数的原型和函数头有一个比较明显的特征——它虽然没有返回值,但没有被声明称void类型,实际上构造函数没有声明类型。
函数C++原型2024-12-02

Web前端:JavaScript中的构造函数

编程学习网:构造函数,是一种特殊的方法。主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们即构造函数的重载。
Web前端:JavaScript中的构造函数
2024-04-23

JavaScript构造函数怎么自定义

这篇文章主要介绍“JavaScript构造函数怎么自定义”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JavaScript构造函数怎么自定义”文章能帮助大家解决问题。典型的面向对象编程语言(比如C+
2023-07-05

C#中构造函数和析构函数的区别是什么

这篇文章将为大家详细讲解有关C#中构造函数和析构函数的区别是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。C#构造函数和析构函数在你可以访问一个类的方法、属性或任何其它东西之前, ***
2023-06-18

C#中构造函数和析构函数的作用是什么

本篇文章给大家分享的是有关C#中构造函数和析构函数的作用是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。C#构造函数(constructor)包括实例C#构造函数和静态C#
2023-06-17

java中构造函数是什么

构造函数是面向对象中的一员,构造函数可以叫做构造器,它的函数名与类名相同,不用定义返回值类型,也没有具体的返回值。构造函数是在构建创造时对象时调用函数,作用是可以给对象进行初始化,创建对象都必须要通过构造函数初始化。(推荐学习:java课程)一个类中如果没有定
java中构造函数是什么
2021-06-06

编程热搜

目录