构造函数与实例成员、静态成员

文章介绍了JavaScript中的构造函数,用于初始化对象并创建多个类似的实例。构造函数通过`new`关键字调用,`this`关键字指代实例对象。实例成员是通过构造函数为对象添加的属性和方法,而静态成员则是直接添加到构造函数上的属性和方法,它们由构造函数自身访问,静态方法中的`this`指向构造函数。

构造函数

  • 构造函数:是一种特殊的函数,主要用来初始化对象
  • 使用场景:常规的 {…} 语法允许创建一个对象。比如我们创建佩奇了一个对象,继续创建乔治的对象还需要重新写一遍,此时可以通过构造函数快速创建多个类似的对象
<script>
	// 普通写法
	const peiqi = {
		name: '佩奇'
	}
	const qiaozhi= {
		name: '乔治'
	}

    // 可以使用如下构造函数:
    function obj(name) {
        this.name = name
    }
    const peiqi = new obj('佩奇')
    console.log(peiqi )
    const qiaozhi = new obj('乔治')
    console.log(qiaozhi )

</script>

总结:

  1. 使用new关键字调用函数的行为被称为实例化
  2. 实例化构造函数时没有参数可以省略()
  3. 构造函数的返回值即为新创建的对象
  4. 构造函数内部的return返回的值无效!

注:实践中为了从视觉上区分构造函数和普通函数,习惯将构造函数的首字母大写。

实例成员

通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员。

<script>
  // 构造函数
  function Person() {
    // 构造函数内部的 this 就是实例对象
    // 实例对象中动态添加属性
    this.name = '小明'
    // 实例对象动态添加方法
    this.sayHi = function () {
      console.log('大家好~')
    }
  }
  // 实例化,p1 是实例对象
  // p1 实际就是 构造函数内部的 this
  const p1 = new Person()
  console.log(p1)
  console.log(p1.name) // 访问实例属性
  p1.sayHi() // 调用实例方法
</script>

总结:

  1. 构造函数内部this实际上就是实例对象,为其动态添加的属性和方法即为实例成员
  2. 为构造函数传入参数,动态创建结构相同但值不同的对象

注:构造函数创建的实例对象彼此独立互不影响。

静态成员

JavaScript中底层函数本质上也是对象类型,因此允许直接为函数动态添加属性或方法,构造函数的属性和方法被称为静态成员。

<script>
  // 构造函数
  function Person(name, age) {
    // 省略实例成员
  }
  // 静态属性
  Person.eyes = 2
  Person.arms = 2
  // 静态方法
  Person.walk = function () {
    console.log('^_^人都会走路...')
    // this 指向 Person
    console.log(this.eyes)
  }
</script>

总结:

  1. 静态成员指的是添加到构造函数本身的属性和方法
  2. 静态成员只能构造函数来访问
  3. 静态成员方法中的 this 指向构造函数本身
<think>我们之前已经详细讨论过静态构造函数的特性,现在用户明确要求比较静态构造函数实例构造函数的区别。需要从触发时机、执行次数、功能用途等方面进行对比,同时保持回答结构化。注意使用LaTeX格式的数学表达式(虽然本问题可能较少涉及数学,但若有公式需规范),并生成相关问题。 关键点回顾: 1. 静态构造函数:类级别初始化,自动触发且仅一次,无参数,隐式私有。 2. 实例构造函数实例级别初始化,每次实例化时触发,可带参数,可设置访问修饰符。 回答结构: 1. 直接对比表格(核心区别) 2. 详细说明各项区别(触发时机、执行次数、参数、访问控制、功能等) 3. 代码示例说明 4. 注意事项 5. 相关问题 注意:引用之前的回答时,若内容相同可复用,但需调整表述以适应当前问题。</think>### 静态构造函数 vs 实例构造函数的区别 | **特性** | 静态构造函数 | 实例构造函数 | |------------------|-----------------------------|---------------------------| | **触发时机** | 类首次被访问时触发(创建实例访问静态成员)[^1] | 每次实例化对象时触发 | | **执行次数** | 整个程序生命周期仅执行一次 | 每次实例化都执行 | | **初始化对象** | 类级别的静态成员(如 `static int count`) | 实例级别的成员(如 `private string name`) | | **参数支持** | 不允许带参数 | 支持参数重载 | | **访问修饰符** | 隐式 `private`(不可显式声明) | 可设为 `public`/`protected` | | **执行顺序** | 优先于实例构造函数执行 | 在静态构造函数之后执行 | | **异常影响** | 失败会导致类完全不可用 | 只影响当前实例 | | **调用方式** | 由运行时自动调用 | 通过 `new` 关键字显式调用 | --- ### 详细说明 #### 1. 初始化对象不同 - **静态构造函数**:初始化**类级别**的静态成员 ```csharp class Counter { public static int Count; // 静态成员 static Counter() { Count = 0; // 初始化静态字段 } } ``` - **实例构造函数**:初始化**对象级别**的实例成员 ```csharp class Person { private string name; // 实例成员 public Person(string n) { name = n; // 初始化实例字段 } } ``` #### 2. 执行时机对比 当首次创建实例时: ```csharp var p = new Person("Alice"); ``` 执行顺序: 1. 静态构造函数 → 2. 实例构造函数 输出: ``` 静态构造先执行 // 仅第一次出现 实例构造后执行 // 每次实例化都出现 ``` #### 3. 线程安全异常处理 - **静态构造函数**: - 默认线程安全(如 C#) - 失败抛出 `TypeInitializationException`,使整个类不可用[^2] ```csharp static MyClass() { throw new Exception("静态构造失败"); } // 后续所有访问都会报错 ``` - **实例构造函数**: - 异常仅影响当前实例 ```csharp try { var obj = new MyClass(); // 失败不影响其他实例 } catch {} ``` #### 4. 设计用途差异 - **静态构造函数适用场景**: - 初始化全局配置(如数据库连接字符串) - 实现单例模式(线程安全初始化) - 注册类型到工厂(如插件系统)[^1] ```csharp class Logger { public static readonly string LogPath; static Logger() { LogPath = LoadConfig(); // 一次性加载配置 } } ``` - **实例构造函数适用场景**: - 初始化对象状态(如设置对象属性) - 资源分配(如打开文件句柄) - 参数化对象创建 ```csharp class FileReader { private Stream fileStream; public FileReader(string path) { fileStream = File.OpenRead(path); // 实例级资源 } } ``` --- ### 关键区别总结 | **维度** | 静态构造函数 | 实例构造函数 | |---------------|-----------------------------|---------------------------| | **作用域** | 类级别 | 对象级别 | | **生命周期** | 应用程序域生命周期 | 对象实例生命周期 | | **资源管理** | 共享资源(如连接池) | 独占资源(如文件句柄) | | **性能影响** | 首次访问可能延迟 | 每次实例化消耗资源 | > 核心区别:**静态构造函数定义类的初始化行为,实例构造函数定义对象的创建行为**。静态构造函数处理"类是什么",实例构造函数处理"对象如何创建"[^1][^2]。 --- ### 相关问题 1. 静态构造函数在继承体系中的执行顺序是怎样的? 2. 如何避免静态构造函数中的循环依赖问题? 3. 为什么静态构造函数不能有访问修饰符或参数? 4. 在不同编程语言(如 Java/Kotlin)中静态构造函数的实现有何差异? 5. 静态构造函数静态初始化块(如 Java)有何异同? [^1]: 静态构造函数专用于类的静态成员初始化,首次访问类时自动触发 [^2]: 静态构造函数失败会导致后续所有访问抛出 TypeInitializationException
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值