scope的继承

本文转载自: http://www.tuicool.com/articles/63iEref

angular中scope的继承与js的原型继承有密切的联系,首先回顾一下js的继承:

function ParentScope(){
    this.aString = "parent string";
    this.aNumber = 100;
    this.anArray = [10,20,30];
    this.anObject = {
    'property1': 'parent prop1',
    'property2': 'parent prop2' 
    };
    this.aFunction = function(){ 
      return 'parent output'; 
    }
}

function ChildScope(){    
}

ChildScope.prototype = new ParentScope();
ChildScope.prototype.constructor= ParentScope;
var childScope = new ChildScope();

ChildScope继承自ParentScope,关系图如下:

如果我们要在 childScope 上查询一个定义在 parentScope 的属性, JavaScript 会先在 childScope 上查找, 如果没有查到, 那么会顺着原型链去查找. 所以以下判别式均为 true

childScope.aString === 'parent string'
childScope.anArray[1] === 20
childScope.anObject.property1 === 'parent prop1'
childScope.aFunction() === 'parent output'

接下来做如下操作

childScope.aString= 'child string'

原型链将不会被访问, 一个新的 aString 会被加入到 childScope 的属性中去, 新的属性会隐藏 parentScope 中的同名属性:

再这么做:

childScope.anArray[1]= 10;

childScope.anObject.property1= 'child prop1';

原型链被访问了. 因为 anArray , anObject 没有在 childScope 中找到.

新的赋值操作均在 parentScope 上进行. childScope 上没有添加任何新的属性.

但如果我们做如下操作:

childScope.anArray= [100, 555];

childScope.anObject= {name: 'Mark', country: 'USA'}

原型链没有被访问, childScope 会获得两个新的属性, 并且会隐藏 parentScope 上的同名属性.

仔细分析, 第一第三次均是对某个属性直接进行赋值, 原型链并不会被访问, 由于属性并不存在, 所以新的属性将会被添加.

而第二次其实是先访问 , 再赋值,原型链就会被打开。

--------------------------------------------------------------------------------------------------------------------------------------------------

再来看Angular scope的继承

以下指令汇创建新的scope,并且在原型上继承父scope

ng-repeat, ng-switch,ng-view,ng-controller

带有scope: true的指令,带有transclude:true的指令

值得注意的是以下指令不会继承父scope

scope: {}的指令,这会创建一个隔离作用域

scope: false ,这会共享作用域

 

让我们看几个例子:

ng-include

JS:

$scope.myPrimitive = 50;
$scope.myObject    = {aNumber: 11};

HTML:

<p>{ myPrimitive }</p> <p>{ myObject.aNumber }</p> // cannot use double curly brackets in jekyll <script type="text/ng-template" id="/tpl1.html"> <input type="number" ng-model="myPrimitive"> </script> <div ng-include src="'/tpl1.html'"></div> <script type="text/ng-template" id="/tpl2.html"> <input type="number" ng-model="myObject.aNumber"> </script> <div ng-include src="'/tpl2.html'"></div> 

每一个ng-include都会创建一个子scope, 并在原型上继承父scope

向第一个 input 输入数字, 一个新的属性 myPrimitive 将会被创建, 同时隐藏 父 scope 的 myPrimitive ;

向第二个 input 输入数字, 子 scope 并不会创建一个新的属性, 这时候原型继承发挥了作用

第一种情况很可能不是我们期待的结果, 所以可以显式的调用 $parent 来解决这个问题.

<input type= "text" ng-model= "$parent.myPrimitive"/>

向第一个 input 键入数字, 这时候就不会产生新的属性了. $parent 指向了 父scope. 但是 $parent 和 原型上的继承并不一定相等. 稍后我们会看到一个例子.

对于所有的 scope, 无论是共享的( scope: false ), 继承的( scope: true ), 还是孤立的( scope: { ... } ),

Angular 都会建立一个 父-子 的层级关系, 这个层级关系是根据 dom 结构的层级关系决定的, 可以通过 $parent , $$childHead , $$childTail 来访问.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ng-switch、ng-view

情况与ng-include一样,不赘述

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ng-repeat

ng-repeat有一些特殊

$scope.myArrayOfPrimitives = [ 11, 22 ];
$scope.myArrayOfObjects    = [{num: 101}, {num: 202}]
<ul><li ng-repeat="num in myArrayOfPrimitives">
       <input ng-model="num"></input>
    </li>
</ul>
<ul><li ng-repeat="obj in myArrayOfObjects">
       <input ng-model="obj.num"></input>
    </li>
</ul>

对于每一次迭代, ng-repeat 都会创建一个 子scope, 并在原型上继承 父scope, 但是他还会将 父scope 上的属性赋值到 子scope 上 . 新的属性名就是 ng-repeat="** in parentScope.property"中的 **.

源码中的 ng-repeat 是这样的:

