您好,登錄后才能下訂單哦!
這篇文章主要介紹了關于angular的前端面試題有哪些,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
1,ng-if 跟 ng-show/hide 的區別有哪些?
第一點區別是,ng-if
在后面表達式為 true
的時候才創建這個 dom
節點,ng-show
是初始時就創建了,用 display:block
和 display:none
來控制顯示和不顯示。
第二點區別是,ng-if
會(隱式地)產生新作用域,ng-switch
、 ng-include
等會動態創建一塊界面的也是如此。
這樣會導致,在 ng-if
中用基本變量綁定 ng-model
,并在外層 p
中把此 model
綁定給另一個顯示區域,內層改變時,外層不會同步改變,因為此時已經是兩個變量了。
<p>{{name}}</p> <div ng-if="true"> <input type="text" ng-model="name"> </div>
ng-show
不存在此問題,因為它不自帶一級作用域。
避免這類問題出現的辦法是,始終將頁面中的元素綁定到對象的屬性(data.x)而不是直接綁定到基本變量(x)上。
2,ng-repeat迭代數組的時候,如果數組中有相同值,會有什么問題,如何解決?
會提示 Duplicates in a repeater are not allowed
. 加 track by $index
可解決。當然,也可以 trace by
任何一個普通的值,只要能唯一性標識數組中的每一項即可(建立 dom
和數據之間的關聯)。
3,ng-click 中寫的表達式,能使用 JS 原生對象上的方法嗎?
不止是 ng-click
中的表達式,只要是在頁面中,都不能直接調用原生的 JS
方法,因為這些并不存在于與頁面對應的 Controller
的 $scope
中。
4、factory、service 和 provider 是什么關系?
factory
:把 service
的方法和數據放在一個對象里,并返回這個對象
service
:通過構造函數方式創建 service
,返回一個實例化對象
provider
:創建一個可通過 config
配置的 service
,$get
中返回的,就是用 factory
創建 service
的內容
從底層實現上來看,service
調用了 factory
,返回其實例;factory 調用了 provider
,返回其 $get
中定義的內容。factory
和 service
功能類似,只不過 factory
是普通 function
,可以返回任何東西(return
的都可以被訪問,所以那些私有變量怎么寫,你懂的);
service
是構造器,可以不返回(綁定到 this
的都可以被訪問);
provider
是加強版 factory
,返回一個可配置的 factory
。
5、angular 中控制器之間如何通信?
1、Service
2、events
,指定綁定的事件
3、使用 $rootScope
4、controller
之間直接使用$parent, $$childHead
等
5、directive
指定屬性進行數據綁定
6,angular 的數據綁定采用什么機制?詳述原理
使用的臟檢查機制,所謂的雙向綁定,其實就是從界面的操作能實時反映到數據,數據的變更能實時展現到界面。AngularJS
在$scope
變量中使用臟值檢查來實現了數據雙向綁定,并且可以通過$scope.$watch
來監聽變化觸發回調;
angular
中使用的是臟檢查機制,在angular
中每次你綁定一些東西到你的UI上時你就會往$watch
隊列里插入一條$watch
,當我們的模版加載完畢時,也就是在linking
階段(Angular
分為compile
階段和linking
階段—譯者注),Angular
解釋器會尋找每個directive
,然后生成每個需要的$watch
。
當瀏覽器接受到可以被angular context
處理的事件時就會觸發digest
循環,這個循環是由兩個更小的循環組合起來的,一個是$watch
列表,一個是$evalAsync
列表,而$watch
列表在$digest
循環中被“臟值檢查”解析,在digest
將會遍歷我們的watch
,然后詢問它是否有屬性和值的變化,直到$watch
隊列都檢查過,在檢查數據變化的時候,由于并不知道這個事件是對哪些數據進行了更改,以及這個事件有可能造成事件之外的其他任何地方的數據更改,所以必須進行一次大檢查,將所有“注冊”過的值全部檢查一遍,一次檢查稱為一個周期,每次最少檢查兩遍,因為第二遍用來確認,前一遍的變動中是否有數據的變動,導致了其他數據的變動,如果第二次有變動的話,會再執行一遍,直到最后兩次完全一致,則停止檢查(其實就是個(遞歸(遍歷))的過程),考慮到內存的消耗和死循環的風險,臟檢查每個周期最多遞歸執行10遍,如果超過10遍就會拋出一個錯誤。當$digest
循環結束時,DOM
相應地變化。
在angular
中
ng-click,ng-change,ng-blur..
.就是對各類用戶事件的封裝
$timeout,$http,$window,$location...
就是對各種JS/API
事件的封裝
ng-model
,以及控制器中的數據,就是對值的“注冊”
$scope
本質是一個總的事件邏輯的封裝容器,同時抽象為數據載體,實質上數據都存在于瀏覽器堆內存中
$scope.apply() & $scope.digest()
即Angular
中的“數據大檢查”的function
所以如果我們使用了非Angular
封裝的事件改編數據時,要手動執行一次大檢查
由于Angular
這種臟檢查的方法效率不高,如果一個頁面綁定的view
超過2000個,就可能存在比較明顯的性能問題,官方稱之為“臟檢查”
舉個例子
<button ng-click="val=val+1">increase 1</button>
click
時會產生一次更新的操作(至少觸發兩次 $digest
循環)
按下按鈕瀏覽器接收到一個事件,進入到angular context
$digest
循環開始執行,查詢每個 $watch
是否變化
由于監視$scope.val
的 $watch
報告了變化,因此強制再執行一次 $digest
循環 新的 $digest
循環未檢測到變化
瀏覽器拿回控制器,更新 $scope.val
新值對應的 dom
$digest
循環的上限是 10 次(超過 10次后拋出一個異常,防止無限循環)。
7、一個 angular 應用應當如何良好地分層?
目錄結構的劃分
對于小型項目,可以按照文件類型組織,比如:
css js controllers models services filters templates
但是對于規模較大的項目,最好按業務模塊劃分,比如:
css modules account controllers models services filters templates disk controllers models services filters templates
modules
下最好再有一個 common
目錄來存放公共的東西。
邏輯代碼的拆分
作為一個 MVVM
框架,Angular
應用本身就應該按照 模型,視圖模型(控制器),視圖來劃分。
這里邏輯代碼的拆分,主要是指盡量讓 controller
這一層很薄。提取共用的邏輯到 service
中 (比如后臺數據的請求,數據的共享和緩存,基于事件的模塊間通信等),提取共用的界面操作到 directive
中(比如將日期選擇、分頁等封裝成組件等),提取共用的格式化操作到 filter
中等等。
在復雜的應用中,也可以為實體建立對應的構造函數,比如硬盤(Disk
)模塊,可能有列表、新建、詳情這樣幾個視圖,并分別對應的有 controller
,那么可以建一個 Disk
構造函數,里面完成數據的增刪改查和驗證操作,有跟 Disk
相關的 controller
,就注入 Disk
構造器并生成一個實例,這個實例就具備了增刪改查和驗證方法。這樣既層次分明,又實現了復用(讓 controller
層更薄了)。
8、angular 應用常用哪些路由庫,各自的區別是什么?
Angular1.x
中常用 ngRoute
和 ui.router
,還有一種為 Angular2
設計的 new router
(面向組件)。后面那個沒在實際項目中用過,就不講了。
無論是 ngRoute
還是 ui.router
,作為框架額外的附加功能,都必須以 模塊依賴 的形式被引入。
區別
ngRoute
模塊是 Angular
自帶的路由模塊,而 ui.router
模塊是基于 ngRoute
模塊開發的第三方模塊。
ui.router
是基于 state
(狀態)的, ngRoute
是基于 url
的,ui.router
模塊具有更強大的功能,主要體現在視圖的嵌套方面。
使用 ui.router
能夠定義有明確父子關系的路由,并通過 ui-view
指令將子路由模版插入到父路由模板的 <p ui-view></p>
中去,從而實現視圖嵌套。而在 ngRoute
中不能這樣定義,如果同時在父子視圖中 使用了 <p ng-view></p>
會陷入死循環。
分屬不同團隊進行開發的 angular
應用,如果要做整合,可能會遇到哪些問題,如何解決?
可能會遇到不同模塊之間的沖突。
比如一個團隊所有的開發在 moduleA 下進行,另一團隊開發的代碼在 moduleB 下
angular.module('myApp.moduleA', []) .factory('serviceA', function(){ ... }) angular.module('myApp.moduleB', []) .factory('serviceA', function(){ ... }) angular.module('myApp', ['myApp.moduleA', 'myApp.moduleB'])
會導致兩個 module
下面的 serviceA
發生了覆蓋。
貌似在 Angular1.x
中并沒有很好的解決辦法,所以最好在前期進行統一規劃,做好約定,嚴格按照約定開發,每個開發人員只寫特定區塊代碼。
9、angular 的缺點有哪些?
強約束
導致學習成本較高,對前端不友好。
但遵守 AngularJS
的約定時,生產力會很高,對 Java
程序員友好。
不利于 SEO
因為所有內容都是動態獲取并渲染生成的,搜索引擎沒法爬取。
一種解決辦法是,對于正常用戶的訪問,服務器響應 AngularJS 應用的內容;對于搜索引擎的訪問,則響應專門針對 SEO 的HTML頁面。
性能問題
作為 MVVM 框架,因為實現了數據的雙向綁定,對于大數組、復雜對象會存在性能問題。
可以用來 優化 Angular 應用的性能 的辦法:
減少監控項(比如對不會變化的數據采用單向綁定)
主動設置索引(指定 track by
,簡單類型默認用自身當索引,對象默認使用 $$hashKey
,比如改為 track by item.id
)
降低渲染數據量(比如分頁,或者每次取一小部分數據,根據需要再取)
數據扁平化(比如對于樹狀結構,使用扁平化結構,構建一個 map
和樹狀數據,對樹操作時,由于跟扁平數據同一引用,樹狀數據變更會同步到原始的扁平數據)
另外,對于Angular1.x ,存在 臟檢查 和 模塊機制 的問題。
移動端
可嘗試 Ionic,但并不完善。
10、解釋下什么是$rootScrope
以及和$scope
的區別?
通俗的說$rootScrope
頁面所有$scope
的父親
如何產生$rootScope
和$scope
吧。
step1:Angular解析ng-app
然后在內存中創建$rootScope
。
step2:angular回繼續解析,找到{{}}表達式,并解析成變量。
step3:接著會解析帶有ng-controller
的p
然后指向到某個controller
函數。這個時候在這個controller
函數變成一個$scope
對象實例。
**11、如何取消 $timeout
, 以及停止一個$watch()
? **
停止 $timeout
我們可以用cancel
:
var customTimeout = $timeout(function () { // your code }, 1000); $timeout.cancel(customTimeout);
停掉一個$watch
:
// .$watch()
會返回一個停止注冊的函數
function that we store to a variable var deregisterWatchFn = $rootScope.$watch(‘someGloballyAvailableProperty', function (newVal) { if (newVal) { // we invoke that deregistration function, to disable the watch deregisterWatchFn(); ... } });
12、Angular Directive中restrict 中分別可以怎樣設置?scope中@,=,&有什么區別?
restrict中可以分別設置:
A匹配屬性
E匹配標簽
C匹配class
M 匹配注釋
當然你可以設置多個值比如AEC,進行多個匹配。
在scope中,@,=,&在進行值綁定時分別表示
@
獲取一個設置的字符串,它可以自己設置的也可以使用{{yourModel}}
進行綁定的;
=
雙向綁定,綁定scope
上的一些屬性;
&
用于執行父級scope
上的一些表達式,常見我們設置一些需要執行的函數
13、$apply()
和 $digest()
的區別
安全性:$apply()
可以接收一個參數作為function()
,這個 function
會被包裝到一個 try … catch
塊中,所以一旦有異常發生,該異常會被 $exceptionHandler service
處理。
$apply
會使ng
進入 $digest cycle
, 并從$rootScope
開始遍歷(深度優先)檢查數據變更。
$digest
僅會檢查該scope和它的子scope
,當你確定當前操作僅影響它們時,用$digest
可以稍微提升性能。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“關于angular的前端面試題有哪些”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。