前端经典面试题---JS篇

来源:互联网 发布:360域名举报 编辑:程序博客网 时间:2024/05/16 23:56

      • null与undefined的区别
      • 对this对象的理解
      • 闭包
      • IE和DOM事件流的区别
      • 兼容事件处理程序
      • 如何阻止事件冒泡和默认事件
      • HTML5为什么只需要写 DOCTYPE HTML
      • link和import有什么区别
      • 介绍一下你对浏览器内核的理解
      • JS阻塞与CSS阻塞
      • NodeJS与JavaScript的区别
      • JavaScript如何实现继承


null与undefined的区别

null是一个表示”无”的对象,转为数值时为0;即该处不应该有值。典型用法是:

  • 作为函数的参数,表示该函数的参数不是对象。
  • 作为对象原型链的终点。

undefined是一个表示”无”的原始值,转为数值时为NaN;表示”缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是:

  • 变量被声明了,但没有赋值时,就等于undefined。
  • 调用函数时,应该提供的参数没有提供,该参数等于undefined。
  • 对象没有赋值的属性,该属性的值为undefined。
  • 函数没有返回值时,默认返回undefined。

对this对象的理解

this是js的一个关键字,随着函数使用场合不同,this的值会发生变化。this指的是调用当前函数的那个对象。

this一般情况下:是全局对象Global。 作为方法调用,那么this就是指这个对象


闭包

含义:函数嵌套函数,内部函数可以引用外部函数的参数和变量,变量和参数不会被垃圾回收机制所回收。

特点:

  • 变量可以长期驻扎在内存之中
  • 避免全局变量的污染
  • 存在私有成员

注意:可能会造成内存泄漏


IE和DOM事件流的区别

  1. 执行顺序不一样
  2. 参数不一样
  3. 事件加不加on
  4. this指向问题

兼容事件处理程序

//绑定事件function(obj,type,handler){    if(obj.addEventListener){        obj.addEventListener(type,handler,false)    }else if(obj.attachEvent){        obj.attachEvent("on"+type,function(){handler.call(obj);})    }else{        obj["on"+type]=handler    }}//删除事件function(obj,type,handler){    if(obj.removeEventListener){        obj.removeEventListener(type,handler,false)    }else if(obj.detachEvent){        obj.detachEvent("on"+type,function(){handler.call(obj);})    }else{        obj["on"+type]=null;    }}

如何阻止事件冒泡和默认事件

//阻止冒泡function stopBubble(e){    if (e && e.stopPropagation){        e.stopPropagation()    }else{        window.event.cancelBubble=true    }    return false}
//阻止浏览器的默认行为 function stopDefault( e ) {     if ( e && e.preventDefault ){         e.preventDefault();     }else{        window.event.returnValue = false;    }     return false; }

HTML5为什么只需要写 <!DOCTYPE HTML>

  • HTML5不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照它们应该的方式来运行)。

  • 而HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。


link和@import有什么区别

  1. link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS;
  2. 页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;
  3. import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题。

介绍一下你对浏览器内核的理解

主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。

渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。

JS引擎:解析和执行javascript来实现网页的动态效果。

最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。


JS阻塞与CSS阻塞

JS阻塞特性:由于浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以在下载JS的时候浏览器会阻止其它一切活动,比如其它资源的下载,内容的呈现等。直到JS下载、解析、执行完毕之后才开始继续并行下载其它资源并呈现内容。为了提高用户体验,新一代浏览器都支持并行下载JS,但是JS下载仍然会阻塞其它资源的下载(例如:图片,css文件等)。

嵌入 JS 会阻塞所有内容的呈现,而外部 JS 只会阻塞其后内容的显示,2 种方式都会阻塞其后资源的下载。

解决方法:

  • 推迟加载:script标签放在</body>
  • 异步加载:HTML5允许我们给 script 标签添加属性: “async” 来告诉浏览器不必停下来等待该脚本执行,什么时候下载完什么时候执行该脚本就可以了。由于使用异步加载后,JS不再顺序执行,如果某个JS被其他JS所依赖,那么就不能使用异步加载了。

