前端笔试题总结-JavaScript

JavaScript专项刷题

  • JS语言是:

    • JS一种动态类型,弱类型,基于原型,直译式的脚本语言(解释性语言)
    • JS是一门单线程语言
    • 浏览器端的JavaScript包含ECMAScript,DOM对象以及BOM对象
    • JS语言不仅可以在浏览器环境运行,也可以在node提供的服务器端的平台运行。
    • JS不是面向对象的语言(有争议,但是牛客上遇到有个题的答案是这么说的
  • 变量作用域:

    当作用域中没有所需的变量时,会通过作用域链向上查找

  • 数据类型:

    • 基本/原始数据类型(值类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol(ES6-独一无二的值)
    • 引用数据类型(复杂类型):对象(Object)
  • BOM对象:

    • Navagator:提供有关浏览器的信息
    • Window:Window对象处于对象层次的最顶层,它提供了处理Navagator窗口的方法和属性
    • Location:提供了与当前打开的URL一起工作的方法和属性,是一个静态的对象
    • History:提供了与历史清单有关的信息
    • Document:包含与文档元素一起工作的对象,它将这些元素封装起来供编程人员使用
  • 静态语言和动态语言:

    静态语言(强类型语言):

    静态语言是在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型。 如C++、Java、Delphi、C#等

    动态语言(弱类型语言):

    动态语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。

  • new Boolean()

    new Boolean(); // false
    new Boolean(0); //false
    new Boolean(null); //false
    new Boolean(""); //false
    new Boolean(NaN); //false
    new Boolean(Symbol()); //true
    
  • JS常见事件:

    onkeypress:某个键盘的键被按下或按住

    onmousedown:某个鼠标按键被按下

    contextmenu:按下右键(添加contextmenu监听并返回false可以阻止弹出右键菜单)

    onblur:元素失去焦点 //通常用于代码验证(当用户离开表单输入域时)

    onfocus:元素获得焦点

  • 事件方法:

    event.stopImmediatePropagation() //彻底的阻止事件, 在其之后的绑定在元素上的其他监听事件都不会触发
    
    //阻止默认事件的默认操作
    event.preventDefault(); //符合W3C标准
    window.event.returnValue = false; //IE
    
    //阻止冒泡
    event.stopPropagation(); //符合W3C标准
    window.event.cancelBubble = true; //IE
    
  • 逻辑判断——相等:

    ===严格相等运算符: 首先计算其操作数的值,然后比较这两个值,比较过程中没有任何类型转换(当类型和值都一致时才相等 )

    ==相等运算符: 如果两个操作数不是同一类型,那么会尝试进行一些类型转换,然后进行比较

    (1)尽管null和undefined是不同的,但它们都表示“值的空缺”,两者往往可以互换,因此==运算符结果为true,但是===运算符结果为false

    (2)NaN表示非数字值,特殊之处:它和任何值都不相等,包括自身。判断NaN的方法:x!=x返回true,说明x是NaN

    特殊需要记忆的:

    NaN= NaN //true
    null= 0 //true
    undefined != 0 //true
    false != null //true
    false != undefined //true
    undefined == null //true
    [] == 0 //true
    [] == true //false []会隐式转化为0
    ![] == false //true []被当成对象处理,所有对象都是true
    [] == false  //true []被隐式转化为0
    
  • 相等运算符(补充):

    • 如果一个值是null,另一个值是undefined,则它们相等

    • 如果一个值是数字,另一个值是字符串,先将字符串转换为数字,然后使用转换后的值进行比较。

    • 如果其中一个值是true,则将其转换为1再进行比较。如果其中的一个值是false,则将其转换为0再进行比较。

    • 如果一个值是对象,另一个值是数字或字符串,则将对象转换为原始值,再进行比较。

  • 数据类型转换true/false:

    数据类型 转换为true的值 转换为false的值
    Boolean true false
    String 非空字符串 空字符串
    Number 非0(包括负数、infinity) 0和null
    Object 任何对象 null(null不属于对象)
    undefined undefined
  • typeof null === 'object' //true
    null instanceof Object //false
    
  • instanceof:

    instanceof在跨frame时会失效。

    判断类型时使用下述方法最为准确:

    Object.prototype.toString.call(obj) === '[object ...]';
    //比如
    Object.prototype.toString.call(arr) === '[object Array]';
    
  • 数组排序:

    升序:a-b

    降序:b-a

  • 如果不给cookie设置过期时间,则coolie会在浏览器会话结束时过期。

  • this:

    1)当在函数调用的时候指向widow(特殊的是:IE中的attachEvent中的this总是指向全局对象window

    2)当方法调用的时候指向调用对象(谁调用指向谁)

    3)当用apply和call上下文调用的时候指向传入的第一个参数

    4)构造函数调用指向实例对象(new时指向新建的对象)

    5)严格模式下禁止this关键字指向全局对象

    匿名函数调用时具有全局作用域

  • Math.round(x):

    如果参数的小数部分大于 0.5,则舍入到下一个绝对值更大的整数;

    如果参数的小数部分小于 0.5,则舍入到下一个绝对值更小的整数;

    如果参数的小数部分恰好等于0.5,则舍入到下一个在正无穷(+∞)方向上的整数。

    eg:

    Math.round(11.5) //12
    Math.round(-11.5) //-11
    Math.round(-11.6) //-12
    
