Git Product home page Git Product logo

Comments (12)

olivernn avatar olivernn commented on August 11, 2024

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.

olivernn avatar olivernn commented on August 11, 2024

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.

ELLIOTTCABLE avatar ELLIOTTCABLE commented on August 11, 2024

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.

olivernn avatar olivernn commented on August 11, 2024

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.

ELLIOTTCABLE avatar ELLIOTTCABLE commented on August 11, 2024

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.

Raynos avatar Raynos commented on August 11, 2024

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.

olivernn avatar olivernn commented on August 11, 2024

@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.

ELLIOTTCABLE avatar ELLIOTTCABLE commented on August 11, 2024

@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.

olivernn avatar olivernn commented on August 11, 2024

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.

ELLIOTTCABLE avatar ELLIOTTCABLE commented on August 11, 2024

… 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.

olivernn avatar olivernn commented on August 11, 2024

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.

olivernn avatar olivernn commented on August 11, 2024

I've just released version 0.4.0 of augment that includes the discussed implementation of Object.getPrototypeOf.

from augment.js.

Related Issues (14)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.