Angular面试题_session面试题

Angular面试题_session面试题二十、angular的缺点有哪些?1.强约束导致学习成本较高,对前端不友好。但遵守AngularJS的约定时,生产力会很高,对Java程序员友好。2.不利于SEO因为所有内容都是动态获取并渲染生成的,搜索引擎没法爬取。一种解决办法是,对于正常用户的访问,服务器响应AngularJS应用的内容;对于搜索引擎的访问,则响应专门针对SEO…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

二十、angular 的缺点有哪些?

1.强约束

导致学习成本较高,对前端不友好。

但遵守 AngularJS 的约定时,生产力会很高,对 Java 程序员友好。

2.不利于 SEO

因为所有内容都是动态获取并渲染生成的,搜索引擎没法爬取。

一种解决办法是,对于正常用户的访问,服务器响应 AngularJS 应用的内容;对于            搜索引擎的访问,则响应专门针对 SEO 的HTML页面。

3..性能问题

作为 MVVM 框架,因为实现了数据的双向绑定,对于大数组、复杂对象会存在性            能问题。

可以用来 优化 Angular 应用的性能 的办法:

减少监控项(比如对不会变化的数据采用单向绑定)

主动设置索引(指定 track by ,简单类型默认用自身当索引,对象默认使用                       $$hashKey ,比如改为 track by item.id )

降低渲染数据量(比如分页,或者每次取一小部分数据,根据需要再取)

数据扁平化(比如对于树状结构,使用扁平化结构,构建一个 map 和树状数据,      对树操作时,由于跟扁平数据同一引用,树状数据变更会同步到原始的扁平数据)

另外,对于Angular1.x ,存在 脏检查 和 模块机制 的问题。

4.移动端

可尝试 Ionic,但并不完善。

参考 如何看2015年1月Peter-Paul Koch对Angular的看法?

如何看待 angular 1.2 中引入的 controller as 语法?

5.最根本的好处

在 angular 1.2 以前,在 view 上的任何绑定都是直接绑定在 $scope 上的

function myCtrl($scope){

  $scope.a = ‘aaa’;

  $scope.foo = function(){

    …

  }

}

使用 controllerAs,不需要再注入 $scope ,controller 变成了一个很简单的 javascript 对象(POJO),一个更纯粹的 ViewModel。

function myCtrl(){

  // 使用 vm 捕获 this 可避免内部的函数在使用 this 时导致上下文改变

  var vm = this;

  vm.a = ‘aaa’;

}

原理

从源码实现上来看,controllerAs 语法只是把 controller 这个对象的实例用 as 别名在 $scope 上创建了一个属性。

if (directive.controllerAs) {

  locals.$scope[directive.controllerAs] = controllerInstance;

}<br>

但是这样做,除了上面提到的使 controller 更加 POJO 外,还可以避免遇到 AngularJS 作用域相关的一个坑(就是上文中 ng-if 产生一级作用域的坑,其实也是 javascript 原型链继承中值类型继承的坑。因为使用 controllerAs 的话 view 上所有字段都绑定在一个引用的属性上,比如 vm.xx,所以坑不再存在)。

<div ng-controller=”TestCtrl as vm”>

<p>{
{name}}</p>

<div ng-if=”vm.name”>

<input type=”text” ng-model=”vm.name”>

</div>

</div>

 

问题

使用 controllerAs 会遇到的一个问题是,因为没有注入 $scope ,导致 $emit 、 $broadcast 、 $on 、 $watch 等 $scope 下的方法无法使用。这些跟事件相关的操作可以封装起来统一处理,或者在单个 controller 中引入 $scope ,特殊对待。

 

栗子

依赖注入是一种软件设计模式,目的是处理代码之间的依赖关系,减少组件间的耦合。

举个栗子,如果没有使用 AngularJS,想从后台查询数据并在前端显示,可能需要这样做:

var animalBox = document.querySelector(‘.animal-box’);

 

var httpRequest = {

  get: function(url, callback){

    console.log(url + ‘ requested’);

    var animals = [‘cat’, ‘dog’, ‘rabbit’];

    callback(animals);

  }

}

 

