0

I'm using a specific framework and somewhere in my code I have a function as a parameter.

I want to check if that function is a specific anonymous function out of that framework. I don't have access to the original function itself to have a proper reference.

I'm creating some debugging tools for myself (non-production) and I'd like to check if the value of func.toString() is:

function(){return undefined }

... to check if it's this specific function and handle some special case.

Question

Is toString() JavaScript output sort of "guaranteed" to be the same in every browser/implementation? Or could it be that other browsers i.e. format it different, remove unnecessary spaces or maybe don't return the output at all?

Note

I know these are in any normal circumstances terrible practices, but this will be in debug tools that only I or the people in my team will use. In theory we also control the Browser we use but I am more interested from a theoretical point of view.

The code

Not necessary for the question, but to give more context.

The code is a knockout.js debug bindingHandler where I can easily see what context an element is.

ko.bindingHandlers.debug = 
{
    init: function(element:HTMLElement, valueAccessor:Action, allBindingsAccessor, viewModel, bindingContext:KnockoutBindingContext) 
    {
        let value = valueAccessor();

        // only "real way" to check for undefined, if the propery itself would be undefined
        // the normal use of valueAcessor() would also return undefined, so we can't differentiate between
        // an unexisting property or deliberately leaving out the property
        if ( valueAccessor.toString() == 'function(){return undefined }' )
            value = bindingContext.$data;

        console.log( '----- Knockoutbinding -----' );
        console.log( element );
        console.log( value );
        console.log( '---------------------------' );
    }
};

Useage:

<div data-bind="debug: window.innerHeight">          <!-- 450 -->
<div data-bind="debug: window.nonExistingProperty">  <!-- undefined -->
<div data-bind="debug: $data"></div>                 <!-- current context -->
<div data-bind="debug"></div>                        <!-- current context (new) -->

Update

I just did some simple tests and Chrome, Firefox and Edge at least seem to honor the exact same source code like @jabaa mentions.

2
  • If you want to do this for debugging, better inject some code into the framework that enables you to identify this function (by something else than its code representation)
    – Bergi
    Commented Dec 28, 2023 at 18:20
  • This is more a "nice to have" then something critical. I prefer if something breaks/differentiates from the original it's this script, not the original framework 😅 I added an example to clear it up
    – Dirk Boer
    Commented Dec 28, 2023 at 18:39

2 Answers 2

2

Since ES2018, the spec requires the return value of toString() to be the exact same source code as it was declared, including any whitespace and/or comments — or, if the host doesn't have the source code available for some reason, requires returning a native function string. Support for this revised behavior can be found in the compatibility table.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/toString

If I correctly understand, all browsers and runtime environments have to return the same string since 2018.

*Is toString() JavaScript output "guaranteed" to be the same in every browser/implementation?"

Yes, since 2018.

2
  • wow, that a suprise plot twist, I already accepted the other answer. How can it be that it not mentioned here: tc39.es/ecma262/#sec-function.prototype.tostring
    – Dirk Boer
    Commented Dec 28, 2023 at 18:32
  • 2
    @DirkBoer but it is mentioned, right in step 2: "If HostHasSourceTextAvailable(func) is true, then return CodePointsToString(func.[[SourceText]])"
    – Bergi
    Commented Dec 28, 2023 at 18:38
2

The Function.prototype.toString function is part of the specification, but it's not strict enough to guarantee that full string comparison (like you do) will work.

The only thing that is enforced by the specification is that the output is a valid string representation of a NativeFunction so two implementations could comply with this specification while outputting different strings (e.g: different indentation, carriage returns, etc.)

Not the answer you're looking for? Browse other questions tagged or ask your own question.