Notice: Undefined index: wb_190625 in /var/www/html/wp-content/themes/boke-1/functions.php on line 232
Angular面试题汇总 – 独の狼

Angular面试题汇总

文章目录[隐藏]

Angular 面试问题

1.  请解释Angular 2应用程序的生命周期hooks是什么?

Angular 2组件/指令具有生命周期事件,是由@angular/core管理的。@angular/core会创建组件,渲染它,创建并呈现它的后代。当@angular/core的数据绑定属性更改时,处理就会更改,在从DOM中删除其模板之前,就会销毁掉它。Angular提供了一组生命周期hooks(特殊事件),可以被分接到生命周期中,并在需要时执行操作。构造函数会在所有生命周期事件之前执行。每个接口都有一个前缀为ng的hook方法。例如,ngOnint界面的OnInit方法,这个方法必须在组件中实现。 

一部分事件适用于组件/指令,而少数事件只适用于组件。

  • ngOnChanges:当Angular设置其接收当前和上一个对象值的数据绑定属性时响应。
  • ngOnInit:在第一个ngOnChange触发器之后,初始化组件/指令。这是最常用的方法,用于从后端服务检索模板的数据。
  • ngDoCheck:检测并在Angular上下文发生变化时执行。每次更改检测运行时,会被调用。
  • ngOnDestroy:在Angular销毁指令/组件之前清除。取消订阅可观察的对象并脱离事件处理程序,以避免内存泄漏。

组件特定hooks:

  • ngAfterContentInit:组件内容已初始化完成
  • ngAfterContentChecked:在Angular检查投影到其视图中的绑定的外部内容之后。
  • ngAfterViewInit:Angular创建组件的视图后。
  • ngAfterViewChecked:在Angular检查组件视图的绑定之后。

 

2.  使用Angular 2,和使用Angular 1相比,有什么优势?

  1. Angular 2是一个平台,不仅是一种语言
  2. 更好的速度和性能
  3. 更简单的依赖注入
  4. 模块化,跨平台
  5. 具备ES6和Typescript的好处。
  6. 灵活的路由,具备延迟加载功能
  7. 更容易学习

 

3.  Angular 2中的路由工作原理是什么?

路由是能够让用户在视图/组件之间导航的机制。Angular 2简化了路由,并提供了在模块级(延迟加载)下配置和定义的灵活性。 

Angular应用程序具有路由器服务的单个实例,并且每当URL改变时,相应的路由就与路由配置数组进行匹配。在成功匹配时,它会应用重定向,此时路由器会构建ActivatedRoute对象的树,同时包含路由器的当前状态。在重定向之前,路由器将通过运行保护(CanActivate)来检查是否允许新的状态。Route Guard只是路由器运行来检查路由授权的接口方法。保护运行后,它将解析路由数据并通过将所需的组件实例化到<router-outlet> </ router-outlet>中来激活路由器状态。

扩展阅读:

  1. https://www.codeproject.com/Articles/1164813/Angular-Routing 
  2. https://vsavkin.com/angular-2-router-d9e30599f9ea#.kt4z1v957

 

4.  什么是事件发射器?它是如何在Angular 2中工作的?

Angular 2不具有双向digest cycle,这是与Angular 1不同的。在Angular2中,组件中发生的任何改变总是从当前组件传播到其所有子组件中。如果一个子组件的更改需要反映到其父组件的层次结构中,我们可以通过使用事件发射器api来发出事件。

简而言之,EventEmitter是在@ angular/core模块中定义的类,由组件和指令使用,用来发出自定义事件。

@output() somethingChanged = new EventEmitter();

我们使用somethingChanged.emit(value)方法来发出事件。这通常用在setter中,当类中的值被更改完成时。

可以通过模块的任何一个组件,使用订阅方法来实现事件发射的订阅。

myObj.somethingChanged.subscribe(val) => this.myLocalMethod(val));

扩展阅读:

  1. http://stackoverflow.com/questions/36076700/what-is-the-proper-use-of-an-eventemitter
  2. https://angular.io/docs/ts/latest/api/core/index/EventEmitter-class.HTML

 