var render = function(el, http){

  http.get(‘/api/animals’, function(animals){

    el.innerHTML = animals;

  })

}

 

render(httpRequest, animalBox);

但是,如果在调用 render 的时候不传参数,像下面这样,会报错,因为找不到 el 和 http(定义的时候依赖了,运行的时候不会自动查找依赖项)

render();

// TypeError: Cannot read property ‘get’ of undefined

而使用 AngularJS,可以直接这样

function myCtrl = ($scope, $http){

  $http.get(‘/api/animals’).success(function(data){

    $scope.animals = data;

  })

}

也就是说,在 Angular App 运行的时候,调用 myCtrl,自动做了 $scope 和 $http 两个依赖性的注入。

 

原理

AngularJS 是通过构造函数的参数名字来推断依赖服务名称的,通过 toString() 来找到这个定义的 function 对应的字符串,然后用正则解析出其中的参数(依赖项),再去依赖映射中取到对应的依赖,实例化之后传入。

简化一下,大概是这样:

var inject = {

  // 存储依赖映射关系

  storage: {}, 

  // 注册依赖

  register: function(name, resource){

    this.storage[name] = resource;

  },

  // 解析出依赖并调用

  resolve: function(target){

    var self = this;

    var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;

    var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;

    fnText = target.toString().replace(STRIP_COMMENTS, ”);

    argDecl = fnText.match(FN_ARGS)[1].split(/, ?/g);

 

    var args = [];

    argDecl.forEach(function(arg){

      if(self.storage[arg]){

        args.push(self.storage[arg]);

      }

    })

 

    return function(){

      target.apply({}, args);

    }

  }

}

 //使用这个 injector,前面那个不用 AngularJS 的栗子这样改造一下就可以调用了

inject.register(‘el’, animalBox);

inject.register(‘ajax’, httpRequest);

render = inject.resolve(render);

render();

 

 

问题

因为 AngularJS 的 injector 是假设函数的参数名就是依赖的名字,然后去查找依赖项,那如果按前面栗子中那样注入依赖,代码压缩后(参数被重命名了),就无法查找到依赖项了。

// 压缩前

function myCtrl = ($scope, $http){

  …

}

 

// 压缩后

function myCtrl = (a, b){

  …

}

所以,通常会使用下面两种方式注入依赖(对依赖添加的顺序有要求)。

// 数组注释法

myApp.controller(‘myCtrl’, [‘$scope’, ‘$http’, function($scope, $http){

  …

}])

//显式 $inject

myApp.controller(‘myCtrl’, myCtrl);

function myCtrl = ($scope, $http){

  …

}

myCtrl.$inject = [‘$scope’, ‘$http’];

补充

对于一个 DI 容器,必须具备三个要素:依赖项的注册,依赖关系的声明和对象的获取。

在 AngularJS 中,module 和 $provide 都可以提供依赖项的注册;内置的 injector 可以获取对象(自动完成依赖注入);依赖关系的声明,就是前面问题中提到的那样。

下面是个栗子

// 对于 module,传递参数不止一个,代表新建模块,空数组代表不依赖其他模块

// 只有一个参数(模块名),代表获取模块

 

// 定义 myApp,添加 myApp.services 为其依赖项

angular.module(‘myApp’, [‘myApp.services’]);

// 定义一个 services module,将 services 都注册在这个 module 下面

angular.module(‘myApp.services’, [])

 

// $provider factory, service, provider, value, constant

// 定义一个 HttpService

angular.module(‘myApp.services’).service(‘HttpService’, [‘$http’, function($http){

  …

}])

 

二十一、 compile和link的区别: 看到一个比较6的答案。性能力(性能和能力)

编译的时候,compile转换dom,碰到绑定监听器的地方就先存着,有几个存几个,到最后汇总成一个link函数,一并执行,提升了性能。

function compile(tElement, tAttrs, transclude) { … }tElement为编译前的element

function link(scope, iElement, iAttrs, controller) { … }  iElement为编译后的element,已经与作用域关联起来,所以可以数据绑定

