javascript - TypeError: console.log(...) är inte en funktion


Jag är verkligen förvirrad över hur jag kan få console.log är inte en funktion på rad 1091. Om jag tar bort closure nedan, klagar inte rad 1091 över ett sådant fel. Chrome Version 43.0.2357.130 (64-bitars).

Här är koden:

$scope.columnNameChanged = function (tableColumn) {
    setDirtyColumn(tableColumn);
    //propagate changes to the key fields
    for (var i = 0; i < $scope.tableIndexes.length; ++i) {
        for (var j = 0; j < $scope.tableIndexes[i].columnName.length; ++j) {
            if ($scope.tableIndexes[i].columnName[j] === tableColumn.previousName) {
                console.log('xxx', $scope.tableIndexes[i].columnName[j])
                (function (i, j) {
                    $timeout(function () {
                        console.log($scope.tableIndexes[i].columnName[j])
                        $scope.tableIndexes[i].columnName[j] = tableColumn.name.toUpperCase();
                        console.log($scope.tableIndexes[i].columnName[j])
                    });
                })(i, j);
            }
        }
    }
};

Svar #1

Lösning

Sätt helt enkelt ett semikolon (;) efter console.log(…).


Förklaring

Felet är enkelt att reproducera på detta sätt:

console.log()
(function(){})

Det försöker skicka function(){} som ett argument till returvärdet av console.log() som i sig inte är en funktion utan faktiskt undefined (kolla typeof console.log();). Detta beror på att JavaScript tolkar detta som console.log()(function(){}). console.log är dock en funktion.

Om du inte hade console-objektet skulle du se

ReferenceError: console är inte definierad

Om du hade console-objektet men inte log-metoden skulle du se

TypeError: console.log är inte en funktion

Vad du har, däremot, är

TypeError: console.log(...) är inte en funktion

Notera (...) efter funktionsnamnet. Med dem hänvisar det till funktions returvärde.

Radbrytningen separerar inte dessa två uttryck som separata satser på grund av JavaScripts regler för automatisk semikoloninfogning (ASI).


Respektera ;

Alla dessa kodexempel resulterar i alla möjliga oväntade fel om inga semikolon finns:

console.log() // As covered before
() // TypeError: console.log(...) is not a function
console.log() // Accessing property 0 of property 1 of the return value…
[1][0] // TypeError: console.log(...) is undefined
console.log() // Like undefined-3
-3 // NaN
let a, b;
const array = Array.from({ length: 2 })

// Now, let’s use destructuring:
[a, b] = array; // ReferenceError: can't access lexical declaration 'array' before initialization
let a, b;
const array = Array.from({ length: 2 }).fill(1),
  array2 = Array.from({ length: 2 })

// Now, let’s use destructuring. Attempt to get the two 1’s from `array` as `a` and `b`:
[a, b] = array;
console.log(a, b); // undefined undefined

Ett annat exempel

Du ser (...) ofta vid användning av kedjade metoder eller kedjade egenskapsåtkomst:

string.match(/someRegEx/)[0]

Om det RegEx inte hittas, kommer metoden att returnera null och egenskapsåtkomsten på null kommer att orsaka ett TypeError: string.match(...) is null — returvärdet är null. I fallet med console.log(...) var returvärdet undefined.

Svar #2

Felet betyder att returvärdet av console.log() inte är en funktion. Du saknar ett semikolon:

console.log('xxx', $scope.tableIndexes[i].columnName[j]);
//                                                      ^

vilket gör att följande (...) av IIFE:n tolkas som ett funktionsanrop.

Jämför felmeddelandena för

> var foo = {bar: undefined};
> foo.bar();
Uncaught TypeError: foo.bar is not a function

och

> var foo = {bar: function(){}};
> foo.bar()();
Uncaught TypeError: foo.bar(...) is not a function

Relaterade artiklar