4

When declaring an object like this:

var name= {
    firsName:"nur",
    lastName:"jaman",
    fullName: function() {
        return this.firsName + " " + this.lastName;
    }
}
console.log(name.fullName());

it throws this error:

Uncaught TypeError: name.fullName is not a function

However, using any other variable name (e.g. var hello = ...) works just fine. Why?

deceze
  • 510,633
  • 85
  • 743
  • 889
jaman
  • 63
  • 6
  • why downvote? he is right – Luthando Ntsekwa Sep 03 '15 at 07:48
  • @Luthando Right about what? – deceze Sep 03 '15 at 07:50
  • 4
    there is a build in property called name for window object. all your global names point to window and it is a string. console.log(window.name) you ll see it s aempty string and you cannot override it – Deepak David Sep 03 '15 at 07:50
  • @jaman If you're executing the code in browser console, remove ` – Tushar Sep 03 '15 at 07:51
  • it gives this error `Uncaught TypeError: name.fullName is not a function` – Luthando Ntsekwa Sep 03 '15 at 07:52
  • 2
    @Deepak Now that the question makes sense, this would be a great answer. – deceze Sep 03 '15 at 07:55
  • oh now i see you decided to remove your downvotes....try the provided code before downvote – Luthando Ntsekwa Sep 03 '15 at 07:56
  • 2
    @Luthando 1) For a short period the code in the question actually *did* work just fine. 2) If you say it throws an error, **always cite the error message**. It could be a million different things. For that alone downvotes are justified. – deceze Sep 03 '15 at 07:57
  • 1
    @LuthandoLoot It was down-voted because: No error message was provided *"It doesn't work"* is not a good problem statement. The user had the variable `var hello = { ... }` (when I was viewing it), which works fine and has no problems. But since those problems were fixed, that's why we removed them. Not because we didn't read the question properly. – Spencer Wieczorek Sep 03 '15 at 07:57
  • 1
    @LuthandoLoot absolutely a valid question when you write a lot of vanilla javascript!! – Deepak David Sep 03 '15 at 07:58

2 Answers2

4

This is happening because name is a existing property on window, that behaves a little different from normal variables.

You can't replace this property, you can only assign string values to it. When assigning other types to the name property, it gets cast to string:

name = false;
var name = false;
window.name = false;

These lines will all result in window having a property name that contains "false".

In a similar fashion, objects and functions saved to the name variable will be cast to string:

var name = function(){};  // "function (){}"
var name = { a: [1, 2] }; // "[object Object]"

If you want to use a variable named "name", you'll have to enclose it in a scope:

// In the global namespace, this will alert `"[object Object]"`
var name = { a: 1};
alert('Global `name`: \n' +
      JSON.stringify(name));

// In it's own namespace, this will alert `{"a":1}`.
(function(){
  var name = { a: 1};
  alert('Namespaced `name`: \n' +
        JSON.stringify(name));
})()
Cerbrus
  • 70,800
  • 18
  • 132
  • 147
1

Without any enclosing scope, var name is window.name, which is a native property which cannot be replaced or overridden. You can assign a string to it, but even then it keeps being an object with special properties:

> name
< "[object Object]"
> name.anchor
< function anchor() {
    [native code]
}
> name = null
> name
< "null"
> typeof name
< "string"
> name.anchor
< function anchor() {
    [native code]
}

Note that the whole thing works just fine when scoped:

function () {
    var name = { .. };
    console.log(name.fullName()); 
}()
deceze
  • 510,633
  • 85
  • 743
  • 889