CSS 本来是可以并行下载的,在什么情况下会出现阻塞加载了(在测试观察中,IE6 下 CSS 都是阻塞加载),当 CSS 后面跟着嵌入的 JS 的时候,该 CSS 就会出现阻塞后面资源下载的情况。而当把嵌入 JS 放到 CSS 前面,就不会出现阻塞的情况了。

根本原因:因为浏览器会维持 HTML 中 CSS 和 JS 的顺序,样式表必须在嵌入的 JS 执行前先加载、解析完。而嵌入的 JS 会阻塞后面的资源加载,所以就会出现上面 CSS 阻塞下载的情况。

另外,可以将那些页面首屏渲染需要用到的CSS代码加入Inline CSS;首屏渲染不需要用到的CSS,使用文件形式并在页面内容渲染完成后再加载。


NodeJS与JavaScript的区别?

JavaScrip由三部分组成:

  • ECMAScript:定义了语法、数据类型、结构及内置的对象。
  • DOM:扩展出来一些操作页面的方法
  • BOM:扩展出来一些操作浏览器的方法
    属于前端部分。

NodeJS 以ECMAScript为基础,可以操作文件系统、操作系统、网络、数据库的方法。属于后端。

JavaScript如何实现继承

原型继承、构造继承、实例继承、拷贝继承

1.原型链

利用原型让一个引用类型继承另外一个引用类型的属性和方法。

//原型链function SuperType() {    this.property = true;}SuperType.prototype.getSuperValue = function() {    return this.property;}function subType() {    this.property = false;}//继承SuperTypeSubType.prototype = new SuperType();SubType.prototype.getSubValue = function (){    return this.property;}var instance = new SubType();console.log(instance.getSuperValue());//true

2.构造继承

在子类型构造函数的内部调用超类构造函数,通过使用call()和apply()方法可以在新创建的对象上执行构造函数。

function SuperType() {    this.colors = ["red","blue","green"];}function SubType() {    SuperType.call(this);//继承了SuperType}var instance1 = new SubType();instance1.colors.push("black");console.log(instance1.colors);//"red","blue","green","black"var instance2 = new SubType();console.log(instance2.colors);//"red","blue","green"

3.组合继承

将原型链和借用构造函数的技术组合在一块,从而发挥两者之长的一种继承模式。

function SuperType(name) {    this.name = name;    this.colors = ["red","blue","green"];}SuperType.prototype.sayName = function() {    console.log(this.name);}function SubType(name, age) {    SuperType.call(this,name);//继承属性    this.age = age;}//继承方法SubType.prototype = new SuperType();Subtype.prototype.constructor = Subtype;Subtype.prototype.sayAge = function() {    console.log(this.age);}var instance1 = new SubType("EvanChen",18);instance1.colors.push("black");consol.log(instance1.colors);//"red","blue","green","black"instance1.sayName();//"EvanChen"instance1.sayAge();//18var instance2 = new SubType("EvanChen666",20);console.log(instance2.colors);//"red","blue","green"instance2.sayName();//"EvanChen666"instance2.sayAge();//20

4.原型式继承

借助原型可以基于已有的对象创建新对象,同时还不必须因此创建自定义的类型。

var person = {    name:"EvanChen",    friends:["Shelby","Court","Van"];};var anotherPerson = Object.create(person);anotherPerson.name = "Greg";anotherPerson.friends.push("Rob");var yetAnotherPerson = Object.create(person);yetAnotherPerson.name = "Linda";yetAnotherPerson.friends.push("Barbie");console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"

5.寄生组合继承(最佳方式)

对组合继承的优化

function inheritProperty(subType, superType) {    var prototype = object(superType.prototype);//创建对象    prototype.constructor = subType;//增强对象    subType.prototype = prototype;//指定对象}function SuperType(name){    this.name = name;    this.colors = ["red","blue","green"];}SuperType.prototype.sayName = function (){    alert(this.name);};function SubType(name,age){    SuperType.call(this,name);    this.age = age;}inheritProperty(SubType,SuperType);SubType.prototype.sayAge = function() {    alert(this.age);}
原创粉丝点击