【前端面试】js基础

 

目录

 

js的基本类型有哪些?引用类型有哪些?

如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)

JS常见的dom操作api

解释一下事件冒泡和事件捕获,如何阻止冒泡?如何阻止默认事件?

事件委托(手写例子)

对闭包的理解?什么时候构成闭包?闭包的实现方法?闭包的优缺点?

this有哪些使用场景?跟C,Java中的this有什么区别?如何改变this的值?

call,apply,bind

显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链

创建对象的多种方式

实现继承的多种方式和优缺点

new 一个对象具体做了什么

手写Ajax,XMLHttpRequest

变量提升

举例说明一个匿名函数的典型用例

document load和document DOMContentLoaded两个事件的区别

typeof能够得到哪些值

函数的作用域是什么?js 的作用域有几种?

JS如何实现重载和多态

原生事件绑定(跨浏览器),dom0和dom2的区别?


  • js的基本类型有哪些?引用类型有哪些?

基本类型:Undefined(声明没有初始化)、Null(没有声明,不存在)、String、Number、Boolean  (变量存放在栈区)

引用类型:object、Array、RegExp(正则表达式)、Date、Function、特殊的基本包装类型(String、Number、Boolean)以及单体内置对象(Global、Math)。(同时保存在栈内存和堆内存)

区别联系:引用类型可以添加属性和方法; 在复制变量值时,基本类型会在变量对象上创建一个新值,再复制给新变量。此后,两个变量的任何操作都不会影响到对方;而引用类型是将存储在变量对象的值复制一份给新变量,但是两个变量的值都指向存储在堆中的一个对象,也就是说,其实他们引用了同一个对象,改变其中一个变量就会影响到另一个变量。

  • 如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)

typeof可以判断 number   string    boolean   undefined,对于[ ]、null、{ }输出都为object,所以要判断array不能使用typeof;

Object.prototype.toString.call 这是object原生原型的一个扩展函数,可以精确对象类型例如Object.prototype.toString.call('[ ]')输出就是[object Array];   Object.prototype.toString.call('{ }')输出是[object Object]

constructor也可以判断数据类型,[].constructor输出就是Array

  • JS常见的dom操作api

节点查找:document.getElementById(根据id查找元素,大小写敏感) 、document.getElementsByTagName (根据标签查找元素,*表示查询所有标签,返回一个HTMLCollection)、document.getElementsByName(根据元素的name属性查找)、document.getElementsByClassName(根据类名查找)、document.querySelector(返回单个Node,如果匹配到多个结果,返回第一个)、document.querySelectorAll(返回一个NodeList) 、document.forms(获取当前页面所有的form)等

节点创建:   createElement (通过 createElement 创建的元素并不属于 document 对象,它只是创建出来,并未添加到html文档中,要调用 appendChild 或 insertBefore 等方法将其添加到HTML文档中)、 createTextNode 、 cloneNode(接收一个bool参数,用来表示是否复制子元素) 和 createDocumentFragment (创建一个 DocumentFragment ,也就是文档碎片,它表示一种轻量级的文档,主要是用来存储临时节点,大量操作DOM时用它可以大大提升性能)

节点修改:appendChild 、insertBefore 、removeChild 、replaceChild

节点关系:parentNode 、children 、childNodes 、firstChild  、lastChild 、previousSibling、nextSibling 、 nextElementSibling

元素属性:setAttribute、getAttribute

元素样式:window.getComputedStyle(通过 element.sytle.xxx 只能获取到内联样式,借助 window.getComputedStyle 可以获取应用到元素上的所有样式,IE8或更低版本不支持此方法。)、getBoundingClientRect(用来返回元素的大小以及相对于浏览器可视窗口的位置)

  • 解释一下事件冒泡和事件捕获,如何阻止冒泡?如何阻止默认事件?

事件冒泡:从事件的目标开始往上冒泡,直到页面的最上一级标签;通俗来讲就是,就是当设定了多个div的嵌套时;即建立了父子关系,当父div与子div共同加入了onclick事件时,当触发了子div的onclick事件后,子div进行相应的js操作,但是父div的onclick事件同样会被触发。 可以通过event.stopPropagation();方法阻止时间冒泡。

事件捕获:从最上一级开始往下查找,直到捕获到事件目标

程序员可以自己选择绑定事件时采用事件捕获还是事件冒泡,方法就是绑定事件时通过addEventListener函数,它有三个参数,第三个参数若是true,则表示采用事件捕获,若是false,则表示采用事件冒泡。例:

ele.addEventListener('click',doSomething2,true)     //true=捕获     false=冒泡

  • 事件委托(手写例子)

事件委托:利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

优点:在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因;如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;

例:

  • 111
  • 222
  • 333
  • 444
