面试汇总javascript

获取元素相对于父元素的位移

js: offsetLeft左位移 offsetTop上位移
jquery: position().left; position().top

js删除数组中空元素

function removeEmptyArrayEle(arr){    
  for(var i = 0; i < arr.length; i++) {
   if(arr[i] == undefined) {
      arr.splice(i,1);
      i = i - 1; // i - 1 ,因为空元素在数组下标 2 位置,删除空之后,后面的元素要向前补位,
                       // 这样才能真正去掉空元素,觉得这句可以删掉的连续为空试试,然后思考其中逻辑
    }
   }
   return arr;
};

javascript 的typeof 都返回哪些数据类型

number, boolean, string, undefined, object, function.

如何判断一个对象的数据类型为数组

使用Array.isArray(arr)和Oblect.prototype.toString.call(arr)是比较好的方法

使用多种方法截取字符串“www.bestmath.cn”中的math

  • 函数:substring()
    定义:substring(start,end)表示从start到end之间的字符串,包括start位置的字符但是不包括end位置的字符。
    功能:字符串截取,比如想从"MinidxSearchEngine"中得到"Minidx"就要用到substring(0,6)
  • 函数:substr()
    定义:substr(start,length)表示从start位置开始,截取length长度的字符串。

如何理解 JavaScript 的原型?

  • 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(null除外)
  • 所有的函数,都有一个prototype属性,属性值也是一个普通的对象
  • 所有的引用类型(数组、对象、函数),都有一个proto属性,属性值是一个普通的对象
  • 所有的引用类型(数组、对象、函数),proto属性值指向它的构造函数的prototype属性值

原型示例

function Foo(name, age) {  //构造函数
this.name = name
}
Foo.prototype.alertName = function () {
  alert(this.name)
}
// 创建示例
var f = new Foo('zhangsan')
f.printName = function () {
    console.log(this.name)
}
// 测试
f.printName()
f.alertName()...

执行printName时很好理解,但是执行alertName时发生了什么?这里再记住一个重点 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找,因此f.alertName就会找到Foo.prototype.alertName

那么如何判断这个属性是不是对象本身的属性呢?使用hasOwnProperty,常用的地方是遍历一个对象的时候

var item
for (item in f) {
// 高级浏览器已经在 for in 中屏蔽了来自原型的属性,但是这里建议大家还是加上这个判断,保证程序的健壮性
if (f.hasOwnProperty(item)) {
      console.log(item)
   }
}...

传送门

闭包概念?

  • javascript不存在块级作用域,但是有函数作用域:函数内定义的的所有变量在函数外是不可见的。
  • 内部函数可以访问的变量即来自他自身的作用域,也可以来自其“父级”作用域,这就形成了一条作用域链。
  • 利用闭包突破作用域链:将内部函数升级为全局变量或者通过外部函数传递(或返回)给全局空间即可。
  • 所以说:如果一个函数会在其父级函数返回之后留住父级作用域的链接的话,相关闭包就会被创造出来。
unction F1() {
    var a = 100
    return function () {
        console.log(a)
    }
}
var f1 = F1()
var a = 200
f1()

自由变量将从作用域链中去寻找,但是 依据的是函数定义时的作用域链,而不是函数执行时,以上这个例子就是闭包。闭包主要有两个应用场景:

  • 函数作为返回值,上面的例子就是

  • 函数作为参数传递,看以下例子

    function F1() {
      var a = 100
      return function () {
          console.log(a)
      }
    }
    function F2(f1) {
      var a = 200
      console.log(f1())
    }
    var f1 = F1()
    F2(f1)
    

以上结果是100 undefined 原因是f1()没有返回值,所用console.log(f1())undefined

说一下异步和单线程?

JS 需要异步的根本原因是 JS 是单线程运行的,即在同一时间只能做一件事,不能“一心二用”。
同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
参考

  • 前端异步的场景
    定时 setTimeout setInterval
    网络请求,如Ajax <img>加载

如何使用事件代理?有何好处?

