Skip to content

Commit

Permalink
Updated docs
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxArt2501 committed Aug 2, 2015
1 parent 004eaea commit 455c49c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
28 changes: 27 additions & 1 deletion doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,32 @@ if (!Object.observe) require("object.observe");

Keep into consideration that this shim *hasn't been developed with node.js in mind*, so it doesn't make use of all the node.js goodies that could make this polyfill more efficient. They may be implemented in the future, but for now it works just fine. Node.js supports `Object.observe` since version 0.12.0, and the "beta" channel does since 0.11.13.

## Loading on a client

In a server side environment, as in node.js (see above), loading the polyfill as a module shouldn't bring any problems. On a client, on the other hand, it's common to pack all the module dependencies in a single file to minimize client requests. Whether using [Browserify](http://browserify.org/), [webpack](http://webpack.github.io/), R.js ([RequireJS](http://requirejs.org/)' packer) or any other tool for the task, developers should be aware that there's no way to reliably dynamically load the polyfill.

For example, using RequireJS, one would do something like:

```js
var dependencies = [ "jquery" ];
if (!Object.observe) dependencies.push("object-observe-lite.min");
define(dependencies, function($) {
...
});
```

But, over the fact that R.js' can't analyze a more complex loading pattern like this one, it simply con't perform a client side test on the server. So, the module is *always* packer in the final script. So, in the end, it's not even necessary to check the definition of `Object.observe`, since the polyfill does it on its own.

It's not even much of a problem, though: the polyfill is currently 2269 bytes minified and gzipped (and 1768 bytes for the "lite" version), so it's probably a bearable load for every client.

If your project does *not* pack the scripts in a single file (which may be fine for small projects or on HTTP2/SPDY connections, or in environments where loading times don't matter), this allows you to load the script only if necessary:

```html
<script>if (Object.observe) document.write('<script src="object-observe.js"></script>')</script>
```

Notice the absence of the `async` attribute, as you would probably load it before everything other script that uses `Object.observe`.

## To do

* Some deeper considerations about whether using `Object.prototype.watch` or not;
Expand Down Expand Up @@ -148,4 +174,4 @@ npm install

Then you can execute `npm run test` or, if you have mocha installed globally, just `mocha` from the package's root directory.

For client side testing, just open [index.html](../test/index.html) in your browser of choice.
For client side testing, just open [index.html](../test/index.html) in your browser of choice.
19 changes: 11 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ That's it. If the environment doesn't already support `Object.observe`, the shim

For client side usage, if you only need the "light" version of the polyfill (see the [documentation](doc/index.md)), replace `object-observe.js` with `object-observe-lite.js`. You can also use the minified versions of the same files (replacing `.js` with `.min.js`). If you want to use the "light" version on the server side, you can either directly reference the desired version with `require` (as in `require("./node_modules/object.observe/dist/object-observe-lite.js");`) or change the `"main"` reference in [`package.json`](package.json).

For more details about loading the polyfill on a client, read the [documentation](doc/index.md#loading-on-a-client).

## Limitations and caveats

* Because properties are polled, when more than one change is made synchronously to the same property, it won't get caught. This means that this won't notify any event:
Expand All @@ -36,11 +38,11 @@ For client side usage, if you only need the "light" version of the polyfill (see
Object.observe(object, function(changes) {
console.log("Changes: ", changes);
});

object.foo = "bar";
object.foo = null;
```

`Object.prototype.watch` could help in this case, but it would be a partial solution.

* Property changes may not be reported in the correct order. The polyfill performs the checks - and issues the notifications - in this order:
Expand All @@ -49,28 +51,28 @@ For client side usage, if you only need the "light" version of the polyfill (see
2. `"delete"` or `"reconfigure"`
3. `"preventExtensions"`
4. `"setPrototype"`

This means that the `"add"` change is listed *before* the `"delete"` in the following snippet:

```js
var obj = { foo: "bar" };
Object.observe(foo, ...);
delete obj.foo;
obj.bar = "foo";
```

Due to the nature of the shim, there's nothing that can be done about it.
* Environments that don't support [`Object.getOwnPropertyNames`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames) (most notably, Internet Explorer prior to version 9) can't detect changes to non-enumerable properties:

```js
var re = /some regex/g;
Object.observe(re, ...);
re.lastIndex = 10;
// Nothing happens...
```

There's no way to prevent this limitation. Developers that need to support those environments should be careful about observing non-plain objects. A special polyfill is provided for arrays and the `length` property.
* Although the polyfill can work on DOM nodes or other *host* objects, the results may be impredictable. Moreover, in older environments like IE8-, observing nodes can be a cumbersome and memory hogging operation: they have a lot of enumerable properties that `Object.observe` should *not* check. Just don't observe nodes: it's not the point of `Object.observe`.
Expand All @@ -85,8 +87,9 @@ This polyfill has been tested (and is working) in the following environments:

* Firefox 35-36 stable and 37-38 Developer Edition
* Internet Explorer 11
* Microsoft Edge 20
* Internet Explorer 5, 7, 8, 9, 10 (as IE11 in emulation mode)
* node.js 0.10.33-36
* node.js 0.10.33-40

It also does *not* overwrite the native implentation in Chrome 36+, Opera 23+, node.js 0.11.13+ and io.js.

Expand Down

0 comments on commit 455c49c

Please sign in to comment.