I'm trying to extend Object functionality this way:
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;
}
}
It's great, but there is a problem:
var foo = { 'bar' : 'eggs' };
for(var key in foo) {
alert(key);
}
There'll be 3 passages of cycle. Is there any way to avoid this?
I'm trying to extend Object functionality this way:
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;
}
}
It's great, but there is a problem:
var foo = { 'bar' : 'eggs' };
for(var key in foo) {
alert(key);
}
There'll be 3 passages of cycle. Is there any way to avoid this?
Share Improve this question edited Feb 20, 2014 at 12:38 Akshay 3,4111 gold badge24 silver badges19 bronze badges asked May 26, 2010 at 14:08 UnstableFractalUnstableFractal 1,4222 gold badges15 silver badges29 bronze badges 2- I highly remend Prototypal Inheritance in JavaScript and Classical Inheritance in JavaScript if you haven't already read them. They're useful when trying to grok OOP in JavaScript. NOTE: The Prototypal post is newer than the Classical post, so I'd consider it authoritative if you spot a conflict or change in opinion. – Hank Gay Commented May 26, 2010 at 14:16
- Don't! Just... don't! Every time you add something to a function's prototype's that you don't own, a person dies, just like that!!! – Pablo Cabrera Commented May 26, 2010 at 14:28
6 Answers
Reset to default 4I, for one, am not pletely against extending native types and ECMA-262 5th ed. solves the problems mentioned in other answers and linked articles for us in a nice manner. See these slides for a good overview.
You can extend any object and define property descriptors that control the behavior of those properties. The property can be made non enumerable meaning when you access the objects properties in a for..in
loop, that property will not be included.
Here's how you can define a getType
method on Object.prototype itself, and make it non enumerable:
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);
}
The getType
function above is mostly useless as it simply returns the typeof object
which in most cases will simply be object, but it's only there for demonstration.
[].getType();
{}.getType();
(6).getType();
true.getType();
You shouldn't extend the object prototype, for that exact reason:
http://erik.eae/archives/2005/06/06/22.13.54/
Use a static method instead.
If you have no choice, you can use the "hasOwnProperty" method:
Object.prototype.foo = function(){ alert('x'); }
var x = { y: 'bar' };
for(var prop in x){
if(x.hasOwnProperty(prop)){
console.log(prop);
}
}
You can use the hasOwnProperty()
method to check if the property belongs to the foo
object:
var foo = { 'bar' : 'eggs' };
for (var key in foo) {
if (foo.hasOwnProperty(key)) {
alert(key);
}
}
Is there any way to avoid this?
Yes, don't extend native types.
Use a wrapper instead:
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;
}
};
Usage:
var obj = { 'bar' : 'eggs' };
alert(wrapper(obj).get_type());
for(var i in obj) { ... works properly }
When you loop over enumerable properties of an object, you can can determin if the current property was "inherited" or not with Object.hasOwnProperty()
for ( var key in foo )
{
if ( foo.hasOwnProperty( key ) )
{
alert(key);
}
}
But let the dangers of monkey patching be known to ye, especially on Object
, as others have posted about
Create your own object instead of extending the default Object.
Also see:
- http://erik.eae/archives/2005/06/06/22.13.54/
- http://dean.edwards.name/weblog/2006/07/erlaubt/
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742362640a4429687.html
评论列表(0条)