hello {{name}}! (here is the $scope of controller)
If a new application is bootstrapped, the $rootScope instance gets created.
For each controller, a child $scope will be created.
So, the child $scope can see the variables of parent scope, so long it is not locally overriden.
<body ng-app ng-init="name='World'"> we create here $rootScope with the model:
name='World' <h1>Hello, {name} (here is the $rootScope)</h1>
<div ng-controller='HelloController'> we create here child scope.
<input ng-model='name'>
hello {name}!
Because the child controller is empty (var HelloController = function ($scope) { };), it has no
model and sees the "name" of parent scope.
If You type a value in the "Say hello..", You create a model "name=xxx" in the controller scope.
And the controller can't see the $rootScope.name any more. So You see than the value $rootScope=="World" over input,
and Your tipped value under input field.
Overcome the Problem with different values
The solution involves binding to a property of an object and not directly to a scope's property:
<div ng-controller="HelloController2" ng-init="thing = {name : 'World'}">
<h1>Hello, {thing.name}</h1>
<div ng-controller="HelloController3">
Say hello to: <input type="text" ng-model="thing.name">
<h2>Hello, {thing.name}!</h2>