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
相关产品推荐
相关产品推荐