childScope = scope.$new(); // child scope prototypically inherits from parent scope ...     
childScope[valueIdent] = value; // creates a new childScope property

如果 ** 是 primitive, 那么一份 copy 会被赋值到新的属性上. 修改 子scope 上的新属性自然不会修改 父 scope 上的属性.

如果 ** 是个 object, 那么一个 reference 会被赋值到新的 子scope 属性上. 修改这个属性, 就是修改 父scope 对应的属性.

ng-controller

ng-controller 也是会创建新的 子scope, 同时原型继承 父scope. 如同 ng-include, ng-switch, ng-view.

但是, 使用 $scope 来共享数据被认为是一种不好的操作. 因为原型链可是会一直向上追溯的.

如果想要共享数据, 最好使用 service

--------------------------------------------------------------------------------------------------------------------------------------

directive

我们来总结以下指令中的 scope:

1.scope: false  指令不会创建新的 scope, 没有继承关系. 与 $parent 共享 $scope

2.scope: true 指令会创建一个 子scope, 并在原型上继承 $parent. 如果在一个 DOM 上有多个指令想要创建新的 scope, 会报错.

3.scope: {...} 指令会创建一个 孤立的scope. 这在创建可重用的组件时是最好的选择. 但是, 即使如此, 指令还是希望读取 $parent 的数据.

 

transclude

指令创建了一个 “transcluded” 的子scope, 在原型上继承其 父scope. 如果上述例子同时具有 transclude: true . 那么这个 “transcluded” scope, 和 “islolated” scope 是姊妹关系. 他们的 $parent 指向同一个 scope. 且 isolate scope 的 $$nextSibling 就是这个 “transcluded scope”. 下图反应了他们之间的关系:

 

转载于:https://www.cnblogs.com/yanze/p/6388987.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Python中,如果一个变量或函数在父类中被定义为私有(以双下划线开头),那么它在子类中将无法被访问。但是,如果将变量或函数定义为受保护的(以单下划线开头),则它将在子类中继承并且可以被访问。 以下是一个简单的例子,展示了一个基类中定义了一个受保护的变量和函数,而子类中可以继承和访问这些变量和函数: ```python class Parent: _protected_var = "I am a protected variable in Parent class" def __init__(self): self._protected_function() def _protected_function(self): print("I am a protected function in Parent class") class Child(Parent): def __init__(self): super().__init__() print(self._protected_var) self._protected_function() c = Child() ``` 输出: ``` I am a protected function in Parent class I am a protected variable in Parent class I am a protected function in Parent class ``` 可以看到,子类`Child`可以继承和访问基类`Parent`中定义的受保护变量和函数。 ### 回答2: "scope test 被子包继承"这句话是一个关于包的继承范围测试的问题。 在Java中,一个包(package)可以被另一个包所继承。被继承的包称为父包,继承的包称为子包。包的继承可以提供代码的共享和重用。 当一个子包继承一个父包时,子包可以访问父包中的所有非私有类、接口和成员。这意味着在子包中,可以直接使用父包的类、接口和成员而不需要引入(import)。 然而,需要注意的是,子包不能访问父包中声明为私有(private)的类、接口和成员。私有成员只能在其所在的包中直接访问。只有公共(public)和受保护(protected)成员可以被继承到子包中。 另外,子包继承父包的同时也继承了父包中的访问修饰符。如果一个类、接口或成员在父包中被声明为公共,那么在子包中也可以对其进行公共访问。如果在父包中被声明为受保护,那么在子包中可以进行受保护访问。 需要注意的是,子包只能继承直接的父包,而不能继承间接的父包。如果子包想要使用间接的父包中的类或接口,必须在子包中引入(import)该类或接口。 综上所述,当"scope test 被子包继承"时,子包将继承父包中的公共和受保护的类、接口和成员,并且可以直接使用它们。同时,子包也继承了父包中的访问修饰符。对于私有的成员,子包将无法直接访问。 ### 回答3: 当一个子包继承了一个scope test时,它将继承scope test的所有成员和方法。这意味着子包可以直接访问和使用该scope test中的所有变量、属性和方法,无需重新声明或定义它们。 在继承后,子包可以通过调用和使用继承的成员来扩展其功能。例如,如果scope test中有一个公共变量,子包可以直接访问和修改该变量的值。同样,如果scope test中有一个公共方法,子包可以直接调用并使用该方法来执行特定的操作。 继承还使得子包能够重写和覆盖scope test中的方法。如果子包需要对某个方法进行定制或修改,它可以在自己的代码中重新实现该方法,并且子包的代码将会优先执行,而不是调用继承的方法。这样,子包可以根据自己的需求进行适应和定制,而无需改变或影响其他继承了该scope test的包或程序。 总的来说,当一个子包继承了一个scope test,它可以直接使用和扩展该scope test中的所有成员和方法。这种继承关系使得子包能够灵活地定制和扩展自己的功能,同时保留并重用scope test中已有的代码和逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值