if(! "a" in window) {
    //判断window对象中是否有变量a
    ...
}
console.log("a" in window);  //true  var声明的全局变量会提前声明,所以为true
var a = 1;
  • 函数定义方式:

    function add(a,b){return a+b;}  //函数声明
    var add=function(a,b){return a+b;} //函数表达式
    var add = new Function('a','b','return a+b') //Function构造函数(不推荐使用,影响函数解析性能)
    
  • slice()方法返回一个新的数组,不会破坏原数组

  • es6中没有枚举的概念

  • ng-style和ng-class:

    angluar中的绑定style和绑定class

    类似的还有:

    给元素绑定监听: ng-click等
    显示隐藏 : ng-show ng-hide
    自带路由:ng-route
    寄存方式:ng-template
    指令绑定了 HTML 表单元素到 scope 变量中:ng-model
    指定控制器ng-controller

  • Promise状态:

    • 异步操作“未完成”(pending)

    • 异步操作“已完成”(resolved,又称fulfilled)

    • 异步操作“失败”(rejected)

    这种变化只能发生一次,一旦当前状态变为“已完成”或“失败”,就意味着不会再有新的状态变化了。因此,Promise对象的最终结果只有两种:

    异步操作成功, Promise对象传回一个值,状态变为resolved。

    异步操作失败, Promise对象抛出一个错误,状态变为rejected。

  • 跨域:

    • 域名、端口、协议任意一个不同,即为跨域
    • js可以使用jsonp进行跨域
    • 通过修改document.domain来跨子域
  • 使用window.name来进行跨域

  • 异步任务:

    异步任务分为宏任务微任务微任务优先级高于宏任务

    promise属于微任务,setTimeout属于宏任务

  • DOM中的children和childrenNodes:

    children :指DOM Object类型的子对象,不包括tag之间隐形存在的TextNode

    childrenNodes :指DOM Object类型的子对象,包括tag之间隐形存在的TextNode对象

  • JS的全局属性、函数:

    全局属性、函数

    setTimeout不是JS的全局函数,它是window的方法

  • 页面的性能指标:

    白屏时间(first Paint Time) ——用户从打开页面开始到页面开始有东西呈现为止,也就是开始解析DOM耗时

    首屏时间 ——用户浏览器首屏内所有内容都呈现出来所花费的时间

    用户可操作时间(dom Interactive) ——用户可以进行正常的点击、输入等操作,默认可以统计domready时间,因为通常会在这时候绑定事件操作

  • map()遇到空位时:

    会跳过空位,但是输出结果会保留空位的值。

    orEach(), filter(), reduce(), every() 和some()都会跳过空位。

    map()会跳过空位,但会保留这个值。

    join()和toString()会将空位视为undefined,而undefined和null会被处理成空字符串。

  • JS变量回收规则:

    • 全局变量不会 被回收。
    • 局部变量 被回收,也就是函数一旦运行完以后,函数内部的东西都会被销毁。
    • 只要被另外一个作用域所引用就不会 被回收
  • 变量类型判断:

    **typeof 能判断类型有:**number、string、boolean、symbol、undefined、object(object、array、null 的变量都返回 object);

    Object.prototype.toString(): Object 对象的实例方法,默认情况下(即不重写该方法),返回参数的类型字符串。

  • 能冒泡的事件

  • DNS:

    • DNS的作用是将域名翻译成IP地址。

    • DNS协议大多运行在UDP之上,但是当请求字节过长超过512字节时用TCP协议,将其分割成多个片段传输。

    • DNS协议默认端口号是53。

    • 操作系统的DNS缓存:windows DNS缓存的默认值是 MaxCacheTTL,它的默认值是86400s,也就是一天。macOS 严格遵循DNS协议中的TTL。

    • 浏览器的DNS缓存:1分钟到半小时不等

  • 严格模式:

    使用'use strict'来开启严格模式(可以开启整个文件,也可以开启部分代码块)

    严格模式下禁止this关键字指向全局对象。

  • iframe:

    局限:

    • 创建比一般的 DOM 元素慢了 1-2 个数量级

    • 阻塞页面加载

    • 唯一的连接池

      绝大部分浏览器,主页面和其中的 iframe 是共享连接池的(同域名可打开的连接是有限的)。这意味着 iframe 在加载资源时可能用光了所有的可用连接,从而阻塞了主页面资源的加载。

    • 不利于 SEO

  • History对象:

    go() //加载history列表中的某个具体页面。
    back() // 加载 history 列表中的前一个URL
    forward() // 加载 history 列表中的下一个URL
    length //返回浏览器历史列表中的URL数量
    
  • 闭包:

    作用:

    • 可以读取函数内部的变量
    • 可以把变量始终保存在内存中

    写法:

    1. 一个函数(即外部函数)里面包含另一个函数(即内部函数),并且return返回这个内部函数, 然后内部函数在定义内部函数之外的作用域被调用,这时的内部函数就是一个闭包了。
    2. 内部函数引用了外部函数的变量,这个变量不会被销毁,因为闭包需要这个变量, 所以通过闭包可以访问闭包保存的变量。

    局限:

    • 因为闭包的变量保存在内存中,内存泄漏,对内存的消耗很大。

    闭包常用的地方:

    • es5 for循环的事件监听
    • 函数里使用了定时器
    • 封装许多高级的功能集
  • JS数组对象方法:

    Array对象

  • reflow(回流\重新布局)和repaint(重绘):

    • 位置改变->reflow->repaint

    • 显示样式改变(颜色等)->repaint

    repaint速度明显快于repaint,在开发中要尽量避免reflow,并减少repaint

  • 可能导致reflow的操作:

    • 改变窗口大小
    • 改变文字大小
    • 内容改变(在输入框中输入内容)
    • 激活伪类(如:hover)
    • 操作(改变)class属性
    • 脚本操作DOM
    • 计算offsetWidthoffsetHeight
    • 设置style属性
  • 浮点数精度:

    • toFixed 把数字转换为字符串,结果的小数点后有指定位数的数字
    • toPrecision 把数字格式化为指定的长度
  • Math.round 把一个数字舍入为最接近的整数

  • 运算符隐式转换:

    +: 有两个含义:第一个含义是做字符串拼接,第二个含义是加减法中的加法。==如果操作数里有一个是字符串,其他的值将被转换成字符串;==其他情况,操作数转换成数字执行加法运算。

    -: 只有一个含义,做数值的减运算。

    当加减号进行数值运算是,若存在NaN,则结果为NaN

    console.log(1+ "2"+"2"); //1 -> "122"
    console.log(1+ +"2"+"2"); //2 -> "32"
    console.log("A"- "B"+"2"); //3 -> "NaN2"
    console.log("A"- "B"+2); //4 -> NaN
    console.log("10"+3-"1") //5 -> 102
    
    1. 先执行字符串拼接运算,得到字符串"12",在进行2个字符串的拼接运算,得到字符串"122"
    2. 执行1+ +"2"时,+"2"为一元运算符运算,相当于Number()函数==(注意不是取正运算)==,会将后面的变量先转换为Number再进行运算,所以得到数值2,在与数值1相加得到Number3;再与后面的字符串进行拼接运算,得到字符串结果"32"
    3. -运算符只会执行数值减运算,但运算符两边转换为Number为NaN,所以得到NaN,再与后面的字符串进行拼接运算,得到结果NaN2
    4. 前段与第3题一致,得到NaN,与后面的数值2进行加运算,NaN+2=NaN,所以结果为NaN
    5. 先执行字符串拼接运算,得到字符串"103",再执行数值减运算,得到数值结果102
  • 字符串拼接效率问题:

    直接使用字符串+运算,会新建一个临时字符串,将新字符串赋值为拼接后的结果,然后返回这个临新字符串并同时销毁原始字符串。效率较低(类似Java)

    当数据量比较大时的拼接方法: 将字符串push进一个空数组tempArr,然后tempArr.join()来获得字符串。

    tempArr.toString()会将item的分隔符’,'也输出,所以不可以用toString()

  • Ajax:

    • Ajax不是新的编程语言,而是一门提供网页局部刷新的技术。

    • Ajax最大的优点是在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容。

    • Ajax技术核心就是XMLHttpRequest对象。

  • Ajax技术的工作原理

    1)创建Ajax对象:

    ​ var xhr = new XMLHttpRequest();

    2)xhr 发送请求:

    ​ xhr.open(‘get’,‘test.html’,‘true’);

    ​ xhr.send();

    3)xhr获取响应:

    xhr.onreadystatechange = function(){
    
    if(xhr.readystate == 4){//请求的状态码
    
    /*
    
    0:请求还没有建立(open执行前)
    
    1:请求建立了还没发送(执行了open)
    
    2:请求正式发送(执行了send)
    
    3:请求已受理,有部分数据可以用,但还没有处理完成
    
    4:请求完全处理完成
    
    */
    
    alert(xhr.responseText);//返回的数据
    
    }
    
    }
    
  • Ajax和Flash的对比:

    Ajax的优势:

    ​ 1.可搜索性 2.开放性 3.费用 4.易用性 5.易于开发

    Ajax的劣势:

    1. 它可能破坏浏览器的后退功能

    2. 使用动态页面更新使得用户难于将某个特定的状态保存到收藏夹中

    Flash的优势:

    ​ 1.多媒体处理 2.兼容性 3.矢量图形

    ​ 4.客户端资源调度(容易调用客户端之外的内容,比如摄像头、麦克风等)

    Flash的劣势:

    ​ 1.二进制格式 2.格式私有 3.文件经常会很大,第一次使用的时候需要等待时间 4.性能问题

  • web的生命周期:

    web的生命周期

  • 对象的for…in方法:

    对象的for…in属性是遍历对象的key

  • 块级元素的总宽度:

    块级元素的总的宽度=左右padding+左右border+内容区的width。

    我们实际设置的width指的就是内容区的width,所以当改变padding、border、width中的任一项的时候,块元素的总宽度都会发生变化。

  • 触摸事件:

    ouchstart: //手指放到屏幕上时触发

    touchmove: //手指在屏幕上滑动式触发

    touchend: //手指离开屏幕时触发

    touchcancel: //系统取消touch事件的时候触发,这个好像比较少用

    每个触摸事件被触发后,会生成一个event对象,event对象里额外包括以下三个触摸列表

    touches: //当前屏幕上所有手指的列表(多点触控)

    targetTouches: //当前dom元素上手指的列表,尽量使用这个代替touches

    changedTouches: //涉及当前事件的手指的列表,尽量使用这个代替touches

  • Number的小数点(.):

    将一个数值型转换为字符串:

    2.toString() //错误Uncaught SyntaxError: Invalid or unexpected token
    

    因为JS引擎会优先将.解析为数字的小数点,所以上述就被解析成了:

    (2)toString
    

    为了避免上述问题,应该写成:

    2..toString()
    2 .toString()
    (2).toString()
    
  • 原型对象:

    hasOwnProperty: 是用来判断一个对象是否有你给出名称的属性或对象。不过需要注意的是,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。

    isPrototypeOf : 是用来判断要检查其原型链的对象是否存在于指定对象实例中,是则返回true,否则返回false。

  • Number()函数:

    结果为0的:

    Number() //0
    Number(0) //0
    Number('') //0
    Number('0') //0
    Number(false) //0
    Number(null) //0
    Number([]) //0
    Number([0]) //0
    

    结果是NaN的:

    Number(undefined) //NaN
    
  • parseInt:

    parseInt()接受2个参数,第一个是要转换为整数的字符串,第二个是进制。

    *** a t t e n t i o n \color{red}{attention} attention:***paraseInt使用时,若第一个参数不是字符串,则会将其隐式转换为字符串类型的。

    结果为NaN的:

    parseInt("") //NaN
    parseInt(null) //NaN
    parseInt(undefined) //NaN
    
  • JS保留字:

    JS保留字

  • jQuery选择器:

    常用有三种:

    ①元素选择器:$(TagName)
    ②ID 选择器:$(#Id)
    ③类选择器:$(.className)

​ removeClass():删除class。

​ addClass():添加class。

​ remove():把元素从元素中删除(包括所有的文本和子节点)。

​ add():把元素添加到已有元素中(包括所有的文本和子节点)。

  • 块内函数定义:

    • 不要在块内声明一个函数(严格模式会报语法错误)。如果确实需要在块中定义函数,可以使用函数表达式来声明函数。
    • 块内声明的变量只要没加var 都算作全局变量。
    • ES5看起来像支持块级作用域,实际上只有函数作用域和全局作用域。
    • ES6才规定块级作用域。
    if (x) {  function foo() {}} //因为有函数声明提前,所以相当于声明了一个全局匿名函数(在if内叫foo)
    if (x) {  foo = function() {}} //没有var,所以是全局函数foo
    if (x) {  var foo = function() {}} //块级函数foo
    
  • 模块引入机制:

    Q:在文件/home/somebody/workspace/somemodule.js中第一行引用了一个模块:require(‘othermodule‘),请问required 的查找模块的顺序是?

    A:

    1. CORE MODULES named othermodule(核心模块)

    2. /home/somebody/workspace/node_modules/othermodule. js (当前路径的js)

    3. /home/somebody/workspace/node_modules/othermodule/index.js(当前路径的同名文件夹下的index.js)

    4. /home/somebody/node_modules/othermodule/index.js (node_modules下的模块)

  • JS标准事件模型的触发顺序:

    事件捕获->事件处理->事件冒泡

  • ★★★★★

    var foo = {n:1};
    (function(foo){            //形参foo同实参foo一样指向同一片内存空间,这个空间里的n的值为1
        var foo;               //优先级低于形参,无效。
        console.log(foo.n);    //输出1
        foo.n = 3;             //形参与实参foo指向的内存空间里的n的值被改为3
        foo = {n:2};           //形参foo指向了新的内存空间,里面n的值为2.
        console.log(foo.n);    //输出新的内存空间的n的值
    })(foo);
    console.log(foo.n);        //实参foo的指向还是原来的内存空间,里面的n的值为3.
    

    输出:1,2,3

  • in操作符:

    判断一个属性(key)是否属于一个对象,对于数组来说,key是下标。

    1 in [1] //false 因为数组长度为1,所以下标只有0,1不在其中
    
  • 1 && 2>1 :

    &&优先级低于>,所以先算2>1 为 true,原题变为:1 && true,操作符短路,所以结果为1。

  • Document对象的属性和方法:

    Document对象的属性和方法

  • 字符串与字符串对象:

    • JS 中值的类型分为原始值类型和对象类型。原始值类型包括 number, string, boolean, null 和 undefined;对象类型即 object。首先原始值类型它就不是对象

    • 另外,要注意 ‘hello’ 和 new String(‘hello’) 的区别,前者是字符串字面值,属于原始类型,而后者是对象。用 typeof 运算符返回的值也是完全不一样的:

      typeof 'hello';  // 'string'
      typeof new String('hello');  // 'object'
      
    • 之所以很多人分不清字符串字面值和 String 对象,归根结底就是 JS 的语法对你们太过纵容了。当执行 ‘hello’.length 时,发现可以意料之中的返回 5,你们就觉得 ‘hello’ 就是 String 对象,不然它怎么会有 String 对象的属性。其实,这是由于 JS 在执行到这条语句的时候,内部将 ‘hello’ 包装成了一个 String 对象,执行完后,再把这个对象丢弃了,这种语法叫做 “装箱”,在其他面向对象语言里也有(如 C#)。

  • JS继承:

    https://www.cnblogs.com/Leophen/p/11401734.html

    • 原型链继承;
    • 借助构造函数继承;
    • 组合继承;
    • 原型式继承;
    • 寄生式继承;
    • 寄生组合式继承。
  • JS跨域:

    • 第一种方式:jsonp请求;jsonp的原理是利用

/ES6 class区别](https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/20):**

  1. es6的class的声明会提前,但不会初始化赋值,类似letconst,会存在暂时性死区(TDZ);

  2. es6的class声明的内部会启用严格模式;

  3. es6的class的所有方法(包括静态方法和实例方法)都是不可枚举的;

  4. es6的class的多有方法(包括静态方法和实例方法)都没有原型对象prototype,所以也没有[[construct]],不能使用new来调用;

  5. es6必须使用new来调用class

  6. es6的class内部无法重写类名。

    function Bar() {
      Bar = 'Baz'; // it's ok,重写后Bar就为string,不再是function(前提是调用一次)
      this.bar = 42;
    }
    const bar = new Bar();
    // Bar: 'Baz'
    // bar: Bar {bar: 42}  
    
    class Foo {
      constructor() {
        this.foo = 42;
        Foo = 'Fol'; // TypeError: Assignment to constant variable
      }
    }
    const foo = new Foo();
    Foo = 'Fol'; // it's ok
    

你可能感兴趣的:(前端,JavaScript,找工作)