利用冒泡的原理,把事件加到父级上,当子元素的事件冒泡到父ul元素时,你可以检查事件对象的target属性,捕获真正被点击的节点元素的引用。

var div1 = document.getElementById('div1')
div1.addEventListener('click', function (e) {
 // e.target 可以监听到触发点击事件的元素是哪一个
   var target = e.target
   if (e.nodeName === 'A') {
     // 点击的是 元素
     alert(target.innerHTML)
   } 
})
  • 使用事件代理的好处
    使代码简洁
    减少浏览器的内存占用
    通过事件委托,新添加的元素自动绑定事件
    参考

property 和 attribute 的区别是什么?

property

DOM 节点就是一个 JS 对象,它符合之前讲述的对象的特征 —— 可扩展属性,因为 DOM 节点本质上也是一个 JS 对象。因此,如下代码所示,p可以有style属性,有className nodeName nodeType属性。注意,这些都是 JS 范畴的属性,符合 JS 语法标准的。

var pList = document.querySelectorAll('p')
var p = pList[0]
console.log(p.style.width)  // 获取样式
p.style.width = '100px'  // 修改样式
console.log(p.className)  // 获取 class
p.className = 'p1'  // 修改 class

// 获取 nodeName 和 nodeType
console.log(p.nodeName)
console.log(p.nodeType)
attribute

property 的获取和修改,是直接改变 JS 对象,而 attribute 是直接改变 HTML 的属性,两种有很大的区别。attribute 就是对 HTML 属性的 get 和 set,和 DOM 节点的 JS 范畴的 property 没有关系。

var pList = document.querySelectorAll('p')
var p = pList[0]
p.getAttribute('data-name')
p.setAttribute('data-name', 'juejin')
p.getAttribute('style')
p.setAttribute('style', 'font-size:30px;')...

什么是同源策略?跨域的方法?

浏览器中有 同源策略 ,即一个域下的页面中,无法通过 Ajax 获取到其他域的接口。例如有一个接口http://m.juejin.com/course/ajaxcourserecom?cid=459,你自己的一个页面http://www.yourname.com/page1.html中的 Ajax 无法获取这个接口。这正是命中了“同源策略”。如果浏览器哪些地方忽略了同源策略,那就是浏览器的安全漏洞,需要紧急修复。
但是 HTML 中几个标签能逃避过同源策略——<script src="xxx"><img src="xxxx"/><link href="xxxx">,这三个标签的src/href可以加载其他域的资源,不受同源策略限制。
参考

立即执行函数的应用场景?

参考

箭头函数与function的区别?

  • 箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

  • 箭头函数不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

  • 箭头函数不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。

  • 不可以使用yield命令,因此箭头函数不能用作Generator函数。

谈谈this对象的理解

参考
javaScript 由于其运行期绑定的特性,this 的具体指向取决于函数的调用方式。一个原则:this 指向的永远是当前调用函数的那个对象。

  • 函数调用
  • 作为对象方法调用
  • 作为构造函数调用
  • apply/call/bind 调用(显示绑定)

下面的代码将输出什么到控制台,为什么?

(function(){
var a=b=3;
})()
console.log(typeof a);// undefined
console.log(typeof b);// 3 因为b是全局函数

什么是ajax?

AJAX 是一种与服务器交换数据的技术,可以在不重新载入整个页面的情况下更新网页的一部分。就是用JavaScript执行异步网络请求。AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术

创建文档碎片节点

createDocumentFragment()

图片懒加载

核心原理是:
1 设置一个定时器,计算每张图片是否会随着滚动条的滚动,而出现在视口(也就是浏览器中的展现网站的空白部分)中;

2 为<img>标签设置一个暂存图片URL的自定义属性(例如loadpic),当图片出现在视口时,再将loadpic的值赋给图片的src属性

