前端面试答案整理之js

来源:互联网 发布:思维脑图软件 编辑:程序博客网 时间:2024/05/01 19:17
  • 介绍JavaScript的基本数据类型。
    string number boolean null undefined
  • 说说写JavaScript的基本规范?
    1.一般将 html 代码和 js 代码分离,也就是将 js 代码全部写到一个独立的以 *.js 的文件中,再通过引入外部js 的方式引入到页面中
    2.注意换行和缩进
    3.注释简单明了。
    4.命名规范,第一个字符必须是字母或下划线(_)或美元符号($),其它字符可以是字母或下划线或美元符号或数字;个人常用camelCase命名法
    5.使用var声明变量。
  • JavaScript原型,原型链 ? 有什么特点?
    js每个对象都会在内部初始化一个prototype属性,当访问对象的某一属性时,优先查找对象是否有该属性,不存在时去原型里面找,prototype又有prototype,就这样一直找下去,这就是所谓的原型链的概念。
    特点:js对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。
  • JavaScript有几种类型的值?画一下他们的内存图?
    包括原始数据类型和引用数据类型。
    堆栈内存图
  • Javascript如何实现继承?
    js中的继承主要是通过原型链来实现的。
    1.原型链继承:主要方法是将父类的实例作为子类的原型,这样就实现了子类继承父类。
// 父类function Animal (name) {  this.name = name || 'Animal';  this.sleep = function(){    alert(this.name + '正在睡觉!');  }}Animal.prototype.eat = function(food) {  alert(this.name + '正在吃:' + food);};//子类function Cat(){}Cat.prototype = new Animal();//注意:要想为子类新增属性和方法,必须要在new之后执行,不能放到构造器中Cat.prototype.name = 'cat';

优点:非常纯粹的继承关系,实例是子类的实例,也是父类的实例;
父类新增原型方法/原型属性,子类都能访问到;
简单,易于实现。
缺点:所有实例共享父类属性。
创建子类实例时,无法向父类构造函数传参。
2.借用构造函数实现继承:主要实现方法是在子类构造函数内部调用父类的构造函数。

//父类function Animal(name){      this.name = name;}//子类function Cat(){    Animal.call(this,'cat');}

优点:创建子类实例时,可以向父类构造函数传参。
可以实现多继承(call多个父类对象)。
缺点:实例并不是父类的实例,只是子类的实例
只能继承父类的实例属性和方法,不能继承原型属性/方法
3.组合继承:使用原型链实现对原型属性和方法的继承,使用构造函数实现对实例属性和方法的继承。

// 父类function Animal (name) {  this.name = name || 'Animal';  this.sleep = function(){    alert(this.name + '正在睡觉!');  }}Animal.prototype.eat = function(food) {  alert(this.name + '正在吃:' + food);};//子类function Cat(){    Animal.call(this,'cat');}Cat.prototype = new Animal();

优点:可以继承实例属性/方法,也可以继承原型属性/方法
可传参
函数可复用
缺点:调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)
- Javascript创建对象的几种方式?
1.工厂模式

function person(name, age, job){    var obj = new Object();    obj.name = name;    obj.age = age;    obj.job = job;    obj.sayName = function(){        alert(this.name);    }    return obj;}var person1 = person('josh', 24, 'FE');

2.构造函数模式

function Person(name, age, job){    this.name = name;    this.age = age;    this.job = job;    this.sayName = function(){        alert(this.name);    }}var person1 = new Person('josh', 24, 'FE');

3.原型模式

function Person() {}Person.prototype = {    'name': 'josh',    'age': 24,    'job': 'FE',    'sayName': function(){        alert(this.name);    }}var person1 = new Person();

构造函数+原型模式

function Person(name, age, job){    this.name = name;    this.age = age;    this.job = job;}Person.prototype.sayName = function(){    alert(this.name)}var person1 = new Person('josh', 24, 'FE');
  • Javascript作用域?
    作用域就是变量和函数的可访问范围,决定着变量的可见性和生命周期。js中不存在块级作用域的概念,只有全局作用域和局部作用域。
    变量不在函数中声明或者是声明的时候不带var,那么就拥有全局作用域。
    变量在函数体中用var声明,就是局部作用域,变量只在函数内部及其子函数内可见。另外注意的是,传入函数的参数也是局部变量。

  • 谈谈This对象的理解。
    this一般是谁调用指向谁
    1.单纯的函数全局调用时,this指的是window对象
    2.作为对象的方法调用时,this指的是该对象
    3.call和apply调用时,this指的是call和apply的第一个参数
    4.作为构造函数调用时,this指的是由构造函数产生的新对象。

  • null,undefined的区别?
    null表示没有对象,此处不应该有值。典型的用法包括:作为函数的参数,表示该函数的参数不是对象;作为对象原型链的终点
    undefined表示缺省值,即应该有一个值,但是没有定义。典型用法:变量声明未赋值;函数应该有参数未提供;函数没有返回值;对象的属性未赋值。

  • 写一个通用的事件侦听器函数(机试题)。

