Elgs Qian Chen Elgs Qian Chen - 3 months ago 31
Javascript Question

TypeError: console.log(...) is not a function

I'm really confused how I can get console.log is not a function on line 1091. If I remove the closure below, line 1091 doesn't complain such error. Chrome Version 43.0.2357.130 (64-bit).

enter image description here

Here is the code:

$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);
}
}
}
};

Answer

Solution

Simply put a semicolon (;) after console.log().


Explanation

The error is easily reproducible like this:

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

It’s trying to pass function(){} as an argument to the return value of console.log() which itself is not a function but actually undefined1. This is because JavaScript interprets this as console.log()(function(){}). console.log however is a function.

If you didn’t have the console object you’d see

ReferenceError: console is not defined

If you had the console object but not the log method you’d see either

TypeError: console.log is not a function

or, for some weird reason,

undefined

What you have, however, is

TypeError: console.log(...) is not a function

Note the (...) after the function name. With those it’s referring to the return value of the function.


1: The return value can be checked with

typeof console.log(); // undefined

… although to be honest, I think typeof kinda lies here, because

typeof console.anyFunctionYouCanImagineAtThisPointWillAlsoReturn(); // undefined

Console methods are weird.


Respect the ;

All these code snippets result in all sorts of unexpected errors if no semicolons are present:

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

Another Example

You see the (...) oftentimes with the use of chained methods or chained property accessors:

string.match(/someRegEx/)[0]

If that RegEx isn’t found, the method will return null and the property accessor on null will cause a TypeError: string.match(...) is null — the return value is null. In the case of console.log(...) the return value was undefined.