window.onload = function(){   var oUl = document.getElementById("ul1");   oUl.onclick = function(ev){     var ev = ev || window.event;     var target = ev.target || ev.srcElement;     if(target.nodeName.toLowerCase() == 'li'){          alert(123);         alert(target.innerHTML);     }   } }
  • 对闭包的理解?什么时候构成闭包?闭包的实现方法?闭包的优缺点?

闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在;

在函数内部定义一个函数就会产生闭包。

闭包的最大用处有两个,一个是读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

  • this有哪些使用场景?跟C,Java中的this有什么区别?如何改变this的值?

作为对象方法调用(this绑定到当前对象)、

作为函数调用(函数可以直接被调用,此时 this 绑定到全局对象;但是正确的设计方式是内部函数的 this 应该绑定到其外层函数对应的对象上,为了规避这一设计缺陷,出现了变量替代的方法,约定俗成,该变量一般被命名为 that)、

作为构造函数调用(构造函数实际上是为了支持面向对象编程,要使用new调用,否则跟普通函数一样)

  • call,apply,bind

call()和apply()这两个方法第一个参数都为this指针指向的目标对象,它们的区别是第二个参数开始传参方式不同。 
call传参:obj,arg2,arg3 
apply传参:obj,[arg2,arg3,…]

bind() 第一个参数为this指针指向的目标对象,bind方法执行后返回的是一个新函数

如果这个三个方法都没有提供第一个参数或参数是this、null、undefined中的一种,那么都将默认第一个参数为Global对象 。

  • 显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链

 显式原型:prototype       隐式原型:__proto__

在js中万物皆对象,方法(Function)是对象,方法的原型(Function.prototype)是对象,对象具有属性(__proto__)称为隐式原型,对象的隐式原型指向构造该对象的构造函数的显式原型。    方法(Function)是一个特殊的对象,除了和其他对象一样具有__proto__属性以外,它还有一个自己特有的原型属性(prototype),这个属性是一个指针,指向原型对象。原型对象也有一个属性叫constructor,这个属性包含一个指针,指向原构造函数。

用法:创建实例时,将实例中共享的原型放到原型对象中,让所有实例共享这部分的属性;想要修改所有实例继承的属性,修改原型对象中的属性即可;若想修改单个实例中的属性,重写原型中已经存在的属性即可,不会影响其他实例的属性。

原型链:所有对象都是由它的原型对象继承而来,而原型对象自身也是一个对象,他也有自己的原型对象,这样层层上溯形成一个类似链表的结构,就是原型链。通过原型链可以实现继承。

  • 创建对象的多种方式

动态原型模式:

function Person(name) {
  this.name = name
  if(typeof this.say != 'function') {
    Person.prototype.say = function(
    alert(this.name)
  }
}

 

  • 实现继承的多种方式和优缺点

原型链继承:引用类型的属性被所有实例共享;

借用构造函数:避免了引用类型的属性被所有实例共享;

组合继承:原型链和借用构造函数的技术组合到一块,使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承; 融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。

  • new 一个对象具体做了什么

首先创建了一个空对象,将空对象的proto成员指向原函数对象的prototype成员对象,将F函数this指针替换成当前新对象再调用原函数。

  • 手写Ajax,XMLHttpRequest

var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.onreadtstatechange = function () {
    if (xhr.readystate == 4) {
        //响应内容解析完成,可以在客户端调用了
        if (xhr.status == 200) {
            //客户端的请求成功了
            alert(xhr.responseText);
        }
    }
}
xhr.send(null);
  • 变量提升

变量提升就是把变量提升提到函数的top的地方。但是只是提升变量的声明,并不会把赋值也提升上来。

函数提升是把整个函数都提到前面去。在我们写js code 的时候,我们有两种写法,一种是函数表达式(var foo = function foo(){}),另外一种是函数声明方式(function foo(){})。我们需要重点注意的是,只有函数声明形式才能被提升。

  • 举例说明一个匿名函数的典型用例

创建闭包


//通过闭包可以 返回局部变量
function box() {
    var user = 'Lee';
    return function () {//通过匿名函数返回box()局部变量
        return user;
};
}
alert(box()());//通过box()()来直接调用匿名函数返回值
 
var b = box();
  • 指出JS的宿主对象和原生对象的区别,为什么扩展JS内置对象不是好的做法?有哪些内置对象和内置函数?

​​​​​​​

  • attribute和property的区别

​​​​​​​

  • document load和document DOMContentLoaded两个事件的区别

DOMContentLoaded: DOM解析完成即触发此事件,不等待styles, images等资源的加载;

load:依赖的资源也已加载完成;  DOMContentLoaded绑定到document,load绑定到window

我们需要给一些元素的事件绑定处理函数。但问题是,如果那个元素还没有加载到页面上,但是绑定事件已经执行完了,是没有效果的。这两个事件大致就是用来避免这样一种情况,将绑定的函数放在这两个事件的回调中,保证能在页面的某些元素加载完毕之后再绑定事件的函数。

DOM文档加载的步骤为

  1. 解析HTML结构。

  2. 加载外部脚本和样式表文件。

  3. 解析并执行脚本代码。

  4. DOM树构建完成。//DOMContentLoaded

  5. 加载图片等外部文件。

  6. 页面加载完毕。//load

在第4步,会触发DOMContentLoaded事件。在第6步,触发load事件。

document.addEventListener("DOMContentLoaded", function() {
   // ...代码...
}, false);
 
window.addEventListener("load", function() {
    // ...代码...
}, false);
  • === 和 == , [] === [], undefined === undefined,[] == [], undefined == undefined

​​​​​​​== 代表相同, ===代表严格相同;进行双等号比较时候: 先检查两个操作数数据类型,如果相同, 则进行===比较, 如果不同, 则愿意为你进行一次类型转换, 转换成相同类型后再进行比较, 而===比较时, 如果类型不同,直接就是false.

双等号==: 

  (1)如果两个值类型相同,再进行三个等号(===)的比较

  (2)如果两个值类型不同,也有可能相等,需根据以下规则进行类型转换在比较:

    1)如果一个是null,一个是undefined,那么相等

    2)如果一个是字符串,一个是数值,把字符串转换成数值之后再进行比较

