摘要:原文發(fā)自我的博客易企秀招聘啦首先我們先來(lái)回顧以下中出現(xiàn)的原型繼承原型繼承自如果我們要在上查詢一個(gè)定義在的屬性會(huì)先在上查找如果沒有查到那么會(huì)順著原型鏈去查找所以以下判別式均為如果我們做如下操作原型鏈并沒有被訪問一個(gè)新的會(huì)被加入到的屬性中去新的
原文發(fā)自我的博客 xiaoyu2er.github.io
易企秀招聘啦!
JavaScript Prototypal Inheritance首先我們先來(lái)回顧以下 javascript 中出現(xiàn)的原型繼承:
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(); var childScope = new ChildScope();
ChildScope 原型繼承自 ParentScope
如果我們要在 childScope 上查詢一個(gè)定義在 parentScope 的屬性, JavaScript 會(huì)先在 childScope 上查找, 如果沒有查到, 那么會(huì)順著原型鏈去查找. 所以以下判別式均為 true
childScope.aString === "parent string" childScope.anArray[1] === 20 childScope.anObject.property1 === "parent prop1" childScope.aFunction() === "parent output"
如果我們做如下操作:
childScope.aString = "child string"
原型鏈并沒有被訪問, 一個(gè)新的 aString 會(huì)被加入到 childScope 的屬性中去, 新的屬性會(huì)隱藏 parentScope 中的同名屬性.
假設(shè)我們做出如下操作:
childScope.anArray[1] = 22 childScope.anObject.property1 = "child prop1"
原型鏈被訪問了. 因?yàn)?anArray, anObject 沒有在 childScope 中找到.
新的賦值操作均在 parentScope 上進(jìn)行. childScope 上沒有添加任何新的屬性.
如果我們做出如下操作
childScope.anArray = [100, 555] childScope.anObject = { name: "Mark", country: "USA" }
原型鏈沒有被訪問, childScope 會(huì)獲得兩個(gè)新的屬性, 并且會(huì)隱藏 parentScope 上的同名屬性.
仔細(xì)體會(huì)上面的三次操作. 第一第三次均是對(duì)某個(gè)屬性進(jìn)行賦值, 原型鏈并不會(huì)被訪問, 由于屬性并不存在, 所以新的屬性將會(huì)被添加. 而第二次其實(shí)是先訪問, childScope.anArray, childScope.anObject, 再對(duì)其訪問的對(duì)象的某個(gè)屬性進(jìn)行復(fù)制.
總結(jié):
如果我們讀取 childScope.propertyX, 而 childScope 擁有 propertyX, 那么原型鏈不會(huì)被訪問
如果我們讀取 childScope.propertyX, 而 childScope 并沒有 propertyX, 那么原型鏈會(huì)被訪問.
如果對(duì) childScope.propertyX 進(jìn)行賦值, 那么原型鏈并不會(huì)被訪問.
最后我們?cè)賮?lái)看一種情況:
delete childScope.anArray childScope.anArray[1] === 22 // true
我們顯示刪除了 childScope 的一個(gè)屬性, 接著試圖讀取這個(gè)屬性, 由于 childScope 并沒有了這個(gè)屬性, 所以原型鏈會(huì)被訪問.
Angular Scope Inheritance接著我們來(lái)看看 Angular 中的 scope 繼承
以下指令會(huì)創(chuàng)建新的 scope, 并且會(huì)在原型上繼承 父scope (即$scope.$parent, 下文兩個(gè)詞互為同義詞):
ng-repeat
ng-switch
ng-view
ng-controller
帶有 scope: true 的指令
帶有 transclude: true 的指令
以下指令創(chuàng)建新的指令, 且在原型上 不繼承 父scope:
帶有 scope: { ... } 的指令, 這會(huì)創(chuàng)建一個(gè) 獨(dú)立的scope (isolate scope)
注意: 默認(rèn)指令并不會(huì)創(chuàng)建 scope, 默認(rèn)是 scope: false, 通常稱之為 共享scope.
讓我們來(lái)看幾個(gè)例子:
ng-includeJS:
$scope.myPrimitive = 50; $scope.myObject = {aNumber: 11};
HTML:
{{ myPrimitive }}
{{ myObject.aNumber }}
每一個(gè) ng-include 都會(huì)創(chuàng)建一個(gè) 子scope, 并在原型上繼承 父 scope
向第一個(gè) input 輸入數(shù)字, 一個(gè)新的屬性 myPrimitive 將會(huì)被創(chuàng)建, 同時(shí)隱藏 父 scope 的 myPrimitive;
向第二個(gè) input 輸入數(shù)字, 子 scope 并不會(huì)創(chuàng)建一個(gè)新的屬性, 這時(shí)候原型繼承發(fā)揮了作用.
第一種情況很可能不是我們期待的結(jié)果, 所以可以顯式的調(diào)用 $parent 來(lái)解決這個(gè)問題.
向第一個(gè) input 鍵入數(shù)字, 這時(shí)候就不會(huì)產(chǎn)生新的屬性了. $parent 指向了 父scope. 但是 $parent 和 原型上的繼承并不一定相等. 稍后我們會(huì)看到一個(gè)例子.
對(duì)于所有的 scope, 無(wú)論是共享的(scope: false), 繼承的(scope: true), 還是孤立的(scope: { ... }), Angular 都會(huì)建立一個(gè) 父-子 的層級(jí)關(guān)系, 這個(gè)層級(jí)關(guān)系是根據(jù) dom 結(jié)構(gòu)的層級(jí)關(guān)系決定的, 可以通過(guò)
$parent $$childHead $$childTail
來(lái)訪問.
為了避免剛才的例子出現(xiàn)的子 scope 創(chuàng)建新屬性情況的發(fā)聲, 除了使用 $scope, 還可以使用調(diào)用原型鏈上的方法.
// in the parent scope $scope.setMyPrimitive = function(value) { $scope.myPrimitive = value; }ng-switch ng-view
ng-switch, ng-view 與 ng-include 情況類似, 不贅述.
ng-repeatng-repeat 有一點(diǎn)特殊.
JS:
$scope.myArrayOfPrimitives = [ 11, 22 ]; $scope.myArrayOfObjects = [{num: 101}, {num: 202}]
HTML:
對(duì)于每一次迭代, ng-repeat 都會(huì)創(chuàng)建一個(gè) 子scope, 并在原型上繼承 父scope, 但是他還會(huì)將 父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 會(huì)被賦值到新的屬性上. 修改 子scope 上的新屬性自然不會(huì)修改 父 scope 上的屬性.
如果 ** 是個(gè) object, 那么一個(gè) reference 會(huì)被賦值到新的 子scope 屬性上. 修改這個(gè)屬性, 就是修改 父scope 對(duì)應(yīng)的屬性.
ng-controllerng-controller 也是會(huì)創(chuàng)建新的 子scope, 同時(shí)原型繼承 父scope. 如同 ng-include, ng-switch, ng-view.
但是, 使用 $scope 來(lái)共享數(shù)據(jù)被認(rèn)為是一種不好的操作. 因?yàn)樵玩溈墒菚?huì)一直向上追溯的.
如果想要共享數(shù)據(jù), 最好使用 service.
我們來(lái)總結(jié)以下指令中的 scope:
scope: false(默認(rèn)的), 指令不會(huì)創(chuàng)建新的 scope, 沒有繼承關(guān)系. 與 $parent 共享 $scope.
scope: true, 指令會(huì)創(chuàng)建一個(gè) 子scope, 并在原型上繼承 $parent. 如果在一個(gè) DOM 上有多個(gè)指令想要?jiǎng)?chuàng)建新的 scope, 會(huì)報(bào)錯(cuò).
scope: { ... }, 指令會(huì)創(chuàng)建一個(gè) 孤立的scope. 這在創(chuàng)建可重用的組件時(shí)是最好的選擇. 但是, 即使如此, 指令還是希望讀取 $parent 的數(shù)據(jù). 這個(gè)時(shí)候可以使用如下符號(hào)獲得:
scope: { **: "="} 與 $parent 建立雙向綁定.
scope: { **: "@"} 與 $parent 建立單向綁定.
scope: { **: "&"} 綁定 $parent 的表達(dá)式.
想要獲得相應(yīng)的屬性, 必須通過(guò)指令上的屬性獲得
HTML: JS: scope: { localProp: "@theParentProp" } HTML: JS: scope: { interpolatedProp: "@interpolated", twowayBindingProp: "=twowayBinding" } 指令在 link 期間: scope.someIsolateProp = "I"m isolated" transclude: true, 指令創(chuàng)建了一個(gè) "transcluded" 的子scope, 在原型上繼承其 父scope. 如果上述例子同時(shí)具有transclude: true. 那么這個(gè) "transcluded" scope, 和 "islolated" scope 是姊妹關(guān)系. 他們的 $parent 指向同一個(gè) scope. 且 isolate scope 的 $$nextSibling 就是這個(gè) "transcluded scope". 下圖反應(yīng)了他們之間的關(guān)系: Angular Wiki: Understanding Scopes 文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。 轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78566.html
假設(shè):
其中的關(guān)系如圖:
摘要:如何在中使用動(dòng)畫前端掘金本文講一下中動(dòng)畫應(yīng)用的部分。與的快速入門指南推薦前端掘金是非常棒的框架,能夠創(chuàng)建功能強(qiáng)大,動(dòng)態(tài)功能的。自發(fā)布以來(lái),已經(jīng)廣泛應(yīng)用于開發(fā)中。 如何在 Angular 中使用動(dòng)畫 - 前端 - 掘金本文講一下Angular中動(dòng)畫應(yīng)用的部分。 首先,Angular本生不提供動(dòng)畫機(jī)制,需要在項(xiàng)目中加入Angular插件模塊ngAnimate才能完成Angular的動(dòng)畫機(jī)制...
摘要:錯(cuò)過(guò)了一周的優(yōu)質(zhì)內(nèi)容,不要再錯(cuò)過(guò)周一的快速回顧一周深度揭秘啟動(dòng)全過(guò)程翻譯組每周社區(qū)問答入門語(yǔ)言簡(jiǎn)明入門與提高一只爬蟲崔小拽爬蟲知乎用戶數(shù)據(jù)爬取和分析如何學(xué)習(xí)開源動(dòng)效分析二動(dòng)畫最佳實(shí)踐一工具箱之生命周期工具箱之權(quán)限管理一步步創(chuàng)建自己的框 錯(cuò)過(guò)了一周的優(yōu)質(zhì)內(nèi)容,不要再錯(cuò)過(guò)周一的快速回顧 一周 fir.im Weekly -《深度揭秘 App 啟動(dòng)全過(guò)程》 SwiftGG翻譯組 -《每周 S...
摘要:錯(cuò)過(guò)了一周的優(yōu)質(zhì)內(nèi)容,不要再錯(cuò)過(guò)周一的快速回顧一周深度揭秘啟動(dòng)全過(guò)程翻譯組每周社區(qū)問答入門語(yǔ)言簡(jiǎn)明入門與提高一只爬蟲崔小拽爬蟲知乎用戶數(shù)據(jù)爬取和分析如何學(xué)習(xí)開源動(dòng)效分析二動(dòng)畫最佳實(shí)踐一工具箱之生命周期工具箱之權(quán)限管理一步步創(chuàng)建自己的框 錯(cuò)過(guò)了一周的優(yōu)質(zhì)內(nèi)容,不要再錯(cuò)過(guò)周一的快速回顧 一周 fir.im Weekly -《深度揭秘 App 啟動(dòng)全過(guò)程》 SwiftGG翻譯組 -《每周 S...
閱讀 1550·2021-11-24 10:17
閱讀 1046·2021-09-29 09:43
閱讀 2177·2021-09-23 11:21
閱讀 2191·2019-08-30 14:13
閱讀 1308·2019-08-29 13:58
閱讀 3168·2019-08-28 17:51
閱讀 1830·2019-08-26 13:29
閱讀 2990·2019-08-26 10:13