You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Person函数返回值,使有无new调用时instanceof均为true?

解决方案:让构造函数兼容无new调用的实例判断

这个问题的核心是搞懂instanceof的判断逻辑,以及构造函数在有无new调用时的行为差异。先拆解下你原来代码的问题:

  • 用new Person('ss')调用时,函数内部的this指向新创建的Person实例,哪怕你写了return false,new调用会忽略非对象类型的返回值,依然返回this,所以p1 instanceof Person为true。
  • 直接调用Person('sdd')时,函数里的this指向全局对象(浏览器环境是window,Node.js是globalThis),你返回了false这个基本类型值,所以p2是布尔值false,基本类型不属于任何自定义构造函数的实例,因此p2 instanceof Person返回false。

要实现无new调用时p2 instanceof Person也为true,你需要让函数返回原型链包含Person.prototype的对象,最稳妥的方式是返回一个Person实例。

修改后的代码

function Person(name){
  this.name = name;
  // 检查当前this是否是Person的实例(即是否通过new调用)
  if (!(this instanceof Person)) {
    // 如果不是new调用,返回一个新的Person实例
    return new Person(name);
  }
  // 是new调用的话,返回this(new调用时即使省略return,也会默认返回this)
  return this;
}

var p1 = new Person('ss');
var p2 = Person('sdd');

console.log(p1 instanceof Person); // true
console.log(p2 instanceof Person); // true

原理说明

instanceof的判断规则是:右侧构造函数的prototype属性是否存在于左侧对象的原型链上。上面的代码中,无论是否用new调用,最终返回的都是Person的实例,其原型链上必然包含Person.prototype,因此两次instanceof检查都会返回true。

如果你想更简洁,也可以直接返回一个基于Person.prototype创建的对象并设置属性,不过上面的写法能完整复用构造函数的逻辑,更符合常规的构造函数设计:

function Person(name){
  const instance = Object.create(Person.prototype);
  instance.name = name;
  return instance;
}

内容的提问来源于stack exchange,提问作者user5711656

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:00:54