Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #28839 > unrolled thread
| Started by | Andrew Poulos <ap_prog@hotmail.com> |
|---|---|
| First post | 2015-10-19 12:12 +1100 |
| Last post | 2015-10-19 13:29 -0700 |
| Articles | 11 — 4 participants |
Back to article view | Back to comp.lang.javascript
Overwriting existing fucntion Andrew Poulos <ap_prog@hotmail.com> - 2015-10-19 12:12 +1100
Re: Overwriting existing fucntion Andrew Poulos <ap_prog@hotmail.com> - 2015-10-19 13:57 +1100
Re: Overwriting existing fucntion Stefan Weiss <krewecherl@gmail.com> - 2015-10-19 05:04 +0200
Re: Overwriting existing fucntion Stefan Weiss <krewecherl@gmail.com> - 2015-10-19 13:14 +0200
Re: Overwriting existing fucntion Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-10-19 19:49 +0200
Re: Overwriting existing fucntion Andrew Poulos <ap_prog@hotmail.com> - 2015-10-20 10:18 +1100
Re: Overwriting existing fucntion Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-10-20 02:17 +0200
Re: Overwriting existing fucntion Stefan Weiss <krewecherl@gmail.com> - 2015-10-21 19:47 +0200
Re: Overwriting existing fucntion Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-10-21 21:40 +0200
Re: Overwriting existing fucntion Stefan Weiss <krewecherl@gmail.com> - 2015-10-22 03:04 +0200
Re: Overwriting existing fucntion Danny <dann90038@gmail.com> - 2015-10-19 13:29 -0700
| From | Andrew Poulos <ap_prog@hotmail.com> |
|---|---|
| Date | 2015-10-19 12:12 +1100 |
| Subject | Overwriting existing fucntion |
| Message-ID | <CbCdnUFUDeXC3rnLnZ2dnUU7-amdnZ2d@westnet.com.au> |
I'm using a 3rd party elearning product that produces web pages. The
product allows me to add "custom" code to a page.
I need to "overwrite" one of the functions that the product produces
with one of my own. Custom code seems to always get added before their
code eg.
<script>
function action70 {
// my customised function
}
...
function action70 {
// their function
}
...
</script>
This means that mine gets "overwritten" so I tried using
function ap() {
function action70(){
// my customised function
}
}
if (window.addEventListener) {
window.addEventListener("load", ap);
}
to get my function to "overwrite" the existing one but only their one
ever gets triggered. How can I add my function before theirs and still
have my one trigger?
Andrew Poulos
[toc] | [next] | [standalone]
| From | Andrew Poulos <ap_prog@hotmail.com> |
|---|---|
| Date | 2015-10-19 13:57 +1100 |
| Message-ID | <COudnQhlS8ycwbnLnZ2dnUU7-KWdnZ2d@westnet.com.au> |
| In reply to | #28839 |
On 19/10/2015 12:12 PM, Andrew Poulos wrote:
> I'm using a 3rd party elearning product that produces web pages. The
> product allows me to add "custom" code to a page.
>
> I need to "overwrite" one of the functions that the product produces
> with one of my own. Custom code seems to always get added before their
> code eg.
>
> <script>
> function action70 {
> // my customised function
> }
>
> ...
> function action70 {
> // their function
> }
> ...
> </script>
>
> This means that mine gets "overwritten" so I tried using
>
> function ap() {
> function action70(){
> // my customised function
> }
> }
> if (window.addEventListener) {
> window.addEventListener("load", ap);
> }
>
> to get my function to "overwrite" the existing one but only their one
> ever gets triggered. How can I add my function before theirs and still
> have my one trigger?
I just tried this
var action70;
function ap() {
action70 = function(){
// my customised function
}
}
if (window.addEventListener) {
window.addEventListener("load", ap);
}
and now my function triggering but I'm unsure why its working. Why does
the first way not work and the second work?
Andrew Poulos
[toc] | [prev] | [next] | [standalone]
| From | Stefan Weiss <krewecherl@gmail.com> |
|---|---|
| Date | 2015-10-19 05:04 +0200 |
| Message-ID | <n01mji$k3l$1@news.albasani.net> |
| In reply to | #28839 |
On 2015-10-19 03:12, Andrew Poulos wrote:
> I need to "overwrite" one of the functions that the product produces
> with one of my own. Custom code seems to always get added before their
> code eg.
...
> function ap() {
> function action70(){
> // my customised function
> }
> }
> if (window.addEventListener) {
> window.addEventListener("load", ap);
> }
This doesn't work because action70() in this example is not visible
outside of ap(); it cannot overwrite a global function. Depending on
what exactly the fixed application code does, and which user agents have
to be supported, you could try using `Object.defineProperty()`:
////// your code /////////////
function my_action70 () {
console.log("custom function");
}
Object.defineProperty(window, "action70", { value: my_action70 });
////// fixed app code /////////
function action70 () {
console.log("original function");
}
////// test ///////////////////
action70(); // "custom function"
- stefan
PS, just saw your reply - the reason why your second version works is
because it creates a property on the global object - i.e., action70() is
now visible outside of ap().
[toc] | [prev] | [next] | [standalone]
| From | Stefan Weiss <krewecherl@gmail.com> |
|---|---|
| Date | 2015-10-19 13:14 +0200 |
| Message-ID | <n02jb7$qrl$1@news.albasani.net> |
| In reply to | #28841 |
On 2015-10-19 05:04, Stefan Weiss wrote:
> Object.defineProperty(window, "action70", { value: my_action70 });
Actually, scratch that. If a simple `action70 = ...` works in the
context you describe, then that's all you need. It would be cleaner to
explicitly set `window.action70` in your code, or to declare a global
`action70` variable (if you can), so that the purpose of the assignment
is immediately obvious to the reader.
`Object.defineProperty()` only has an advantage if the application code
also tries to set `window.action70` or assigns to `action70` without
declaring it, which sounds unlikely from what you wrote.
- stefan
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2015-10-19 19:49 +0200 |
| Message-ID | <2283142.7jlluFck8S@PointedEars.de> |
| In reply to | #28839 |
Andrew Poulos wrote:
> I'm using a 3rd party elearning product that produces web pages. The
> product allows me to add "custom" code to a page.
>
> I need to "overwrite" one of the functions that the product produces
> with one of my own. Custom code seems to always get added before their
> code eg.
>
> […]
> function ap() {
> function action70(){
> // my customised function
> }
> }
> if (window.addEventListener) {
> window.addEventListener("load", ap);
> }
>
> to get my function to "overwrite" the existing one but only their one
> ever gets triggered.
This works insofar that it is proper executable code, but the event handler
calls the event listener referred by “ap”, which declares a local function
and then exits, so that the Function instance just created by the
declaration is immediately available for garbage collection – functionally a
no-op, it may even be optimized to function ap () {} or, further, the
addEventListener() call may be optimized out.
> How can I add my function before theirs and still have my one trigger?
You cannot. But (towards which you should have asked, see “X–Y problem”)
you can overwrite their function afterwards by assigning a value to the same
identifier, provided that they have not made the corresponding property
read-only:
document.addEventListener("load", function () { action70 = … }, false);
If the property is read-only but still configurable, you can make it
writable again before that:
Object.defineProperty(global, "action70", {
writable: true,
enumerable: true, // or false
configurable: true // or false
});
Properties resulting from variable declarations should not be configurable
in the first place, so in that case you do not have to worry about read-
onlyness.
Different to what Stefan suggested, you should not be using “window” to
refer to the global object, but if you need to make it explicit, “this” in
the global execution context. For example
/* global context */
var global = this;
/* any context */
document.addEventListener("load",
function () { global.action70 = … }, false);
(A reference to the global object can also be obtained in other ways.)
Also, the host object referred to by “window” might not implement an
“addEventListener()” method; “document” is safer, “document.body” is
probably safest, given the history of the “load” event, but might not yet be
available at this time (before the “body” element has been parsed).
Consider using the “defer” attribute. On the other hand, you appear to be
using HTML5, so this difference might not of importance to you. However, as
in theory the document can be loaded before loading of the window content
has been completed, using “document” or “document.body” instead might speed
things up a little.
Note that this approach depends on the definition in W3C UI Events
(formerly, W3C DOM Level 3 Events) that event listeners are added and
executed in source code order. If this needs to work where
addEventListener() is not available (IE < 9 or IE 9 in Compatibility Mode),
using window.attachEvent() instead of .addEventListener() does not suffice
as, among other peculiarities, .attachEvent() does not observe addition
order.
--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Andrew Poulos <ap_prog@hotmail.com> |
|---|---|
| Date | 2015-10-20 10:18 +1100 |
| Message-ID | <R8ydnSViU8ql57jLnZ2dnUU7-K-dnZ2d@westnet.com.au> |
| In reply to | #28843 |
On 20/10/2015 4:49 AM, Thomas 'PointedEars' Lahn wrote:
> Andrew Poulos wrote:
>
>> I'm using a 3rd party elearning product that produces web pages. The
>> product allows me to add "custom" code to a page.
>>
>> I need to "overwrite" one of the functions that the product produces
>> with one of my own. Custom code seems to always get added before their
>> code eg.
>>
>> […]
>> function ap() {
>> function action70(){
>> // my customised function
>> }
>> }
>> if (window.addEventListener) {
>> window.addEventListener("load", ap);
>> }
>>
>> to get my function to "overwrite" the existing one but only their one
>> ever gets triggered.
>
> This works insofar that it is proper executable code, but the event handler
> calls the event listener referred by “ap”, which declares a local function
> and then exits, so that the Function instance just created by the
> declaration is immediately available for garbage collection – functionally a
> no-op, it may even be optimized to function ap () {} or, further, the
> addEventListener() call may be optimized out.
This is the bit that caught me out. "function action70(){" is a local
function even though a function with the same identifier exists in the
global space.
>> How can I add my function before theirs and still have my one trigger?
>
> You cannot. But (towards which you should have asked, see “X–Y problem”)
> you can overwrite their function afterwards by assigning a value to the same
> identifier, provided that they have not made the corresponding property
> read-only:
>
> document.addEventListener("load", function () { action70 = … }, false);
>
> If the property is read-only but still configurable, you can make it
> writable again before that:
>
> Object.defineProperty(global, "action70", {
> writable: true,
> enumerable: true, // or false
> configurable: true // or false
> });
>
> Properties resulting from variable declarations should not be configurable
> in the first place, so in that case you do not have to worry about read-
> onlyness.
>
> Different to what Stefan suggested, you should not be using “window” to
> refer to the global object, but if you need to make it explicit, “this” in
> the global execution context. For example
>
> /* global context */
> var global = this;
>
> /* any context */
> document.addEventListener("load",
> function () { global.action70 = … }, false);
>
> (A reference to the global object can also be obtained in other ways.)
>
> Also, the host object referred to by “window” might not implement an
> “addEventListener()” method; “document” is safer, “document.body” is
> probably safest, given the history of the “load” event, but might not yet be
> available at this time (before the “body” element has been parsed).
> Consider using the “defer” attribute. On the other hand, you appear to be
> using HTML5, so this difference might not of importance to you. However, as
> in theory the document can be loaded before loading of the window content
> has been completed, using “document” or “document.body” instead might speed
> things up a little.
>
> Note that this approach depends on the definition in W3C UI Events
> (formerly, W3C DOM Level 3 Events) that event listeners are added and
> executed in source code order. If this needs to work where
> addEventListener() is not available (IE < 9 or IE 9 in Compatibility Mode),
> using window.attachEvent() instead of .addEventListener() does not suffice
> as, among other peculiarities, .attachEvent() does not observe addition
> order.
Thank you for such a comprehensive answer. If you ever published a book
on scripting web pages I, for one, would buy a copy.
Andrew Poulos
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2015-10-20 02:17 +0200 |
| Message-ID | <1867226.5Pa8prDpYa@PointedEars.de> |
| In reply to | #28845 |
Andrew Poulos wrote:
> On 20/10/2015 4:49 AM, Thomas 'PointedEars' Lahn wrote:
>> Andrew Poulos wrote:
>>> […]
>>> function ap() {
>>> function action70(){
>>> // my customised function
>>> }
>>> }
>>> if (window.addEventListener) {
>>> window.addEventListener("load", ap);
>>> }
>>>
>>> to get my function to "overwrite" the existing one but only their one
>>> ever gets triggered.
>>
>> This works insofar that it is proper executable code, but the event
>> handler calls the event listener referred by “ap”, which declares a local
>> function and then exits, so that the Function instance just created by
>> the declaration is immediately available for garbage collection –
>> functionally a no-op, it may even be optimized to function ap () {} or,
>> further, the addEventListener() call may be optimized out.
>
> This is the bit that caught me out. "function action70(){" is a local
> function even though a function with the same identifier exists in the
^^^^^^
> global space.
^^^^^^^^^^^^
Yes; in general: in the outer execution contexts.
It is easier to see if you think of a function declaration as a variable
declaration with initialization in disguise:
function ap ()
{
function action70 ()
{
// my customised function
}
}
is equivalent to
var ap = function () {
var action70 = function () {
// my customised function
};
};
except that the original code is executed before all statements in the same
execution context that are not declarations (misleadingly called “hoisting”
elsewhere), and in source code order with other declarations in the same
context.
You would not expect that “action70” or its value is available outside ap
unless ap() returned the value, and the same is true for function
declarations.
> Thank you for such a comprehensive answer. If you ever published a book
> on scripting web pages I, for one, would buy a copy.
You are welcome. Duly noted.
--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Stefan Weiss <krewecherl@gmail.com> |
|---|---|
| Date | 2015-10-21 19:47 +0200 |
| Message-ID | <n08j45$cfc$1@news.albasani.net> |
| In reply to | #28843 |
On 2015-10-19 19:49, Thomas 'PointedEars' Lahn wrote: > Different to what Stefan suggested, you should not be using “window” to > refer to the global object, but if you need to make it explicit, “this” in > the global execution context. For example > > /* global context */ > var global = this; This will not give you the global object, but rather the window object again (actually, the window's WindowProxy object) in HTML5: | A global object | | An object that provides the APIs that can be called by the code in | scripts that use this settings object. | | Note: This is typically a Window object or a WorkerGlobalScope | object. When a global object is an empty object, it can't do anything | that interacts with the environment. | | If the global object is a Window object, then, in JavaScript, the | ThisBinding of the global execution context for this script must | be the Window object's WindowProxy object, rather than the global | object. [ECMA262] | | Note: This is a willful violation of the JavaScript specification | current at the time of writing (ECMAScript edition 5, as defined | in section 10.4.1.1 Initial Global Execution Context, step 3). The | JavaScript specification requires that the this keyword in the | global scope return the global object, but this is not compatible | with the security design prevalent in implementations as specified | herein. [ECMA262] http://www.w3.org/TR/html5/webappapis.html#global-object Even before HTML5, I've never heard of a browser in which `window` in the global context would be anything other than a host object giving access to the global object's properties - barring non-document contexts, shadowing, obsolete browsers, and bugs. Unless you're doing something very unusual, the warning to not rely on `window` is unnecessary. - stefan
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2015-10-21 21:40 +0200 |
| Message-ID | <37067801.r229cbFWdt@PointedEars.de> |
| In reply to | #28851 |
Stefan Weiss wrote: > On 2015-10-19 19:49, Thomas 'PointedEars' Lahn wrote: >> Different to what Stefan suggested, you should not be using “window” to >> refer to the global object, but if you need to make it explicit, “this” >> in the global execution context. For example >> >> /* global context */ >> var global = this; > > This will not give you the global object, but rather the window object > again (actually, the window's WindowProxy object) in HTML5: Nonsense. -- PointedEars FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/> Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix> Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Stefan Weiss <krewecherl@gmail.com> |
|---|---|
| Date | 2015-10-22 03:04 +0200 |
| Message-ID | <n09cnk$7cu$1@news.albasani.net> |
| In reply to | #28852 |
On 2015-10-21 21:40, Thomas 'PointedEars' Lahn wrote: > Stefan Weiss wrote: >>> /* global context */ >>> var global = this; >> >> This will not give you the global object, but rather the window object >> again (actually, the window's WindowProxy object) in HTML5: > > Nonsense. It's getting hard to take you seriously anymore. I quoted and linked the relevant passage from the spec, for crying out lout. You can also easily confirm it for yourself. "Nonsense" must be your way of saying "I stand corrected". - stefan
[toc] | [prev] | [next] | [standalone]
| From | Danny <dann90038@gmail.com> |
|---|---|
| Date | 2015-10-19 13:29 -0700 |
| Message-ID | <85939d69-3e02-40f8-bcf4-260716cbe18a@googlegroups.com> |
| In reply to | #28839 |
to Andrew Poulos
putting the function as a child function of another,
will simply make it a private function, in this case
of function/class "ap".
you could use a variable to use that "class" and
then call the function, assuming is set as
this.myaction70 = function(){....}
however, if you just need a namespace for it, simply
make an object, and have myaction70() as property/member
of that object
var ap = {
myaction70 : funtion(){ // something }
}
------------------------------------------------
window.addEventListener("load",ap.myaction70,false);
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web