Note 1. ECMAScript. Bound functions.

  • Thread starter Dmitry A. Soshnikov
  • Start date
A

Asen Bozhilov

Lasse said:
Dmitry A. Soshnikov writes:

It's distinguishable from the correct behavior. If you use the bound
function as a method of an instance created from it, then it will
believe it to be a construct call, even if it isn't.

Yes that is true, but is it too far? For example with built in
`Object.create' and `bind' you cannot create an instance by bound
function. Built-in `bind' return function object who does not have
`prototype' property. So in normal case `Object.create' should throw
TypeError. You should need explicitly define `prototype' property and
after that create an instance.
The problem is that you can't identify a construct call
programmatically. Testing whether "this" is an instance of the
function being created can be faked.

Indeed, but as I said emulation of something does not need to
implement all features of original. That approach works in certain
cases and probably I should describe the possible problems by usage of
it.
 
D

Dmitry A. Soshnikov

Yes, there are also some other distinguishes, e.g.:

print(new F1(3) instanceof F1); // false

Or e.g. Asen's implementation dependent on `prototype' property of the
bound function, which shouldn't have such property.
Yes that is true, but is it too far? For example with built in
`Object.create' and `bind' you cannot create an instance by bound
function. Built-in `bind' return function object who does not have
`prototype' property. So in normal case `Object.create' should throw
TypeError. You should need explicitly define `prototype' property and
after that create an instance.

What do you mean? Object.create accepts any object as a future prototype
of the being created object. It doesn't matter, whether you define
`prototype' property on bound function and pass `BoundF.prototype' to
the Object.create, or just a single object. Anyway, defining
`BoundF.prototype' will not change anything in respect of using `new'
operator, because prototype of the newly created object is taken from
the TargetF.prototype.
Indeed, but as I said emulation of something does not need to
implement all features of original. That approach works in certain
cases and probably I should describe the possible problems by usage of
it.

Yes, true, as I mentioned, emulation -- is emulation. For example, how
other emulate `Object.freeze'? there is no way to do this in ES3, so
they just return the object itself -- just the `Object.freeze' is
present now as it would do something.

But taking into account that some distinguishes I nevertheless update
the article again, restoring the state that "it's not possible to
implement spec's behavior for the "bind", although an acceptable
emulation can be made, e.g. -- <and the link to your code here>".

Dmitry.
 
A

Asen Bozhilov

Dmitry said:
Asen Bozhilov wrote:

What do you mean? Object.create accepts any object as a future prototype
of the being created object. It doesn't matter, whether you define
`prototype' property on bound function and pass `BoundF.prototype' to
the Object.create, or just a single object.

var F = (function () {}).bind(obj);

print(F.prototype); //undefined
Object.create(F.prototype); //TypeError

So as I said for creating instance you should explicit define
`prototype' property and after that use, `Object.create'.
 
D

Dmitry A. Soshnikov

var F = (function () {}).bind(obj);

print(F.prototype); //undefined
Object.create(F.prototype); //TypeError

So as I said for creating instance you should explicit define
`prototype' property and after that use, `Object.create'.

Ah, but that's I said -- the fact that you pass F.prototype won't mean
that you created an instance of _exactly_ F. You can do this simply
passing any object, not necessary F.prototype:

Object.create({
constructor: F
});

That I meant.

Dmitry.
 
A

Asen Bozhilov

Dmitry said:
Asen Bozhilov wrote:

Ah, but that's I said -- the fact that you pass F.prototype won't mean
that you created an instance of _exactly_ F. You can do this simply
passing any object, not necessary F.prototype:

Object.create({
   constructor: F

});

That I meant.

Created object here is not an instance of `F'. See example:

function F() {
print(this instanceof F);
}

var obj = Object.create({constructor : F});
obj.constructor();

That object just has constructor property which refer `F' it is not
instance of `F'. So in that case I will pass bounded thisValue to
target function instead of treat as `new Bound();'
 
D

Dmitry A. Soshnikov

Ah, but that's I said -- the fact that you pass F.prototype won't mean
that you created an instance of _exactly_ F. You can do this simply
passing any object, not necessary F.prototype:

Object.create({
constructor: F
});

That I meant.

It can confuse, I mean, in any case even if you define
`BoundF.prototype' and pass it to the `Object.create', `instanceof'
operator won't work. Only if you change `TargetF.prototype':

function F() {}

var BoundF = F.bind(null);

var a = new BoundF;

print(a instanceof BoundF); // true
print(a instanceof F); // true

var boundProto = {
constructor: BoundF,
x: 200
};

BoundF.prototype = boundProto;

var b = Object.create(BoundF.prototype);

// false, because of overloaded [[HasIntance]],
// which delegates to F.[[HasIntance]]
print(b instanceof BoundF);
print(b instanceof F); // of course, false

var c = Object.create(boundProto);

