Angularjs Scope 原型鏈

咱們知道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繼承(原型鏈),因此呢不要感受它很神奇很神祕,你要去了解它才能把它發揮出來 ^^ 

相關文章
相關標籤/搜索