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