如果指令只进行DOM的修改,不进行数据绑定,那么配置在compile函数中,如果指令要进行数据绑定,那么配置在link函数中。

 

二十二、. $apply()和 $digest()的区别

安全性:$apply()可以接收一个参数作为function(),这个 function 会被包装到一个 try … catch 块中,所以一旦有异常发生,该异常会被 $exceptionHandler service 处理。

$apply会使ng进入 $digest cycle , 并从$rootScope开始遍历(深度优先)检查数据变更。

$digest仅会检查该scope和它的子scope,当你确定当前操作仅影响它们时,用$digest可以稍微提升性能。

 

转载于:https://www.cnblogs.com/ndos/p/8331693.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/180910.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • web网站常见攻击及防范

    web网站常见攻击及防范一个网站建立以后,如果不注意安全方面的问题,很容易被人攻击,下面就讨论一下几种漏洞情况和防止攻击的办法.一.SQL注入所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的

  • 联想笔记本键盘亮屏幕不亮_笔记本电脑进入睡眠状态后无法通过鼠标或键盘来唤醒屏幕怎么解决…「建议收藏」

    联想笔记本键盘亮屏幕不亮_笔记本电脑进入睡眠状态后无法通过鼠标或键盘来唤醒屏幕怎么解决…「建议收藏」‍通常情况下,我们如果有一段时间没有使用笔记本电脑,那么笔记本会自动进入睡眠状态。有用户发现笔记本电脑进入睡眠状态后无法通过鼠标或键盘来唤醒屏幕,那么应该怎么解决这个问题呢?大家可以参考下面提供的方法看看能否解决。1、如果遇到睡眠不能唤醒的问题,可以点击笔记本上的电源按钮,有的机型是通过点击电源按钮来唤醒的;2、如果点开机键还是不能解决,可以查看硬盘指示灯,在睡眠状态下,硬盘灯是闪烁的;3、如果硬…

  • Okio原理分析之简介

    Okio原理分析之简介Okio是一个实现java.io和java.nio的库,更方便访问、存储和处理数据。作为OkHttp组件的一部分,在Android中引入支持HTTP的客户端Okio一些关键概念介绍先看一下类图,对整体框架有个大概的了解ByteString和Buffer保存数据ByteString代表一个不可变的字节序列。对于char数据,String是基础类型。Buffer可变的字节序列,像ArrayList,读写Buffer的操作与queue类似,从尾部写,从头部读,不需要管理position/limi

  • Hybrid App 开发快速指南[通俗易懂]

    Hybrid App 开发快速指南[通俗易懂]课程背景混合应用相对于原生应用而言,是原生应用和Web应用的结合体。过去几年,混合应用开发的各种利弊已得到充分的讨论和验证。关于混合应用是什么、为什么使用的问题,相信大家都有自己的答案,但如何开发混合应用,从现有资料中却很难找到一个系统、全面的回答。刚上手或准备上手混合应用的开发者,经常苦于没有一套经过验证的最佳实践来指导开发,在开发的各个阶段往往遇到各种问题:如何选型?如何架构前端…

  • 序列化和反序列化的底层实现原理是什么?

    序列化和反序列化的底层实现原理是什么?序列化和反序列化作为Java里一个较为基础的知识点,大家心里也有那么几句要说的,但我相信很多小伙伴掌握的也就是那么几句而已,如果再深究问一下Java如何实现序列化和反序列化的,就可能不知所措了!遥记当年也被问了这一个问题,自信满满的说了一大堆,什么是序列化、什么是反序列化、什么场景的时候才会用到等,然后面试官说:那你能说一下序列化和反序列化底层是如何实现的吗?一脸懵逼,然后回家等通知!一、…

  • 5分钟商学院之个人篇–情感和创新

    1.情感能力情商的5个基础元能力:同理心、自我认知、自我控制、自我激励和人际关系处理1.1同理心从别人的情感出发,站在别人的角度看待问题怎样才能训练同理心?指路玩杀人游戏1.2自我

    2021年12月30日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号