var EventUtil = {    getEvent: function(e){        return e ? e : window.e;    },    getTarget: function(e){        return e.target || e.srcElement;    },    preventDefault: function(e){        if (e.preventDefault) {            e.preventDefault();        }else {            e.returnValue = false;        }    },    stopPropagation: function(e){        if (e.stopPropagation) {            e.stopPropagation();        }else {            e.cancelBubble = true;        }    },    addHandler: function (ele,type,handler) {        if (ele.addEventListener) {            ele.addEventListener(type,handler,false);        }else if (ele.attachEvent) {            ele.attachEvent('on' + type, handler)        }else{            ele['on' + type] = handler;        }    },    removeHandler: function(e,type,handler){        if (ele.removeEventListener) {            ele.removeEventListener(type,handler,false)        }else if (ele.detachEvent) {            ele.detachEvent('on' + type,handler)        }else{            ele['on' + type] = null;        }    }}
  • [“1”, “2”, “3”].map(parseInt) 答案是多少?
    [1,NaN,NaN]

  • 什么是闭包(closure),为什么要用它?
    闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。
    闭包的特性:1.函数内再嵌套函数2.内部函数可以引用外层的参数和变量3.参数和变量不会被垃圾回收机制回收

  • 如何判断一个对象是否属于某个类?
    1.Object.prototype.toString.call() 2.instanceof
  • new操作符具体干了什么呢?
    1.首先创建一个空对象 2.构造函数中的this指向该对象 3.在构造函数中通过this为该对象设置属性 4. 返回经过处理的对象

  • js延迟加载的方式有哪些?
    1.将js文件放在body里面引入,这样就会在页面加载完成之后再加载js文件。
    2.使用script标签的defer和async属性,都不会阻塞页面的加载,但是defer是在页面加载的同时加载,但是等到页面加载完成之后再执行;async是页面加载的时候同时加载,js文件加载完之后立即执行
    3.通过监听onload事件,动态添加script节点。

  • Ajax 是什么? 如何创建一个Ajax?
    Ajax是指在不重新加载整个页面的情况下,与服务器进行通信并更新部分网页的技术
    Ajax的核心是XMLHttpRequest对象。
    1.创建一个XHR对象
    2.启动一个请求以备发送,xhr.open(method,url,aync)
    3.发送请求,xhr.send()
  • 如何解决跨域问题?
    1.jsonp,利用script标签可以跨域的特点实现。jsonp主要包括2部分:回调函数和数据。回调函数指的是当响应到来时应该在页面调用的函数,数据是指传入回调函数的参数。
<script type="text/javascript">    function dosomething(jsondata){    }</script><script src="http://example.com/data.php?callback=dosomething"></script>

优点:兼容性好
缺点:只支持get请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题
2.window.name。
在一个窗口的生命周期中,所以的页面共享window.name属性。每个页面对window.name都有读写权限
3.通过修改document.domain来跨子域。
对于相同主域名不同子域名下的页面,可以设置document.domain让它们同域
4.webSocket
本质上是一种持久化的socket连接,在浏览器客户端利用js实现初始化连接之后,就可以监听相关事件并且调用socket方法对服务器响应的消息进行读写操作。

  • 模块化开发怎么做?
    模块就是实现特定功能的一组方法,我目前常用的是把一个模块写成一个对象,所有的模块成员都放在这个对象里面,调用的时候就是使用这个对象的某一属性。
    js模块规范总共2种:commonJS 和AMD;
    coommonJS:一个文件就是一个单独的模块,每一个模块就是单独的作用域,模块只有一个出口,module.exports对象。里面主要用require加载模块。
var math = require('math');

AMD(Asynchronous Modules Definition):异步加载模块。也采用require()加载模块,但是不同于commonJS

require([module], callback);eg:require(['math'], function (math) {   math.add(2, 3);});

CMD(通用模块定义)

// 定义模块  myModule.jsdefine(function(require, exports, module) {  var $ = require('jquery.js')  $('div').addClass('active');});// 加载模块seajs.use(['myModule.js'], function(my){});

CMD与AMD的区别:
1.CMD推崇就近依赖,什么时候需要什么时候requrie
2.AMD推崇前置依赖,被依赖的模块放在前面require
同样都是异步加载模块,AMD在加载模块完成后就会执载行该模块,所有模块都执行完后会进入require的回调函数,执行主逻辑,这样的效果就是依赖模块的执行顺序和书写顺序不一定一致,看网络速度,哪个先下载下来,哪个先执行,但是主逻辑一定在所有依赖加载完成后才执行;CMD加载完某个依赖模块后并不执行,只是下载而已,在所有依赖模块加载完成后进入主逻辑,遇到require语句的时候才执行对应的模块,这样模块的执行顺序和书写顺序是完全一致的

1 0
原创粉丝点击