5.  如何在Angular 2应用程序中使用codelyzer?

所有企业应用程序都会遵循一组编码惯例和准则,以更好的方式维护代码。Codelyzer是一个开源工具,用于运行和检查是否遵循了预定义的编码准则。Codelyzer仅对Angular和TypeScript项目进行静态代码分析。

Codelyzer运行在tslint的顶部,其编码约定通常在tslint.json文件中定义。Codelyzer可以直接通过Angularcli或npm运行。像Visual Studio Code和Atom这样的编辑器也支持codelyzer,只需要通过做一个基本的设置就能实现。

要在Visual Studio代码中设置codelyzer,我们可以在文件 – >选项 – >用户设置中添加tslint规则的路径。

{

    "tslint.rulesDirectory": "./node_modules/codelyzer",

    "typescript.tsdk": "node_modules/typescript/lib"

}

从cli中运行的代码:ng lint。 

从npm中运行的代码: npm run lint

扩展阅读:

  1. https://github.com/mgechev/codelyzer
  2. https://www.youtube.com/watch?v=bci-Z6nURgE

 

6.  什么是延迟加载?如何在Angular 2中启用延迟加载?

大多数企业应用程序包含用各式各样的用于特定业务案例的模块。捆绑整个应用程序代码并完成加载,会在初始调用时,产生巨大的性能开销。延迟加载使我们只加载用户正在交互的模块,而其余的模块会在运行时按需加载。

延迟加载通过将代码拆分成多个包并以按需加载的方式,来加速应用程序初始加载过程。

每个Angular应用程序必须有一个叫AppModule的主模块。代码应该根据应用程序业务案例分为不同的子模块(NgModule)。

 

启用延迟加载的Plunkr示例: 

  1. 我们不需要在根模块中导入或声明延迟加载模块。
  2. 将路由添加到顶层路由(app.routing.ts)并设置loadChildren。loadChildren会从根文件夹中获取绝对路径。RouterModule.forRoot()会获取routes数组并配置路由器。
  3. 在子模块中导入模块特定路由。
  4. 在子模块路由中,将路径指定为空字符串“”,也就是空路径。RouterModule.forChild会再次采用路由数组为子模块组件加载并配置路由器。
  5. 然后,导出const路由:ModuleWithProviders = RouterModule.forChild(routes);

 

7.  在Angular 2应用中,我们应该注意哪些安全威胁?

就像任何其他客户端或Web应用程序一样,Angular 2应用程序也应该遵循一些基本准则来减轻安全风险。其中一些是:

  1. 避免为你的组件使用/注入动态HTML内容。
  2. 如果使用外部HTML,也就是来自数据库或应用程序之外的地方,那么就需要清理它。
  3. 不要将外部网址放在应用程序中,除非它是受信任的。避免网址重定向,除非它是可信的。
  4. 考虑使用AOT编译或离线编译。
  5. 通过限制api,选择使用已知或安全环境/浏览器的app来防止XSRF攻击。

扩展阅读https://angular.io/docs/ts/latest/guide/security.HTML#!#best-practices

 

8.  如何优化Angular 2应用程序来获得更好的性能?

优化取决于应用程序的类型和大小以及许多其他因素。但一般来说,在优化Angular 2应用程序时,我会考虑以下几点:

  1. 考虑AOT编译。
  2. 确保应用程序已经经过了捆绑,uglify和tree shaking。
  3. 确保应用程序不存在不必要的import语句。
  4. 确保应用中已经移除了不使用的第三方库。
  5. 所有dependencies 和dev-dependencies都是明确分离的。
  6. 如果应用程序较大时,我会考虑延迟加载而不是完全捆绑的应用程序。

扩展阅读:

  1. https://medium.com/@areai51/the-4-stages-of-perf-tuning-for-your-angular2-app-922ce5c1b294#.pw4m2srmr
  2. https://www.lucidchart.com/techblog/2016/05/04/angular-2-best-practices-change-detector-performance/

 

