tc39 / proposal-bind-operator

This-Binding Syntax for ECMAScript
1.74k stars 30 forks source link

Implementation using native current JavaScript #49

Closed 7fe closed 7 years ago

7fe commented 7 years ago

Parts of this can be done already using .toString() and the obj[val]() syntax. For example here. If you were looking for backwards compatibility you could adopt a similar syntax to keep JavaScript language from getting to complex and also to Ruby like.

http://limeblack.github.io/UnlimitJS

and an example.

<!doctype html><script src="http://limeblack.github.io/UnlimitJS/unlimit.js"></script>
<scrip>var yell = function(){
  alert(''+this);
  return this;
}[Unlimit]();

'Example string'[yell]()[yell]();
</script>
ljharb commented 7 years ago

A library that mutates globals (if I'm reading it correctly) isn't a viable option.

7fe commented 7 years ago

@ljharb I guess it's a syntax proposal then that is backwards compatible with a polyfill.

Lot's of polyfills modify globals it wouldn't have to internally just for backwards compatibility.

robotlolita commented 7 years ago

Just gonna note here that complexity arises when you make existing syntax do more than one thing, not when you add new syntax to do something very specific. In the first case everyone needs to learn the new special semantics, even if they have no intention of using the feature. Plus, now they have to figure out from the context when that syntax is going to behave like X or Y. The latter (adding new syntax) does not have this problem.

I'm extremely against making existing syntax do things observably different from what they do now, in particular when that also involves breaking every existing program.

7fe commented 7 years ago

It supports IE6 and doesn't break every existing programs. Not sure where you got that idea.

Either way I believe I understand your point.

michaelficarra commented 7 years ago

@limeblack I think you may want to take a look at the interfaces proposal. It seems to have overlapping goals with your unlimit.js library: safely treating built-in or foreign data types as if you've added new behaviour to them. That is also where this bind operator proposal overlaps with the interfaces proposal.

robotlolita commented 7 years ago

@limeblack my point is that changing the meaning of a[b]() is going to break existing programs.

7fe commented 7 years ago

ahh yes well I would assume we would only change the a[b]() syntax for functions in the operator [func]. But I definitely do agree the syntax is confusing. I will likely close this issue in a bit. I will read the interfaces proposal.

7fe commented 7 years ago

I reopened this issue because this can be done without mutating global's using a Symbol object in a couple different ways.

<!doctype html><script>(function(){
  var s = Symbol();
  var Unlimit = window.Unlimit = {toString:function(){return s}};
  Unlimit.fn = Symbol();
  Object.prototype[Unlimit] = function(fn){
    Unlimit.fn.call(this);
  };
})();

yell = function(a){alert('a');return this;};
yell.toString = function(){
   Unlimit.fn = this;
   return Unlimit.toString();
};

'test'[yell]();

</script>
Volune commented 7 years ago

@limeblack You may want to have a look at this experimental library too.

bathos commented 7 years ago

As an experiment this sort of thing is fun, but it’s a hack for sure — not something people should realistically use. While the global state leak above could be partially patched up sort of, and a symbol key is indeed an upgrade if you really want to patch Object.prototype, it’s still based on hidden side effects and abusing (+ squatting over) toString. It also isn’t a generic solution —

const bar = Object.create(null);
bar[yell](); // throws error

(I’d also point out that if this is considered an "implementation using native current JavaScript", then by that logic it already is implemented in current JS, since we already have Function.prototype.call, which doesn’t have these holes.)