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

JavaScript中for...in循环为何会输出实例的changeName方法?

为啥for...in循环会输出changeName方法?

嘿,这个问题我太熟啦!咱们来一步步拆解为啥会出现这个情况:

首先看你写的构造函数代码:

function person(name, age) {
  this.name = name;
  this.age = age;
  this.changeName = changeName;
  function changeName(name) {
    this.name = name;
  }
}

你在这里把changeName函数直接赋值给了this.changeName——这意味着当你用new person("Ying", 21)创建my实例时,changeName是作为实例自身的可枚举属性存在的,而不是挂在person的原型链上。

接下来要说到for...in循环的核心特性:它会遍历对象自身的所有可枚举属性,不管属性的值是字符串、数字还是函数。默认情况下,直接赋值给对象的属性(比如你这里的name、age、changeName)都是可枚举的,所以for...in会把这三个属性全部捞出来。

最后你用document.write(my[i])输出的时候,函数对象会被自动转换成字符串形式,也就是它的源码文本,所以你就看到了function changeName(name) { this.name = name; }这段内容。

如果你不想让方法被for...in遍历到,有几个常用的解决办法:

  • 把方法挂载到构造函数的原型上:
    function person(name, age) {
      this.name = name;
      this.age = age;
    }
    person.prototype.changeName = function(name) {
      this.name = name;
    }
    
    之后遍历的时候可以用my.hasOwnProperty(i)来过滤原型链上的属性;
  • 用Object.defineProperty()把属性设置为不可枚举:
    function person(name, age) {
      this.name = name;
      this.age = age;
      Object.defineProperty(this, 'changeName', {
        value: function(name) { this.name = name; },
        enumerable: false
      });
    }
    
  • 更推荐用ES6的class语法,class里的方法默认是不可枚举的,写法也更清晰:
    class Person {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
      changeName(name) {
        this.name = name;
      }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:51:21