在使用 `new` 关键字创建对象时,如果忘记添加 `new` 关键字会发生什么?

简介: 【10月更文挑战第31天】`SafeConstructor` 函数中,通过检查 `this` 是否为 `SafeConstructor` 的实例来判断是否使用了 `new` 关键字。如果没有使用,则自动使用 `new` 关键字重新调用自身,确保始终返回一个正确的对象实例。

在使用 new 关键字创建对象时,如果忘记添加 new 关键字,会导致函数以普通函数的方式被调用,从而产生与预期不同的结果:

全局作用域污染

  • 如果构造函数内部使用了 this 关键字来初始化对象的属性,在忘记添加 new 关键字的情况下,this 会指向全局对象(在浏览器环境中是 window 对象)。这可能会导致意外地在全局作用域中创建属性,从而污染全局命名空间。
function Person(name, age) {
   
  this.name = name;
  this.age = age;
}

var person = Person('Alice', 25);
console.log(window.name); 
console.log(window.age);

在上述示例中,由于忘记使用 new 关键字,Person 函数内部的 this 指向了 window,导致在全局作用域下创建了 nameage 两个属性。

函数内部逻辑错误

  • 除了全局作用域污染问题,由于函数没有以构造函数的方式被调用,其内部的逻辑可能无法正常执行。例如,如果构造函数中存在一些依赖于 this 指向正确对象实例的逻辑,那么在忘记添加 new 关键字时,这些逻辑可能会出错。
function Counter() {
   
  this.count = 0;
  this.increment = function() {
   
    this.count++;
  };
}

var counter = Counter();
counter.increment(); 
console.log(counter.count);

在上述示例中,Counter 函数在没有使用 new 关键字调用时,increment 方法中的 this 指向了全局对象,而全局对象上并没有 count 属性,所以执行 increment 方法时会出现错误,并且无法正确地更新和获取 count 的值。

返回值问题

  • 正常使用 new 关键字创建对象时,构造函数会自动返回一个新创建的对象实例。但如果忘记添加 new 关键字,函数将按照普通函数的返回规则执行。如果函数没有显式地使用 return 语句返回一个值,那么函数调用的结果将是 undefined;如果函数显式地返回了一个原始值或其他非对象类型的值,那么返回的将是该值,而不是一个新创建的对象实例。
function MyObject() {
   
  this.property = 'Value';
  return 'Not an object';
}

var obj = MyObject();
console.log(obj); 
console.log(obj.property);

在上述示例中,MyObject 函数在没有使用 new 关键字的情况下被调用,并且显式地返回了一个字符串。因此,obj 的值为 'Not an object',尝试访问 obj.property 会导致错误,因为 obj 并不是一个具有 property 属性的对象。

为了避免这些问题,在使用构造函数创建对象时,务必确保添加 new 关键字。另外,也可以在构造函数内部通过一些方式来检测是否使用了 new 关键字进行调用,并在必要时进行相应的处理,以增强代码的健壮性。例如:

function SafeConstructor() {
   
  if (!(this instanceof SafeConstructor)) {
   
    return new SafeConstructor();
  }
  this.property = 'Safe';
}

var safeObj1 = new SafeConstructor();
var safeObj2 = SafeConstructor();

console.log(safeObj1.property); 
console.log(safeObj2.property);

在上述改进后的 SafeConstructor 函数中,通过检查 this 是否为 SafeConstructor 的实例来判断是否使用了 new 关键字。如果没有使用,则自动使用 new 关键字重新调用自身,确保始终返回一个正确的对象实例。

相关文章
|
6月前
|
C#
30.C# 关键字 this初步学习
30.C# 关键字 this初步学习
38 1
|
存储 算法 编译器
带你了解并掌握一些C++关键字的使用
带你了解并掌握一些C++关键字的使用
96 0
|
13天前
静态方法中可以使用 this 关键字吗?
静态方法中的 `this` 关键字主要用于访问类的静态成员,但在使用时要清楚其指向和限制,避免因错误地使用 `this` 而导致程序出现意外的行为和错误。
|
3月前
|
C# 计算机视觉
C#中out关键字
C#中out关键字
62 0
|
5月前
|
Java API
RentrantLock关键字详解
RentrantLock关键字详解
|
6月前
|
C++
|
Java
关键字this
关键字this
57 0
|
Java 编译器
复习篇【类的构造方法与代码块的执行】
复习篇【类的构造方法与代码块的执行】
复习篇【类的构造方法与代码块的执行】
|
存储 C#
C# 修饰关键字解析
C# 修饰关键字解析