// change target's prototype
F.prototype = boundProto;

print(c instanceof BoundF); // true
print(c instanceof F); // true
print(b instanceof BoundF); // true
print(b instanceof F); // true

Dmitry.
 
D

Dmitry A. Soshnikov

Created object here is not an instance of `F'. See example:

function F() {
print(this instanceof F);
}

var obj = Object.create({constructor : F});
obj.constructor();

That object just has constructor property which refer `F' it is not
instance of `F'. So in that case I will pass bounded thisValue to
target function instead of treat as `new Bound();'

You already figured out my confusing, while I was writing clarification
;) See previous reply -- `instanceof' won't work in any case in testing
with a bound function.

Dmitry.
 
D

Dmitry A. Soshnikov

Ah, but that's I said -- the fact that you pass F.prototype won't mean
that you created an instance of _exactly_ F. You can do this simply
passing any object, not necessary F.prototype:

Object.create({
constructor: F
});

That I meant.

It can confuse, I mean, in any case even if you define
`BoundF.prototype' and pass it to the `Object.create', `instanceof'
operator won't work. Only if you change `TargetF.prototype':

function F() {}

var BoundF = F.bind(null);

var a = new BoundF;

print(a instanceof BoundF); // true
print(a instanceof F); // true

var boundProto = {
constructor: BoundF,
x: 200
};

BoundF.prototype = boundProto;

var b = Object.create(BoundF.prototype);

// false, because of overloaded [[HasIntance]],
// which delegates to F.[[HasIntance]]
print(b instanceof BoundF);
print(b instanceof F); // of course, false

var c = Object.create(boundProto);

// change target's prototype
F.prototype = boundProto;

print(c instanceof BoundF); // true
print(c instanceof F); // true
print(b instanceof BoundF); // true
print(b instanceof F); // true