注意[] === [] 、[] == []返回均为false

  • typeof能够得到哪些值

​​​​​​​number   string    boolean   undefined,对于[ ]、null、{ }输出都为object;

  • 什么是“use strict”,好处和坏处​​​​​​​

  • 函数的作用域是什么?js 的作用域有几种?

​​​​​​​指在函数内声明的所有变量在函数体内始终是可见的,这就意味着变量在声明之前已经可用了。

全局,局部。使用时注意变量声明会提前

  • JS如何实现重载和多态

​​​​​​​重载:一组具有相同名字,不同参数列表的函数/方法。

实现:1.使用argumnets对象的length,判断参数长度

           2.typeof等判断

多态:

  • 常用的数组api,字符串api

  • 原生事件绑定(跨浏览器),dom0和dom2的区别?

1. DOM0级事件处理程序(属性绑定,兼容性好)

  通过javascript制定事件处理程序的传统方式,将一个函数赋值给一个事件处理程序属性。特点是简单,跨浏览器。
        var btn = document.getElementById("btn");
             btn.onclick = function(){
             alert('cliked');
         }
 dom0级方法制定的事件处理程序被认为是元素的方法,因此这个时候事件处理程序是在元素的作用域中运行,this指向当前元素。

        btn.onclick = null;  //删除事件处理程序

2. DOM2级事件处理程序(函数绑定,兼容性不好)

DOM2级规范以一种符合逻辑的方式来标准化DOM事件,IE9,Firefox,Opera,Safari,Chrome全部已经实现了"DOM2级事件"模块的核心部分。IE8是最后一个仍然使用其专有事件系统的主要浏览器。

addEventListener() 事件绑定          removeEventListener()事件删除

如果定义了两个dom0级事件,dom0级事件会覆盖;dom2不会覆盖,会依次执行;dom0和dom2可以共存,不互相覆盖,但是dom0之间依然会覆盖。

  • 给定一个元素获取它相对于视图窗口的坐标

  • 如何实现图片滚动懒加载

  • js 的字符串类型有哪些方法? 正则表达式的函数怎么使用?

​​​​​​​​​​​​​​

  • 深拷贝

  • 编写一个通用的事件监听函数

  • web端cookie的设置和获取

  • setTimeout和promise的执行顺序

  • JavaScript 的事件流模型都有什么?

  • navigator对象,location和history

  • js的垃圾回收机制

  • 内存泄漏的原因和场景

  • DOM事件的绑定的几种方式

  • DOM事件中target和currentTarget的区别

  • typeof 和 instanceof 区别,instanceof原理

  • js动画和css3动画比较

  • JavaScript 倒计时(setTimeout)

  • js处理异常

  • js的设计模式知道那些

  • 轮播图的实现,以及轮播图组件开发,轮播10000张图片过程

  • websocket的工作原理和机制。

  • 手指点击可以触控的屏幕时,是什么事件? 什么是函数柯里化?以及说一下JS的API有哪些应用到了函数柯里化的实现?(函数柯里化一些了解,以及在函数式编程的应用,- 最后说了一下JS中bind函数和数组的reduce方法用到了函数柯里化。)

  • JS代码调试-

你可能感兴趣的:(编程语言)