Comments (12)
That looks interesting, I tried to get a shim for this before based on John Resig's blog post but couldn't get it to work cross browser, this version looks a little more robust however, thanks for pointing it out.
from augment.js.
I've taken a closer look at this version of the shim and I'm not sure it can ever reliably work in IE. Because it eventually fallsback to checking constructor.prototype
the shim will return different things based on how the prototype object was defined.
For example if the prototype is defined without an object literal the result is as expected:
Foo = function () {}
Foo.prototype.bar = "BAZ"
foo = new Foo ()
foo.constructor.prototype.bar // => "BAZ"
However if the prototype is defined using an object literal the constructor prototype points to Object.prototype
Foo = function () {}
Foo.prototype = {
bar: "BAZ"
}
foo = new Foo ()
foo.constructor.prototype.bar // does not return "BAZ"
I have set up a little test that demonstrates this here.
If this is correct then I'm not sure it is a good idea to include the shim as part of augment, ideally all shims should behave very closely to the native implementations. Otherwise you will get different behaviour for the same methods depending on which browser they run in.
I'm more than willing to be proved wrong however, if you can see a way to make this behave as expected I'd be very happy to include it as part of augment.
from augment.js.
This is a generally-known problem (regarding the difference-in-operation on I.E. versus, well, the rest of the world); how about instead exposing a cross-browser-consistent version of the I.E. functionality called getConstructorPrototypeOf
, that will operate identically to getPrototypeOf
in well-behaved code (i.e. code that maintains the constructor.prototype.constructor
relationship), but at least operate predictably and consistently even on non-well-behaved code, in I.E. and elsewhere?
from augment.js.
Thats an interesting approach to the problem. I don't think there is anyway to implement Object.getPrototypeOf in JavaScript in a cross browser way. I'm not sure however that adding non-standard methods to augment is the correct way to solve this problem.
I think your getConstructorPrototypeOf
might be more suited to supplement.js and I'd be more than happy to accept a patch to add it there. I feel that augment.js should only contain standard methods and only where they can be reliably implemented in JavaScript.
from augment.js.
I’d agree, except that this is something that is “reliably implementable” everywhere except out-of-date IEs. In my opinion, out-of-date IEs “don’t matter,” beyond minimum efforts to make things work even to some minimal extent. Any sysadmin forcing an ancient IE upon their users is basically signing them up for the Shitty Web™, so there’s not a lot of point in wasting time/effort on it, or making a product of a lower quality overall just to pander to them.
… all that said, you, as the maintainer of this project, may disagree. ;D
from augment.js.
Object.getPrototypeOf
is a simple return this.__proto__
in all non-IE browsers.
In IE browsers it's a simple return this.constructor.prototype
The only case it breaks if people use new Constr
but forget to set Constr.prototype.constructor
and then that's basically saying if you write bad code the method breaks.
The solution is warning people not to write bad code rather then not giving people a method that works.
from augment.js.
@ELLIOTTCABLE - the main reason to use augment.js is to be able to seamlessly use the more modern JavaScript methods in old browsers such as IE. TBH if you are not supporting IE less than 8 you probably aren't getting a huge amount of benefit from augment.js since the browser share of old versions of safari, firefox etc are quite small.
@Raynos - if the Constr.prototype.constructor
has been set then yes this does work. I must have been writing some bad code for quite a while now though as I don't think I've ever actually set that in my own code!
Perhaps this method could be added, with the caveat that you must set the constructor property in your prototype in IE if you are defining a prototype using an object literal. I guess without augment.js you would have to do this anyway to get similar behaviour.
Ideally I would like to be able to throw some kind of error in IE if Constr.prototype.constructor
has not been set, just so that you are forced to do this if you want to use this method in IE.
I'll try and put something together this week, I'd appreciate any feedback on the implementation once its done.
from augment.js.
@olivernn that’s entirely my point. This only doesn’t work in the case of writing_bad_code LOGICAL AND developing_for_IE
, and IMO, there’s so little of an excuse for the entirety of the set union applying to those situations, that it’s entirely includable.
Not a big deal either way, I suppose. ^_^
from augment.js.
Okay this is what I have so far, this does work in IE.
;(function () { "use strict"
var ensureIsObject = function (param) {
if (param !== Object(param)) throw new TypeError('Object.getPrototypeOf called on non-object');
}
if (!Object.getPrototypeOf) {
if (typeof "test".__proto__ === "object") {
Object.getPrototypeOf = function (obj) {
ensureIsObject(obj)
return obj.__proto__
}
} else {
Object.getPrototypeOf = function (obj) {
ensureIsObject(obj)
return obj.constructor.prototype
}
};
};
})();
I'm toying with the idea of adding a check to the IE version that throws a warning if you are setting the prototype using an object literal but haven't set the constructor
property. So far though the only way I can see to do this is something like this:
({}).constructor.prototype === obj.constructor.prototype
The problem with this would be if you were calling Object.getPrototypeOf
on a plain object. I'm not entirely sure why you would be doing this, but if you did want to, throwing an error here would mean you were screwed. Perhaps this check is unnecessary though, thoughts?
from augment.js.
… that test is already incorrect, right off the bat, isn’t it? As (new new Function()()).constructor.prototype !== Object.prototype
. When you create a new function, a new prototype object is immediately created for it, is it not? Thus, there’s no real way to determine if <something>.constructor
’s .prototype
was changed after new <something>.constructor()
resulted in the construction. At least, that I can think of off the top of my head.
from augment.js.
Yeah good catch - was just hoping that there was a way to catch the case where the prototype was assigned to an object literal but constructor hadn't been set. TBH trying to catch it will probably cause more problems then it would solve.
I'll try and put together a release sometime this week with Object.getPrototypeOf
included. There are a couple of other build related things I'd like to clean up as well though so it could be a couple of days.
from augment.js.
I've just released version 0.4.0 of augment that includes the discussed implementation of Object.getPrototypeOf
.
from augment.js.
Related Issues (14)
- Wrong string.trim implementation HOT 1
- Object.create missing on purpose? HOT 1
- Use a better trim implementation HOT 5
- Suggestion HOT 1
- Add Object.create HOT 2
- Extended Years not supported by Date.prototype.toISOString HOT 5
- how does this compare to es5-shim? HOT 5
- dontEnum bug HOT 1
- ES5 bind HOT 1
- Potential edge case bugs HOT 4
- Customisable build. HOT 1
- Docs Site Down HOT 1
- Can we add string.include method? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from augment.js.