/**
* 图片的src实现原理
*/
$(document).ready(function(){
    // 获取页面视口高度
    var viewportHeight = $(window).height();
    var lazyload = function() {
        // 获取窗口滚动条距离
        var scrollTop = $(window).scrollTop();
        $('img').each(function(){
        // 判断 视口高度+滚动条距离 与 图片元素距离文档原点的高度         
        var x = scrollTop + viewportHeight - $(this).position().top;
        // 如果大于0 即该元素能被浏览者看到,则将暂存于自定义属性loadpic的值赋值给真正的src            
        if (x > 0)
        {
            $(this).attr('src',$(this).attr('loadpic')); 
        }
    })
    }
    // 创建定时器 “实时”计算每个元素的src是否应该被赋值
    setInterval(lazyload,100);
});

移动端网页使用click时间会有什么问题?如何解决

https://www.cnblogs.com/zhaodahai/p/6831165.html
http://blog.csdn.net/xjun0812/article/details/64919063
移动端页面对于点击事件会有300毫秒的延迟,也就是js捕获click事件的回调函数处理,需要300ms后才生效,导致多数用户感觉移动设备上基于HTML的web应用界面响应速度慢,甚至有时候会影响一些业务逻辑的处理。

如何从外部读取函数内部的局部变量?

出于种种原因,我们有时候需要获取到函数内部的局部变量。但是,上面已经说过了,正常情况下,这是办不到的!只有通过变通的方法才能实现。

那就是在函数内部,再定义一个函数。

function f1(){

var n=999;

function f2(){
      alert(n); // 999
    }

}

在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。

这就是Javascript语言特有的"链式作用域"结构(chain scope),

子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!

说一下页面传值的方法 **

http://blog.csdn.net/m0_37452696/article/details/78310238
https://www.cnblogs.com/cjl21/p/7159102.html
通过cookie

如何拷贝一个数组

https://www.cnblogs.com/jiangzilong/p/6513552.html

数组去重的方法?参考

function unique1(arr){
     var newArr = [];//新建一个数组
     for(var i=0,len=arr.length;i<len;i++){
         if(newArr.indexOf(arr[i]) == -1){//若新数组中未包含该项则将其存入新数组
          newArr.push(arr[i]);
      }
     }
     return newArr;
 } 

解决setInterval计算延迟问题?参考

call个apply的区别和作用?参考

git和svn的区别?参考

mvc 和 mvvm的区别参考

webpack判断环境变量?node判断环境变量?

process.env.NODE_ENV === 'production'

js对DOM增删改查?

查找元素
document.getElementById("ul")
document.getElementsByTagName("li");
insertBefore(节点, 原有节点) 在已有元素前插入
appendChild(节点) 追加一个节点
createElement(标签名) 创建一个节点
removeChild(节点) 删除一个节点

什么是“use strict”?使用它的好处和坏处?

ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。

好处:

  • 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
  • 消除代码运行的一些不安全之处,保证代码运行的安全;
  • 提高编译器效率,增加运行速度;
  • 为未来新版本的Javascript做好铺垫。
    注:经过测试 IE6,7,8,9 均不支持严格模式。

坏处:
现在网站的 JS 都会进行压缩,一些文件用了严格模式,而另一些没有。这时这些本来是严格模式的文件,被 merge 后,这个串就到了文件的中间,不仅没有指示严格模式,反而在压缩后浪费了字节

js延迟加载的方式有哪些?参考

ES5和ES6的继承有什么区别?

ES5的继承时通过原型或构造函数机制来实现。
ES6通过class关键字定义类,里面有构造方法,类之间通过extends关键字实现继承。子类必须在constructor方法中调用super方法,否则新建实例报错。因为子类没有自己的this对象,而是继承了父类的this对象,然后对其进行加工。如果不调用super方法,子类得不到this对象。

实现继承哪些方法?参考

promise底层原理?参考

setTimeout click promise 执行顺序

参考

为什么要用node 应用场景?参考

两个超长字符串相乘的结果?

写出实时获取后台数据的请求参考

箭头函数的this会改变吗?

this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。

set 中两个symbol?参考

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。
set中两个Symbol值就是两个不相等的值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容