如何修改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
相关产品推荐
相关产品推荐

