【问题标题】:AngularJS $scope prototypal inheritance - primitive vs. objects?AngularJS $scope 原型继承 - 原始与对象?
【发布时间】:2023-08-02 07:00:01
【问题描述】:

我已经广泛阅读了有关 Javascript 原型继承的内容,特别是在子作用域中。我的理解是,我们始终确保一个“。”在我们的 ng-model 绑定中,因此它引用了一个对象。

我的问题是......为什么原型继承在其本地范围内创建一个原语而不是一个对象?看起来完全一样。

在一种情况下,我们有一个原语。在另一种情况下,我们有一个对象 - 比如说一个数组。更令人困惑的是,我可以将一个对象传递给子范围(没有“.”),并且通过将数据推送到在本地范围内传递的对象上,父对象仍然被修改,因此没有子数组对象被建造。再说一遍,为什么?原型继承似乎会自动创建原语……是什么让对象与众不同?

【问题讨论】:

  • 原型继承不会创建任何东西。 Angular 将属性添加到当前范围。属性是基元还是对象也没关系。
  • 这很重要。对象位于父范围内并进行适当修改,而基元则不是。我试图理解为什么会这样。
  • 如果没有一些可能导致您混淆的示例,这个问题就太宽泛了。我不同意@zeroflagL,尽管关于doesn't matter,因为一旦作用域变成子作用域,什么保持绑定,什么不绑定,这确实很重要
  • var $scope.name = "丹尼尔";
  • Charles 和@charlietfl,也许我不够明确或误解了这个问题。问题是:为什么原型继承在其本地范围内创建原语而不是对象。因此,如果您有ng-model="something.text",那么text 将被添加到scope.something。但如果对象something 尚不存在于作用域链中的某个位置,则它将被创建并添加到当前作用域中。如果你的意思不同,Charles,请改写问题。

标签: javascript angularjs scope


【解决方案1】:

下面是如何从父作用域创建子作用域的简化(例如)版本。如需更全面的视图 - 请转至source

父范围已创建:

function Scope(){ }; 
var scope = new Scope(); // scope instance is created

假设它有一些原始属性和一些对象属性:

scope.a = 1;
scope.obj = {a: 1};

子范围实例被创建,它的原型是“范围”

function ChildScope(){ };
ChildScope.prototype = scope;
var childScope = new ChildScope(); // an instance of the child scope

现在,让我们看看:

console.log(scope.a);          // should be 1
console.log(childScope.a);     // should be 1
console.log(scope.obj.a);      // should be 1
console.log(childScope.obj.a); // should be 1

正如预期的那样,对吧?

如果我们现在对 childScope 中公开的属性设置值

childScope.a = 2;
childScope.obj.a = 3;

然后是输出:

console.log(scope.a);          // should still be 1
console.log(childScope.a);     // should be 2 now
console.log(scope.obj.a);      // should be 3
console.log(childScope.obj.a); // should be 3

jsFiddle

因此,当您在基元数组上执行ng-repeat 时:item in ["a", "b",...] 并在其中使用<input ng-model="item">,您实际上是在执行childScope.item = "..."

【讨论】:

  • 此答案并不能真正解释 OP 的 why 问题,请参阅此问题以获得更广泛的答案:*.com/questions/14049480/…
  • why 遵循 JS 中原型继承的行为,我已经展示了如何使用父作用域作为其原型来创建子作用域。有重复的问题和答案是另一回事。