Another confusing (but conforming) behavior of the `instanceof' is
testing an object created from a _non-bound_ constructor with a bound one:

var object = new F;

alert([
object instanceof F, // true
object instanceof BoundF, // true
]);

I've updated the article mentioning all these cases.

Dmitry.
 
D

Dmitry A. Soshnikov

On 15.06.2010 0:46, Dmitry A. Soshnikov wrote:

I remember one discussion (but can't find it now, if you'll find, let me
know) where joined objects are recognized as not so needed, so I guess
they were removed from ES5 because of that.

Found it: <URL:
http://www.mail-archive.com/[email protected]/msg00082.html>

This is separate replies acknowledge that "joined objects" were mistake
of ES3:

<URL: http://www.mail-archive.com/[email protected]/msg00089.html>
<URL: http://www.mail-archive.com/[email protected]/msg00117.html>

Dmitry.
 
G

Garrett Smith

[about goog.isDef]

FAQ entry proposal regarding:
No, a Function statement is not defined by either 3 or 5 editions.
Function statement is a nonstandard syntax extension.

Please take a look at the FAQ and see if that doesn't clear things up
for you.
http://jibbering.com/faq/#functionStatement

Asen noted that function declaration appearing where only statements are
allowed will result in a SyntaxError in BESEN and DMDScript. I plan to
add that to the FAQ. Currently, we have:

| Implementations that have the function statement extension process
| Fze as a Statement, in order, while other known implementations
| evaluate Fze upon entering the execution context that it appears in.
| For consistent behavior across implementations, avoid function
| statement; use either FunctionExpression or FunctionDeclaration
| instead.

I'd like to change the FAQ to mention that.
Proposed:
| Implementations that have the function statement extension process
| Fze as a Statement, in order. Others, including JScript, evaluate Fze
| upon entering the execution context that it appears in. Yet others,
| notably BESEN and DMDScript, throw a SyntaxError.
|
| For consistent behavior across implementations, do not use function
| statement; use either FunctionExpression or FunctionDeclaration
| instead.
</FAQENTRY>

Garrett
 
B

Benjamin 'BeRo' Rosseaux

Am 15.06.2010 09:00, schrieb Garrett Smith:
Proposed:
| Implementations that have the function statement extension process
| Fze as a Statement, in order. Others, including JScript, evaluate Fze
| upon entering the execution context that it appears in. Yet others,
| notably BESEN and DMDScript, throw a SyntaxError.
|
| For consistent behavior across implementations, do not use function
| statement; use either FunctionExpression or FunctionDeclaration
| instead.

BESEN supports function statements if the facile javascript emulation
compatibility mode is activated (per example with compat("js") if the
BESEN-specific extensions compatibility mode are also activated), but in
the default mode without any activated compatibility mode flags BESEN
doesn't support function statements, to be as possible fully ES5
specification complaint.
 
G

Garrett Smith

Am 15.06.2010 09:00, schrieb Garrett Smith:


BESEN supports function statements if the facile javascript emulation
compatibility mode is activated (per example with compat("js") if the
BESEN-specific extensions compatibility mode are also activated), but in
the default mode without any activated compatibility mode flags BESEN
doesn't support function statements, to be as possible fully ES5
specification complaint.

OK - I did not know about BESEN compatibility mode.

| Yet others, notably DMDScript and default configuration of BESEN,
| throw a SyntaxError.

Garrett
 
G

Garrett Smith

Am 15.06.2010 09:00, schrieb Garrett Smith:
[...]

| Yet others, notably DMDScript and default configuration of BESEN,
| throw a SyntaxError.

I'll be updating the post early next week with this info, unless
somebody has something they want to add.

Garrett
 
G

Garrett Smith

Am 15.06.2010 09:00, schrieb Garrett Smith:
[...]

| Yet others, notably DMDScript and default configuration of BESEN,
| throw a SyntaxError.

I'll be updating the post early next week with this info, unless
somebody has something they want to add.

After reviewing, I decided that the fact of three different known interpreations was not explicitly stated. Since this is an important point, I added it.

"Code that uses function statement has three known interpretations."

The proposed text, so far is this:
+----------------------------------------------------------------------+
What is a function statement?

The term function statement has been widely and wrongly used to
describe a FunctionDeclaration. This is misleading because in
ECMAScript, a FunctionDeclaration is not a Statement; there are places
in a program where a Statement is permitted but a FunctionDeclaration
is not. To add to this confusion, some implementations, notably
Mozillas', provide a syntax extension called function statement. This
is allowed under section 16 of ECMA-262, Editions 3 and 5.

Example of nonstandard function statement:

// Nonstandard syntax, found in GMail source code. DO NOT USE.
try {
// FunctionDeclaration not allowed in Block.
function Fze(b,a){return b.unselectable=a}
/*...*/
} catch(e) { _DumpException(e) }

Code that uses function statement has three known interpretations. Some
implementations process Fze as a Statement, in order. Others, including
JScript, evaluate Fze upon entering the execution context that it
appears in. Yet others, notably DMDScript and default configuration of
BESEN, throw a SyntaxError.

For consistent behavior across implementations, do not use function
statement; use either FunctionExpression or FunctionDeclaration instead.

Example of FunctionExpression (valid):

var Fze;
try {
Fze = function(b,a){return b.unselectable=a};
/*...*/
} catch(e) { _DumpException(e) }

Example of FunctionDeclaration (valid):

// Program code
function aa(b,a){return b.unselectable=a}
+----------------------------------------------------------------------+

Garrett
 
J

John G Harris

What is a function statement?

The term function statement has been widely and wrongly used to
describe a FunctionDeclaration. This is misleading because in
ECMAScript, a FunctionDeclaration is not a Statement; there are places
in a program where a Statement is permitted but a FunctionDeclaration
is not. To add to this confusion, some implementations, notably
Mozillas', provide a syntax extension called function statement. This
is allowed under section 16 of ECMA-262, Editions 3 and 5.
<snip>

"This is allowed" : I prefer "Syntax extensions are allowed".

At first glance it looked as though function statements were mentioned
in the standard and explicitly permitted.

John
 
G

Garrett Smith

On 6/17/2010 4:35 PM, Benjamin 'BeRo' Rosseaux wrote:
Am 15.06.2010 09:00, schrieb Garrett Smith:
[...]

| Yet others, notably DMDScript and default configuration of BESEN,
| throw a SyntaxError.

I'll be updating the post early next week with this info, unless
somebody has something they want to add.

After reviewing, I decided that the fact of three different known interpreations was not explicitly stated. Since this is an important point, I added it.

"Code that uses function statement has three known interpretations."

The proposed text, so far is this:
+----------------------------------------------------------------------+ [...]
+----------------------------------------------------------------------+

I've updated the entry: http://jibbering.com/faq/#functionStatement

Changes made were based on comments from Asen (via Twitter) and Benjamin
Rosseaux reflecting behavior in BESEN and DMDScript.

Garrett
 
J

John G Harris

On 2010-06-21 01:27 PM, Garrett Smith wrote:
After reviewing, I decided that the fact of three different known
interpreations was not explicitly stated. Since this is an important
point, I added it.

"Code that uses function statement has three known interpretations."

The proposed text, so far is this:
+----------------------------------------------------------------------+ [...]
+----------------------------------------------------------------------+

I've updated the entry: http://jibbering.com/faq/#functionStatement

You allowed only 23 hours for comments to be made in reply to your
revised proposal. Might I draw your attention to item 1.4 in the FAQ.

Changes made were based on comments from Asen (via Twitter) and
Benjamin Rosseaux reflecting behavior in BESEN and DMDScript.

Is c.l.j no longer good enough for comments on the FAQ? Was this comment
sensible or nonsense? Will it be archived in Google Groups?

John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top