9.  如何实现不出现编辑器警告的自定义类型?

在大多数的情况下,第三方库都带有它的.d.ts 文件,用于类型定义。在某些情况下,我们需要通过向现有类型提供一些更多的属性来扩展现有类型,或者如果我们需要定义其它类型以避免TypeScript警告。

如果我们需要扩展外部库的类型定义,一个好的做法是,我们并非对node_modules或现有的typings文件夹进行改动,而是创建一个命名为“自定义类型”的新文件夹,来存储所有的自定义类型。

要定义应用程序(JavaScript / Typescript)对象的类型,我们应该在应用程序相应模块的models文件夹中,定义接口和实体类。

对于这些情况,我们可以通过创建我们自己的“ .d.ts”文件来实现定义或扩展类型。

扩展阅读:

  1. https://www.typescriptlang.org/docs/handbook/declaration-merging.HTML
  2. https://typescript.codeplex.com/wikipage?title=Writing%20Definition%20%28.d.ts%29%20Files
  3. http://stackoverflow.com/questions/32948271/extend-interface-defined-in-d-ts-file

 

10. 什么是Shadow DOM?它如何帮助Angular 2更好地执行?

Shadow DOM是HTML规范的一部分,它允许开发人员封装自己的HTML标记,CSS样式和JavaScript。Shadow DOM以及其它一些技术,使开发人员能够像<audio>标签一样构建自己的一级标签,Web组件和API。总的来说,这些新的标签和API被称为Web组件。Shadow DOM通过提供了更好的关注分离,通过其它的HTML DOM元素实现了更少的样式与脚本的冲突。

因为shadow DOM本质上是静态的,同时也是开发人员无法访问的,所以它是一个很好的候选对象。因为它缓存的DOM将在浏览器中呈现得更快,并提供更好的性能。此外,还可以相对很好地管理shadow DOM,同时检测Angular 2应用的改变,并且可以有效地管理视图的重新绘制。

扩展阅读:

  1. https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM
  2. https://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/
  3. https://code.tutsplus.com/tutorials/intro-to-shadow-dom–net-34966

 

11. 什么是AOT编译?它有什么优缺点?

AOT编译代表的是Ahead Of Time编译,其中Angular编译器在构建时,会将Angular组件和模板编译为本机JavaScript和HTML。编译好的HTML和JavaScript将会部署到Web服务器,以便浏览器可以节省编译和渲染时间。

优点:

  1. 更快的下载:由于应用程序已经编译,许多Angular编译器相关库就不再需要捆绑,应用程序包变得更小,所以该应用程序可以更快地下载。
  2. 更少的Http请求数:如果应用程序没有捆绑来支持延迟加载(或任何原因),对于每个关联的HTML和CSS,都会有一个单独的服务器请求。但是预编译的应用程序会将所有模板和样式与组件对齐,因此到服务器的Http请求数量会更少。
  3. 更快的渲染:如果应用程序不是AOT编译,那么应用程序完全加载时,编译过程会发生在浏览器中。这需要等待下载所有必需的组件,然后等待编译器花费时间来编译应用程序。使用AOT编译,就能实现优化。
  4. 在构建时检测错误:由于预先编译,可以检测到许多编译时错误,能够为应用程序提供更好的稳定性。

缺点:

  1. 仅适用于HTML和CSS,其它文件类型需要前面的构建步骤
  2. 没有watch模式,必须手动完成(bin / ngc-watch.js)并编译所有文件
  3. 需要维护AOT版本的bootstrap文件(使用cli等工具时不需要)
  4. 在编译之前,需要清理步骤

扩展阅读https://angular.io/docs/ts/latest/cookbook/aot-compiler.HTML

 

12. Observables和Promises的核心区别是什么?

从堆栈溢出就是一个区别: 

当异步操作完成或失败时,Promise会处理一个单个事件。

