首页 > 解决方案 > AngularJS 中的原型继承如何工作?

问题描述

这个例子来自ng-book: The complete book on AngularJS。我不明白以下示例的结果。

<div ng-controller="SomeController">
    {{ someBareValue }}
    <button ng-click="someAction()">Communicate to child</button>
    <div ng-controller="ChildController">
        {{ someBareValue }}
        <button ng-click="childAction()">Communicate to parent</button>
    </div>
</div>

angular.module('myApp', [])
    .controller('SomeController', function($scope) {
        // anti-pattern, bare value
        $scope.someBareValue = 'hello computer';
        // set actions on $scope itself, this is okay
        $scope.someAction = function() {
            // sets {{ someBareValue }} inside SomeController and ChildController
            $scope.someBareValue = 'hello human, from parent';
        };
    })
    .controller('ChildController', function($scope) {
        $scope.childAction = function() {
        // sets {{ someBareValue }} inside ChildController
        $scope.someBareValue = 'hello human, from child';
    };
});

示例在这里: http: //output.jsbin.com/UbIRIHa/1/

书中说

由于原型继承与 JavaScript 中的值对象一起工作的方式,通过父项中的操作更改 someBareValue 确实会更改子项,但反之则不然。要查看此问题的实际效果,请尝试先单击子按钮,然后单击父按钮。这样做可以清楚地表明子控制器具有副本,而不是对 someBareValue 的引用。

我不明白的是:如果像书中建议的那样,先点击“与父母沟通”,然后点击“与孩子沟通”,那么“与孩子沟通”无法更改孩子中的文字。

但是,如果先单击父按钮,则可能会更改子文本。

我不明白为什么点击顺序对父按钮的结果很重要,原型继承在这个例子中扮演什么角色?

标签: javascriptangularjsangularjs-scope

解决方案


您可以将原型视为继承该原型的子作用域的一组“默认值”。对原型的任何更改都将反映在 childScopes 中,但是一旦您将特定值分配给 childScope 上的这些属性之一,childScope 此后将保留该属性。

观察:

var parentScope = { message: 'hello' };

var childScope1 = Object.create(parentScope);
var childScope2 = Object.create(parentScope);

console.log(childScope1.message);  // hello
console.log(childScope2.message);  // hello

parentScope.message = "goodbye";

console.log(childScope1.message);  // goodbye
console.log(childScope2.message);  // goodbye

childScope1.message = "I'm different!";

console.log(childScope1.message);  // I'm different!
console.log(childScope2.message);  // goodbye

parentScope.message = "hello again";

console.log(childScope1.message);  // I'm different!
console.log(childScope2.message);  // hello again


推荐阅读