我正在尝试以这种方式扩展Object功能:
Object.prototype.get_type = function() {
if(this.constructor) {
var r = /\W*function\s+([\w\$]+)\(/;
var match = r.exec(this.constructor.toString());
return match ? match[1].toLowerCase() : undefined;
}
else {
return typeof this;
}
}
很棒,但有一个问题:
var foo = { 'bar' : 'eggs' };
for(var key in foo) {
alert(key);
}
周期将有3个循环。 有什么方法可以避免这种情况吗?
答案 0 :(得分:4)
我,我并不完全反对扩展原生类型和ECMA-262 5th ed。以一种很好的方式为我们解决了其他答案和链接文章中提到的问题。有关概述,请参阅这些slides。
您可以扩展任何对象并定义控制这些属性行为的属性描述符。可以使该属性不可枚举,这意味着当您在for..in
循环中访问对象属性时,该属性将不会包含在内。
以下是如何在Object.prototype本身上定义getType
方法,并使其不可枚举:
Object.defineProperty(Object.prototype, "getType", {
enumerable: false,
writable: false,
configurable: false,
value: function() {
return typeof this;
}
});
// only logs "foo"
for(var name in { "foo": "bar" }) {
console.log(name);
}
上面的getType
函数几乎没用,因为它只返回object
的类型,在大多数情况下它只是对象,但它仅用于演示。
[].getType();
{}.getType();
(6).getType();
true.getType();
答案 1 :(得分:3)
您不应该扩展对象原型,原因如下:
http://erik.eae.net/archives/2005/06/06/22.13.54/
请改用静态方法。
如果您有否选项,则可以使用“hasOwnProperty”方法:
Object.prototype.foo = function(){ alert('x'); }
var x = { y: 'bar' };
for(var prop in x){
if(x.hasOwnProperty(prop)){
console.log(prop);
}
}
答案 2 :(得分:3)
您可以使用hasOwnProperty()
方法检查属性是否属于foo
对象:
var foo = { 'bar' : 'eggs' };
for (var key in foo) {
if (foo.hasOwnProperty(key)) {
alert(key);
}
}
答案 3 :(得分:2)
有什么方法可以避免这种情况吗?
是的,不要扩展原生类型。
改为使用包装器:
var wrapper = (function(){
var wrapper = function(obj) {
return new Wrapper(obj);
};
function Wrapper(o) {
this.obj = obj;
}
Wrapper.prototype = wrapper.prototype;
return wrapper;
}());
// Define your get_type method:
wrapper.prototype.get_type = function(){
if(this.obj.constructor) {
var r = /\W*function\s+([\w\$]+)\(/;
var match = r.exec(this.obj.constructor.toString());
return match ? match[1].toLowerCase() : undefined;
}
else {
return typeof this.obj;
}
};
用法:
var obj = { 'bar' : 'eggs' };
alert(wrapper(obj).get_type());
for(var i in obj) { ... works properly }
答案 4 :(得分:1)
创建您自己的对象,而不是扩展默认对象。
另见:
答案 5 :(得分:1)
当您循环对象的可枚举属性时,您可以使用Object.hasOwnProperty()确定当前属性是否“已继承”
for ( var key in foo )
{
if ( foo.hasOwnProperty( key ) )
{
alert(key);
}
}
但是,让monkey patching的危险告诉你们,特别是在Object
上,正如其他人发布的那样