Observable类似于(在许多语言中的)Stream,当每个事件调用回调函数时,允许传递零个或多个事件。通常Observable比Promise更受欢迎,因为它不但提供了Promise特性,还提供了其它特性。使用Observable可以处理0,1或多个事件。你可以在每种情况下使用相同的API。Observable是可取消的,这相比于Promise也具有优势。如果服务器的HTTP请求结果或其它一些异步操作不再需要,则Observable的订阅者可以取消订阅,而Promise将最终调用成功或失败的回调,即使你不需要通知或其提供的结果。Observable提供像map,forEach,reduce之类的类似于数组的运算符,还有强大的运算符,如retry()或replay()等,使用起来是相当方便的。

Promises vs Observables

  • Promises:
  1. 返回单个值
  2. 不可取消
  • Observables:
  1. 可以使用多个值
  2. 可取消
  3. 支持map,filter,reduce和类似的操作符
  4. ES 2016提议的功能
  5. 使用反应式扩展(RxJS)
  6. 根据时间的变化,数组成员可以异步获取

13、angular的数据绑定采用什么机制?详述原理

脏检查机制。

双向数据绑定是 AngularJS 的核心机制之一。当 view 中有任何数据变化时,会更新到 model ,当 model 中数据有变化时,view 也会同步更新,显然,这需要一个监控。

原理就是,Angular 在 scope 模型上设置了一个监听队列,用来监听数据变化并更新 view 。每次绑定一个东西到 view 上时 AngularJS 就会往 $watch 队列里插入一条 $watch ,用来检测它监视的 model 里是否有变化的东西。当浏览器接收到可以被 angular context 处理的事件时, $digest 循环就会触发,遍历所有的 $watch ,最后更新 dom。

14、AngularJS的数据双向绑定是怎么实现的?

1、每个双向绑定的元素都有一个watcher

2、在某些事件发生的时候,调用digest脏数据检测。

这些事件有:表单元素内容变化、Ajax请求响应、点击按钮执行的函数等。

3、脏数据检测会检测rootscope下所有被watcher的元素。

$digest函数就是脏数据监测

15、angularjs 是mvc还是mvvm框架

首先阐述下你对mvc和mvvm的理解

首先为什么我们会需要MVC?因为随着代码规模越来越大,切分职责是大势所趋,还有为了后期维护方便,修改一块功能不影响其他功能。还有为了复用,因为很多逻辑是一样的。而MVC只是手段,终极目标是模块化和复用。

mvvm的优点

低耦合:View可以独立于Model变化和修改,同一个ViewModel可以被多个View复用;并且可以做到View和Model的变化互不影响;

可重用性:可以把一些视图的逻辑放在ViewModel,让多个View复用;

