| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| I still have a question regarding the following code, in a commonly used routine. First, Here's the code in question: Function.prototype.bind = function(){ var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift(); return function(){ return fn.apply(object, args.concat(Array.prototype.slice.call(arguments)) ); }; }; var myObject = {}; function myFunction(){ return this == myObject; } In the code, return fn.apply(object, args.concat(Array.prototype.slice.call(arguments)) ); , it seems apply is getting an extra, array element (because the first element in arguments is still the object (the one setting the context of "this). In short, it looks to me like the object element which sets the context of "this" is in the final args array twice (twice at the beginning of the array). This can't be. I must be wrong, Please explain . |
|
#2
| |||
| |||
| lorlarz wrote: > I still have a question regarding the following code, > in a commonly used routine. First, Here's the code in > question: > > Function.prototype.bind = function(){ > var fn = this, args = Array.prototype.slice.call(arguments), object = > args.shift(); > return function(){ > return fn.apply(object, > args.concat(Array.prototype.slice.call(arguments)) ); > > > }; > }; > > > var myObject = {}; > function myFunction(){ > return this == myObject; > > > } > > In the code, > return fn.apply(object, > args.concat(Array.prototype.slice.call(arguments)) ); > , > it seems apply is getting an extra, > array element (because the first element in arguments > is still the object (the one setting the context of "this). > The anonymous function's arguments object is not the same arguments object of the enclosing bind function. > In short, it looks to me like the object element which > sets the context of "this" is in the final args array > twice (twice at the beginning of the array). > It would seem to be less confusing to pass in an actual parameter variable for the context, and include a comment:- /** * @param {Object} context - the - this - value to be used. * @param {arguments} [1..n] optional arguments that are prepended * to returned function's call. * @return {Function} a function that applies the original * function with - context - as the thisArg. */ Function.prototype.bind = function(context){ ... } This will affect the args variable and the way you call slice. Take a closer look at args.shift, too. http://bclary.com/2004/11/07/#a-15.4.4.9 Garrett |
|
#3
| |||
| |||
| On Sep 6, 12:37*pm, dhtml <dhtmlkitc...@gmail.com> wrote: > lorlarz wrote: > > I still have a question regarding the following code, > > in a commonly used routine. *First, Here's the code in > > question: > > > Function.prototype.bind = function(){ > > var fn = this, args = Array.prototype.slice.call(arguments), object= > > args.shift(); > > return function(){ > > return fn.apply(object, > > args.concat(Array.prototype.slice.call(arguments)) ); > > > * *}; > > }; > > > var myObject = {}; > > function myFunction(){ > > return this == myObject; > > > } > > > In the code, > > return fn.apply(object, > > args.concat(Array.prototype.slice.call(arguments)) ); > > , > > it seems apply is getting an extra, > > array element (because the first element in arguments > > is still the object (the one setting the context of "this). > > The anonymous function's arguments object is not the same arguments > object of the enclosing bind function. > > > In short, it looks to me like the object element which > > sets the context of "this" is in the final args array > > twice (twice at the beginning of the array). > > It would seem to be less confusing to pass in an actual parameter > variable for the context, and include a comment:- > > /** > * * @param {Object} context - the - this - value to be used. > * * @param {arguments} [1..n] optional arguments that are prepended > * * to returned function's call. > * * @return {Function} a function that applies the original > * * function with - context - as the thisArg. > * */ > Function.prototype.bind = function(context){ > * ... > > } > > This will affect the args variable and the way you call slice. > > Take a closer look at args.shift, too. > > http://bclary.com/2004/11/07/#a-15.4.4.9 > > Garrett Your clarification was great and I understand and I agree with your input as well. Thank you. |
|
#4
| |||
| |||
| lorlarz wrote: > On Sep 6, 12:37 pm, dhtml <dhtmlkitc...@gmail.com> wrote: >> lorlarz wrote: >>> I still have a question regarding the following code, >>> in a commonly used routine. First, Here's the code in >>> question: >>> Function.prototype.bind = function(){ >>> var fn = this, args = Array.prototype.slice.call(arguments), object = >>> args.shift(); >>> return function(){ >>> return fn.apply(object, >>> args.concat(Array.prototype.slice.call(arguments)) ); >>> }; >>> }; >>> var myObject = {}; >>> function myFunction(){ >>> return this == myObject; >>> } >>> In the code, >>> return fn.apply(object, >>> args.concat(Array.prototype.slice.call(arguments)) ); >>> , >>> it seems apply is getting an extra, >>> array element (because the first element in arguments >>> is still the object (the one setting the context of "this). >> The anonymous function's arguments object is not the same arguments >> object of the enclosing bind function. >> >>> In short, it looks to me like the object element which >>> sets the context of "this" is in the final args array >>> twice (twice at the beginning of the array). >> It would seem to be less confusing to pass in an actual parameter >> variable for the context, and include a comment:- >> >> /** >> * @param {Object} context - the - this - value to be used. >> * @param {arguments} [1..n] optional arguments that are prepended >> * to returned function's call. >> * @return {Function} a function that applies the original >> * function with - context - as the thisArg. >> */ >> Function.prototype.bind = function(context){ >> ... >> >> } >> >> This will affect the args variable and the way you call slice. >> >> Take a closer look at args.shift, too. >> >> http://bclary.com/2004/11/07/#a-15.4.4.9 >> >> Garrett > > Your clarification was great and I understand and I > agree with your input as well. Thank you. Well I didn't really help you all that much. But you could post up some code to show us. There may also be the consideration that this method does two things: 1) partial apply 2) bind Most of the you won't usually need all of this functionality together. And will just need a bind. There are a few potential problems with adding Function.prototype.bind: If, for example, the next version of EcmaScript includes Function.prototype.bind, and it does it differently than your user-defined one, it might confuse other programmers who looked at the calls to the would-be non-standard bind. Some versions of bind that I've seen just a bind (fast), while others use partialApply + bind (slower). Existing code stuck with a partialApply + bind assinged to Function.prototype.bind could be tweaked for efficiency, refactored to use some other approach that is efficient and uses a safer name, allowing for the possibility of deprecating (not removing) the old Function.prototype.bind. Garrett |
|
#5
| |||
| |||
| On Sep 6, 10:12*pm, dhtml <dhtmlkitc...@gmail.com> wrote: > lorlarz wrote: > > On Sep 6, 12:37 pm, dhtml <dhtmlkitc...@gmail.com> wrote: > >> lorlarz wrote: > >>> I still have a question regarding the following code, > >>> in a commonly used routine. *First, Here's the code in > >>> question: > >>> Function.prototype.bind = function(){ > >>> var fn = this, args = Array.prototype.slice.call(arguments), object = > >>> args.shift(); > >>> return function(){ > >>> return fn.apply(object, > >>> args.concat(Array.prototype.slice.call(arguments)) ); > >>> * *}; > >>> }; > >>> var myObject = {}; > >>> function myFunction(){ > >>> return this == myObject; > >>> } > >>> In the code, > >>> return fn.apply(object, > >>> args.concat(Array.prototype.slice.call(arguments)) ); > >>> , > >>> it seems apply is getting an extra, > >>> array element (because the first element in arguments > >>> is still the object (the one setting the context of "this). > >> The anonymous function's arguments object is not the same arguments > >> object of the enclosing bind function. > > >>> In short, it looks to me like the object element which > >>> sets the context of "this" is in the final args array > >>> twice (twice at the beginning of the array). > >> It would seem to be less confusing to pass in an actual parameter > >> variable for the context, and include a comment:- > > >> /** > >> * * @param {Object} context - the - this - value to be used. > >> * * @param {arguments} [1..n] optional arguments that are prepended > >> * * to returned function's call. > >> * * @return {Function} a function that applies the original > >> * * function with - context - as the thisArg. > >> * */ > >> Function.prototype.bind = function(context){ > >> * ... > > >> } > > >> This will affect the args variable and the way you call slice. > > >> Take a closer look at args.shift, too. > > >>http://bclary.com/2004/11/07/#a-15.4.4.9 > > >> Garrett > > > Your clarification was great and I understand and I > > agree with your input as well. *Thank you. > > Well I didn't really help you all that much. But you could post up some > code to show us. > > There may also be the consideration that this method does two things: > 1) partial apply > 2) bind > > Most of the you won't usually need all of this functionality together. > And will just need a bind. > > There are a few potential problems with adding Function.prototype.bind: > > If, for example, the next version of EcmaScript includes > Function.prototype.bind, and it does it differently than your > user-defined one, it might confuse other programmers who looked at the > calls to the would-be non-standard bind. > > Some versions of bind that I've seen just a bind (fast), while others > use partialApply + bind (slower). > > Existing code stuck with a partialApply + bind assinged to > Function.prototype.bind could be tweaked for efficiency, refactored to > use some other approach that is efficient and uses a safer name, > allowing for the possibility of deprecating (not removing) the old > Function.prototype.bind. > > Garrett- Hide quoted text - > > - Show quoted text - Here is a script to put in a web page and run, using the new bind method of functions: Function.prototype.bind = function(){ var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift(); return function(){ return fn.apply(object, args.concat(Array.prototype.slice.call(arguments)) ); }; }; var myObject = {}; function myFunction(thename){ alert(thename); return this == myObject; } alert((myFunction.bind(myObject, "joe"))()); Since the returned function gets all its arguments from myFunction (the object using the new Function bind methed), the second argument sent the returned function's first -- after the object is stripped of as its context. |
|
#6
| |||
| |||
| On Sep 6, 10:12*pm, dhtml <dhtmlkitc...@gmail.com> wrote: > lorlarz wrote: > > On Sep 6, 12:37 pm, dhtml <dhtmlkitc...@gmail.com> wrote: > >> lorlarz wrote: > >>> I still have a question regarding the following code, > >>> in a commonly used routine. *First, Here's the code in > >>> question: > >>> Function.prototype.bind = function(){ > >>> var fn = this, args = Array.prototype.slice.call(arguments), object = > >>> args.shift(); > >>> return function(){ > >>> return fn.apply(object, > >>> args.concat(Array.prototype.slice.call(arguments)) ); > >>> * *}; > >>> }; > >>> var myObject = {}; > >>> function myFunction(){ > >>> return this == myObject; > >>> } > >>> In the code, > >>> return fn.apply(object, > >>> args.concat(Array.prototype.slice.call(arguments)) ); > >>> , > >>> it seems apply is getting an extra, > >>> array element (because the first element in arguments > >>> is still the object (the one setting the context of "this). > >> The anonymous function's arguments object is not the same arguments > >> object of the enclosing bind function. > > >>> In short, it looks to me like the object element which > >>> sets the context of "this" is in the final args array > >>> twice (twice at the beginning of the array). > >> It would seem to be less confusing to pass in an actual parameter > >> variable for the context, and include a comment:- > > >> /** > >> * * @param {Object} context - the - this - value to be used. > >> * * @param {arguments} [1..n] optional arguments that are prepended > >> * * to returned function's call. > >> * * @return {Function} a function that applies the original > >> * * function with - context - as the thisArg. > >> * */ > >> Function.prototype.bind = function(context){ > >> * ... > > >> } > > >> This will affect the args variable and the way you call slice. > > >> Take a closer look at args.shift, too. > > >>http://bclary.com/2004/11/07/#a-15.4.4.9 > > >> Garrett > > > Your clarification was great and I understand and I > > agree with your input as well. *Thank you. > > Well I didn't really help you all that much. But you could post up some > code to show us. > > There may also be the consideration that this method does two things: > 1) partial apply > 2) bind > > Most of the you won't usually need all of this functionality together. > And will just need a bind. > > There are a few potential problems with adding Function.prototype.bind: > > If, for example, the next version of EcmaScript includes > Function.prototype.bind, and it does it differently than your > user-defined one, it might confuse other programmers who looked at the > calls to the would-be non-standard bind. > > Some versions of bind that I've seen just a bind (fast), while others > use partialApply + bind (slower). > > Existing code stuck with a partialApply + bind assinged to > Function.prototype.bind could be tweaked for efficiency, refactored to > use some other approach that is efficient and uses a safer name, > allowing for the possibility of deprecating (not removing) the old > Function.prototype.bind. > > Garrett- Hide quoted text - Here is a script to put in a web page and run, using the new bind method of functions: Function.prototype.bind = function(){ var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift(); return function(){ return fn.apply(object, args.concat(Array.prototype.slice.call(arguments)) ); }; }; var myObject = {}; function myFunction(thename){ alert(thename); return this == myObject; } alert((myFunction.bind(myObject, "joe"))()); Since the returned function gets all its arguments from myFunction (the function using the new Function bind methed), the second argument is the returned function's first -- after the object is stripped of as its context. |
|
#7
| |||
| |||
| lorlarz wrote: > On Sep 6, 10:12 pm, dhtml <dhtmlkitc...@gmail.com> wrote: >> lorlarz wrote: >>> On Sep 6, 12:37 pm, dhtml <dhtmlkitc...@gmail.com> wrote: >>>> lorlarz wrote: >> Garrett- Hide quoted text - > I did not type that ^. Are you using Google Groups? > Here is a script to put in a web page and run, using the > new bind method of functions: > > Function.prototype.bind = function(){ > var fn = this, args = Array.prototype.slice.call(arguments), object = > args.shift(); > return function(){ > return fn.apply(object, > args.concat(Array.prototype.slice.call(arguments)) ); > > }; > > }; > > var myObject = {}; > function myFunction(thename){ > > alert(thename); > return this == myObject; > > } > > alert((myFunction.bind(myObject, "joe"))()); > > Since the returned function gets all its arguments from > myFunction (the function using the new Function bind methed), > the second argument is the returned function's first -- > after the object is stripped of as its context. > Correct. But why not pass in a parameter for the context? Function.prototype.bind = function(context) { }; I understood you were in agreement with what I wrote (not that you have to be), and that was what I wrote in my initial reply. The benefit would be that the code would be clearer because you wouldn't have to call args.shift(). It would also be a little faster. (It will be much easier to read your code if you indent your code with spaces.) Garrett |
|
#8
| |||
| |||
| On Sep 7, 9:54*pm, dhtml <dhtmlkitc...@gmail.com> wrote: > lorlarz wrote: > > On Sep 6, 10:12 pm, dhtml <dhtmlkitc...@gmail.com> wrote: > >> lorlarz wrote: > >>> On Sep 6, 12:37 pm, dhtml <dhtmlkitc...@gmail.com> wrote: > >>>> lorlarz wrote: > >> Garrett- Hide quoted text - > > I did not type that ^. Are you using Google Groups? > > > > > > > Here is a script to put in a web page and run, using the > > new bind method of functions: > > > Function.prototype.bind = function(){ > > var fn = this, args = Array.prototype.slice.call(arguments), object= > > args.shift(); > > return function(){ > > return fn.apply(object, > > args.concat(Array.prototype.slice.call(arguments)) ); > > > * * * * }; > > > }; > > > var myObject = {}; > > function myFunction(thename){ > > > alert(thename); > > return this == myObject; > > > } > > > alert((myFunction.bind(myObject, "joe"))()); > > > Since the returned function gets all its arguments from > > myFunction (the function using the new Function bind methed), > > the second argument is the returned function's first -- > > after the object is stripped of as its context. > > Correct. > > But why not pass in a parameter for the context? > > Function.prototype.bind = function(context) { > > }; > > I understood you were in agreement with what I wrote (not that you have > to be), and that was what I wrote in my initial reply. > > The benefit would be that the code would be clearer because you wouldn't > have to call args.shift(). It would also be a little faster. > > (It will be much easier to read your code if you indent your code with > spaces.) > > Garrett I do agree with you. I am just presenting a code example from an upcoming book from a javascript expert, which I have an early copy of. He did not explain the code, so I came to this newsgroup to get a full understanding of it as is. In my own work (if I need to) I will be sure to use your variations on the routine, which I agree are better. I am watching google more closely now, to correctly quote you (and others); sorry, I missed that one misquote (though it was of something empty, so your good reputation is hopefully fully intact). Still, I will police google, as you and others have requested and not make the error again. Thanks for you help. You have my respect. |
|
#9
| |||
| |||
| lorlarz wrote: > On Sep 7, 9:54 pm, dhtml <dhtmlkitc...@gmail.com> wrote: >> lorlarz wrote: >>> On Sep 6, 10:12 pm, dhtml <dhtmlkitc...@gmail.com> wrote: >>>> lorlarz wrote: >>>>> On Sep 6, 12:37 pm, dhtml <dhtmlkitc...@gmail.com> wrote: >>>>>> lorlarz wrote: >>>> Garrett- Hide quoted text - >> I did not type that ^. Are you using Google Groups? >> >> >> >> >> >>> Here is a script to put in a web page and run, using the >>> new bind method of functions: >>> Function.prototype.bind = function(){ >>> var fn = this, args = Array.prototype.slice.call(arguments), object = >>> args.shift(); >>> return function(){ >>> return fn.apply(object, >>> args.concat(Array.prototype.slice.call(arguments)) ); >>> }; >>> }; >>> var myObject = {}; >>> function myFunction(thename){ >>> alert(thename); >>> return this == myObject; >>> } >>> alert((myFunction.bind(myObject, "joe"))()); >>> Since the returned function gets all its arguments from >>> myFunction (the function using the new Function bind methed), >>> the second argument is the returned function's first -- >>> after the object is stripped of as its context. >> Correct. >> >> But why not pass in a parameter for the context? >> >> Function.prototype.bind = function(context) { >> >> }; >> >> I understood you were in agreement with what I wrote (not that you have >> to be), and that was what I wrote in my initial reply. >> >> The benefit would be that the code would be clearer because you wouldn't >> have to call args.shift(). It would also be a little faster. >> >> (It will be much easier to read your code if you indent your code with >> spaces.) >> >> Garrett > > I do agree with you. I am just presenting a code example > from an upcoming book from a javascript expert, which I > have an early copy of. He did not explain the code, so > I came to this newsgroup to get a full understanding of > it as is. In my own work (if I need to) I will be sure > to use your variations on the routine, which I agree are > better. > So you're editing a book that you need help understanding. The code is written in a complicated that way confuses you. You agree that the code should be changed to be less confusing. As a technical editor, it would seem to be a part of your role to make sure that a method had the correct parameters, was formatted properly, and had explanatory comment. > I am watching google more closely now, to correctly > quote you (and others); sorry, I missed that one > misquote (though it was of something empty, so > your good reputation is hopefully fully intact). > Still, I will police google, as you and others have > requested and not make the error again. > The issue with "-show quoted text-" (at least to me) makes it look like there is something else there and if there is, then what is it and are you replying to that? You could try a newsreader. Thunderbird works pretty well. There are free news servers that you can use. Garrett |
|
#10
| |||
| |||
| On Sep 8, 11:18*am, dhtml <dhtmlkitc...@gmail.com> wrote: > lorlarz wrote: > > On Sep 7, 9:54 pm, dhtml <dhtmlkitc...@gmail.com> wrote: > >> lorlarz wrote: > >>> On Sep 6, 10:12 pm, dhtml <dhtmlkitc...@gmail.com> wrote: > >>>> lorlarz wrote: > >>>>> On Sep 6, 12:37 pm, dhtml <dhtmlkitc...@gmail.com> wrote: > >>>>>> lorlarz wrote: > >>>> Garrett- Hide quoted text - > >> I did not type that ^. Are you using Google Groups? > > >>> Here is a script to put in a web page and run, using the > >>> new bind method of functions: > >>> Function.prototype.bind = function(){ > >>> var fn = this, args = Array.prototype.slice.call(arguments), object = > >>> args.shift(); > >>> return function(){ > >>> return fn.apply(object, > >>> args.concat(Array.prototype.slice.call(arguments)) ); > >>> * * * * }; > >>> }; > >>> var myObject = {}; > >>> function myFunction(thename){ > >>> alert(thename); > >>> return this == myObject; > >>> } > >>> alert((myFunction.bind(myObject, "joe"))()); > >>> Since the returned function gets all its arguments from > >>> myFunction (the function using the new Function bind methed), > >>> the second argument is the returned function's first -- > >>> after the object is stripped of as its context. > >> Correct. > > >> But why not pass in a parameter for the context? > > >> Function.prototype.bind = function(context) { > > >> }; > > >> I understood you were in agreement with what I wrote (not that you have > >> to be), and that was what I wrote in my initial reply. > > >> The benefit would be that the code would be clearer because you wouldn't > >> have to call args.shift(). It would also be a little faster. > > >> (It will be much easier to read your code if you indent your code with > >> spaces.) > > >> Garrett > > > I do agree with you. *I am just presenting a code example > > from an upcoming book from a javascript expert, which I > > have an early copy of. *He did not explain the code, so > > I came to this newsgroup to get a full understanding of > > it as is. *In my own work (if I need to) I will be sure > > to use your variations on the routine, which I agree are > > better. > > So you're editing a book that you need help understanding. > > The code is written in a complicated that way confuses you. You agree > that the code should be changed to be less confusing. As a technical > editor, it would seem to be a part of your role to make sure that a > method had the correct parameters, was formatted properly, and had > explanatory comment. > > > I am watching google more closely now, to correctly > > quote you (and others); sorry, I missed that one > > misquote (though it was of something empty, so > > your good reputation is hopefully fully intact). > > Still, I will police google, as you and others have > > requested and not make the error again. > > The issue with "-show quoted text-" (at least to me) makes it look like > there is something else there and if there is, then what is it and are > you replying to that? > > You could try a newsreader. Thunderbird works pretty well. There are > free news servers that you can use. > > Garrett Actually, Manning Publishers have a program where anyone can buy a book in the process of being written (and give feedback) and then also get the completed book as soon as it is done -- all for one pretty good price. I am a friend of the author, not an official editor. But, I did nonetheless make a suggestion that the author do some good explanation of the code (and perhaps he should also generate an example, like I did). As to taking the parameter: I am not willing to assume that the way that seems better to you and I is always better, as the new bind method of Function will actually be used -- so I have not passed on that critcism. For one thing, the function returned (just the original function expressly set to a context) must be open to taking other parameters, anyway -- I sent one parameter other than the object context in the example I provided. It can be returned and then immediately called in one fell swoop, if parameters are passed with each use (whether just the context parameter is the only one passed or if there are others). Thus, there is something to argue against your point. |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.