javascriptknockout.js

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


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.


Solution

  • 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.