独立开发:开发人员可以专注与业务逻辑和数据的开发(ViewModemvvmdi计人员可以专注于UI(View)的设计;

可测试性:清晰的View分层,使得针对表现层业务逻辑的测试更容易,更简单。

在angular中MVVM模式主要分为四部分:

View:它专注于界面的显示和渲染,在angular中则是包含一堆声明式Directive的视图模板。

ViewModel:它是View和Model的粘合体,负责View和Model的交互和协作,它负责给View提供显示的数据,以及提供了View中Command事件操作Model的途径;在angular中$scope对象充当了这个ViewModel的角色;

Model:它是与应用程序的业务逻辑相关的数据的封装载体,它是业务领域的对象,Model并不关心会被如何显示或操作,所以模型也不会包含任何界面显示相关的逻辑。在web页面中,大部分Model都是来自Ajax的服务端返回数据或者是全局的配置对象;而angular中的service则是封装和处理这些与Model相关的业务逻辑的场所,这类的业务服务是可以被多个Controller或者其他service复用的领域服务。

Controller:这并不是MVVM模式的核心元素,但它负责ViewModel对象的初始化,它将组合一个或者多个service来获取业务领域Model放在ViewModel对象上,使得应用界面在启动加载的时候达到一种可用的状态。

mvc的界面和逻辑关联紧密,数据直接从数据库读取。mvvm的界面与viewmode是松耦合,界面数据从viewmodel中获取。所以angularjs更倾向于mvvm

16、再写controlloer逻辑的时候 你需要注意什么?

1.简化代码(这个是所有开发人员都要具备的)

2.坚决不能操作dom节点 这个时候可能会问 为什么不能啊

你的回答是:DOM操作只能出现在指令(directive)中。最不应该出现的位置就是服务(service)中。Angular倡导以测试驱动开发,在service或者controller中出现了DOM操作,那么也就意味着的测试是无法通过的。当然,这只是一点,重要的是使用Angular的其中一个好处是啥,那就是双向数据绑定,这样就能专注于处理业务逻辑,无需关系一堆堆的DOM操作。如果在Angular的代码中还到处充斥着各种DOM操作,那为什么不直接使用jquery去开发呢。

测试驱动开发是什么呢?普及一下:

测试驱动开发,英文全称Test-Driven Development,简称TDD,是一种不同于传统软件开发流程的新型的开发方法。它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码,并加速开发过程。

17、controller之间怎么通讯

1、event

这里可以有两种方式,一种是$scope.$emit,然后通过监听$rootScope的事件获取参数;另一种是$rootScope.$broadcast,通过监听$scope的事件获取参数。

这两种方法在最新版本的Angular中已经没有性能区别了,主要就是事件发送的方向不同,可以按实际情况选择。

2、service

可以创建一个专用的事件Service,也可以按照业务逻辑切分,将数据存储在相应的Service

3、$rootScope

这个方法可能会比较dirty一点,胜在方便,也就是把数据存在$rootScope中,这样各个子$scope都可以调用,不过需要注意一下生命周期

4、直接使用$scope.$$nextSibling及类似的属性

类似的还有$scope.$parent。这个方法的缺点就更多了,官方不推荐使用任何$$开头的属性,既增加了耦合,又需要处理异步的问题,而且scope的顺序也不是固定的。不推荐

另外就是通过本地存储、全局变量或者现代浏览器的postMessage来传递参数了,除非特殊情况,请避免这类方式。

18、有哪些措施可以改善Angular 性能 
1、官方提倡的,关闭debug,$compileProvider

myApp.config(function ($compileProvider) {
  $compileProvider.debugInfoEnabled(false);
});

2、使用一次绑定表达式即{{::yourModel}} 
3、减少watcher数量 
4、在无限滚动加载中避免使用ng-repeat,关于解决方法可以参考这篇文章 
5、使用性能测试的小工具去挖掘你的angular性能问题,我们可以使用简单的console.time()也可以借助开发者工具以及Batarang

console.time("TimerName");
//your code
console.timeEnd("TimerName");

19、你认为在Angular中使用jQuery好么? 

这是一个开放性的问题,尽管网上会有很多这样的争论,但是普遍还是认为这并不是一个特别好的尝试。其实当我们学习Angular的时候,我们应该做到从0去接受angular的思想,数据绑定,使用angular自带的一些api,合理的路由组织和,写相关指令和服务等等。angular自带了很多api可以完全替代掉jquery中常用的api,我们可以使用angular.element,$http,$timeout,ng-init等。

我们不妨再换个角度,如果业务需求,而对于一个新人(比较熟悉jQuery)的话,或许你引入jQuery可以让它在解决问题,比如使用插件上有更多的选择,当然这是通过影响代码组织来提高工作效率,随着对于angular理解的深入,在重构时会逐渐摒弃掉当初引入jquery时的一些代码。

所以我觉得两种框架说完全不能一起用肯定是错的,但是我们还是应该尽力去遵循angular的设计。

20、angular和jquery的区别

angular是基于数据驱动,所以angular适合做数据操作比较繁琐的项目(这里可以再提一下单页面应用,如果你不会福利又来了 http://www.zhihu.com/question/20792064)

jquery是基于dom驱动,jquery适合做dom操作多的项目

21、对angular中的form表单了解多少

Angular对input元素的type进行了扩展,一共提供了以下10种类型:

text

number

url

email

radio

checkbox

hidden

button

submit

reset

Angular为表单内置了4中CSS样式。

ng-valid 校验合法状态

ng-invalid 校验非法状态

ng-pristine 如果要使用原生的form,需要设置这个值

ng-dirty     表单处于脏数据状态

Angular在对表单进行自动校验的时候会校验Model上的属性,如果不设置ng-model,则Angular无法知道myForm.$invalid这个值是否为真。

校验的一下内容

required 表示是否输入内容

ng-maxlength 最大长度

ng-minlength 最小长度

22、fliter是什么你了解的有多少?实现一个自定义fliter

ng 内置的 filter 有九种:

date(日期)

currency(货币)

limitTo(限制数组或字符串长度)

orderBy(排序)

lowercase(小写)

uppercase(大写)

number(格式化数字,加上千位分隔符,并接收参数限定小数点位数)

filter(处理一个数组,过滤出含有某个子串的元素)

json(格式化 json 对象)

23、表达式 {{yourModel}} 是如何工作的?

它依赖于 $interpolation服务,在初始化页面html后,它会找到这些表达式,并且进行标记,于是每遇见一个 {{}} ,则会设置一个 $watch 。而 $interpolation 会返回一个带有上下文参数的函数,最后该函数执行,则算是表达式 $parse 到那个作用域上。

24、列出至少三种实现不同模块之间通信方式?

  • Service
  • events,指定绑定的事件
  • 使用 $rootScope
  • controller之间直接使用$parent$$childHead
  • directive 指定属性进行数据绑定

25、什么是命令式编程,什么是声明式编程

jQuery的一个常见问题就是它是命令式编程,就意味着你要告诉计算机如何达成某项目的,其实你想要的就是程序运行的结果。而声明式编程则转移了重点,它只是告诉机器你想要的结果,让机器自己实现这个结果。javascript就是一种命令式语言,但HTML,和它指导的AngularJS就是声明式的,只需要告诉计算机你需要的展现形式,至于细节就由机器处理了。这样,完成一个任务的代码就大幅缩减了,代码质量也更高了。

26、两个平级界面块 a 和 b,如果 a 中触发一个事件,有哪些方式能让 b 知道?详述原理

这个问题换一种说法就是,如何在平级界面模块间进行通信。有两种方法,一种是共用服务,一种是基于事件。

共用服务

在 Angular 中,通过 factory 可以生成一个单例对象,在需要通信的模块 a 和 b 中注入这个对象即可。

基于事件

这个又分两种方式

第一种是借助父 controller。在子 controller 中向父 controller 触发($emit)一个事件,然后在父 controller 中监听($on)事件,再广播($broadcast)给子 controller ,这样通过事件携带的参数,实现了数据经过父 controller,在同级 controller 之间传播。

第二种是借助 $rootScope。每个 Angular 应用默认有一个根作用域 $rootScope, 根作用域位于最顶层,从它往下挂着各级作用域。所以,如果子控制器直接使用 $rootScope 广播和接收事件,那么就可实现同级之间的通信。

为您推荐

发表评论

电子邮件地址不会被公开。

4条评论

  1. I can’t get through at the moment http://9taxi.in.net/ 9 taxi B-movie legend Bruce Campbell, who plays Wes­ten’s best friend, said he wasn’t so sentimental, noting everything comes to an end. Still, despite his status as a horror icon thanks to the “Evil Dead” trilogy and other films, Campbell considers “Burn Notice” the most successful project he’s ever been part of.

  2. very best job http://xnxx.promo/ xnxx .com We turned and started swimming. The jagged assortment of buildings that made up the San Francisco skyline seemed so far away from our low vantage point. I could feel the cold water ripping across my face and hands.

  3. I’d like to send this to http://xnxx.in.net/ xnxx The 43-square-mile fire above Palm Springs was 68 percent contained. It didn’t move overnight and crews were concentrating Monday on surrounding it on ridges thousands of feet up in the San Jacinto Mountains, U.S. Forest Service spokesman Lee Beyer said.