咱們知道scope是能夠繼承的.scope的繼承和js原型鏈是同一個概念。angularjs
<div ng-controller="parentCtrl"> {{name}} <div ng-controller="childCtrl"> {{name}} </div> </div>
在angular中,ng-controller指令會幫咱們建立一個scope並繼承它的父親scope . app
parentCtrl scope繼承自 $rootScope , childCtrl scope 繼承自parent scope.spa
app.controller("parentCtrl", function ($scope,$rootScope) { $scope.name = "keatkeat"; }); app.controller("childCtrl", function ($scope) { });
因此即便咱們在childCtrl沒有給 name 賦值,模板依然能夠從parentCtrl 讀取到"keatkeat".code
繼承對於子層讀取父親屬性值很是良好和簡單。可是在寫就不那麼方便了!對象
好比 blog
app.controller("childCtrl", function ($scope) { $scope.name = "xinyao"; });
當咱們在子層填"xinyao"時,你會發現這個值確實在子層的模板出現了,而父親模板依舊是原來的"keatkeat"繼承
孩子能夠覆蓋父親,這也許是咱們想要的。原型鏈
但也有這種狀況 get
app.controller("parentCtrl", function ($scope,$rootScope) { $scope.name = { first: "keat", last: "keat" } }); app.controller("childCtrl", function ($scope) { $scope.name.first = "xin"; $scope.name.last = "yao"; });
當父親的值是個對象時,就要特別當心了。$scope.name.first = "xin"; 會修改掉父親的值!原型
因此對於原型鏈來講,孩子是有"機會"修改掉父親的值的。
若是你不熟悉js 可能會不太能理解,其實原理是很簡單的
你能夠把 $scope.name.first = "xin"; 當作這樣
var obj = $scope.name; //讀取name屬性,在子層沒有,因此會去父層找,而且找到了一個對象
obj.first = "xin"; //你寫入的天然是父層的對象咯,因此也就覆蓋了父親啦 .
這其實也挺好的!善加利用的話,孩子能夠修改父親的值也很方便。
那麼是否是隻有對象纔可能這樣呢。
若是隻是 $scope.name = "keatkeat"; 就不可能被子層修改了嗎?
大部分狀況是!可是也有例外!
好比
app.controller("parentCtrl", function ($scope, $rootScope) { var _name = "keatkeat"; Object.defineProperty($scope, "name", { get: function () { return _name }, set: function (newValue) { _name = newValue } }); }); app.controller("childCtrl", function ($scope) { $scope.name = "xinyao"; });
父親的name是加了setter的屬性, object.defineProperty是ECMA5 的新功能。
一但這樣,孩子就沒法在添加本身的name屬性了,它會直接調用父親的name作讀寫!
善加利用的話仍是不錯的!
總結 : angularjs的scope是單純的js對象,繼承也是單純的js繼承(原型鏈),因此呢不要感受它很神奇很神祕,你要去了解它才能把它發揮出來 ^^