荐 前端笔试题总结-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数量
-
闭包:
作用:
- 可以读取函数内部的变量
- 可以把变量始终保存在内存中
写法:
- 一个函数(即外部函数)里面包含另一个函数(即内部函数),并且return返回这个内部函数, 然后内部函数在定义内部函数之外的作用域被调用,这时的内部函数就是一个闭包了。
- 内部函数引用了外部函数的变量,这个变量不会被销毁,因为闭包需要这个变量, 所以通过闭包可以访问闭包保存的变量。
局限:
- 因为闭包的变量保存在内存中,内存泄漏,对内存的消耗很大。
闭包常用的地方:
- es5 for循环的事件监听
- 函数里使用了定时器
- 封装许多高级的功能集
-
JS数组对象方法:
-
reflow(回流\重新布局)和repaint(重绘):
-
位置改变->reflow->repaint
-
显示样式改变(颜色等)->repaint
repaint速度明显快于repaint,在开发中要尽量避免reflow,并减少repaint
-
-
可能导致reflow的操作:
- 改变窗口大小
- 改变文字大小
- 内容改变(在输入框中输入内容)
- 激活伪类(如:hover)
- 操作(改变)class属性
- 脚本操作DOM
- 计算
offsetWidth
或offsetHeight
- 设置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
- 先执行字符串拼接运算,得到字符串
"12"
,在进行2个字符串的拼接运算,得到字符串"122"
- 执行
1+ +"2"
时,+"2"
为一元运算符运算,相当于Number()
函数==(注意不是取正运算)==,会将后面的变量先转换为Number再进行运算,所以得到数值2
,在与数值1
相加得到Number3
;再与后面的字符串进行拼接运算,得到字符串结果"32"
-
-
运算符只会执行数值减运算,但运算符两边转换为Number为NaN,所以得到NaN,再与后面的字符串进行拼接运算,得到结果NaN2
- 前段与第3题一致,得到NaN,与后面的数值
2
进行加运算,NaN+2=NaN
,所以结果为NaN
- 先执行字符串拼接运算,得到字符串
"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的劣势:
-
它可能破坏浏览器的后退功能
-
使用动态页面更新使得用户难于将某个特定的状态保存到收藏夹中
Flash的优势:
1.多媒体处理 2.兼容性 3.矢量图形
4.客户端资源调度(容易调用客户端之外的内容,比如摄像头、麦克风等)
Flash的劣势:
1.二进制格式 2.格式私有 3.文件经常会很大,第一次使用的时候需要等待时间 4.性能问题
-
-
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个参数,第一个是要转换为整数的字符串,第二个是进制。
***:***paraseInt使用时,若第一个参数不是字符串,则会将其隐式转换为字符串类型的。
结果为NaN的:
parseInt("") //NaN parseInt(null) //NaN parseInt(undefined) //NaN
-
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:
-
CORE MODULES named othermodule(核心模块)
-
/home/somebody/workspace/node_modules/othermodule. js (当前路径的js)
-
/home/somebody/workspace/node_modules/othermodule/index.js(当前路径的同名文件夹下的index.js)
-
/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对象的属性和方法:
-
字符串与字符串对象:
-
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):**
-
es6的
class
的声明会提前,但不会初始化赋值,类似let
,const
,会存在暂时性死区(TDZ); -
es6的
class
声明的内部会启用严格模式; -
es6的
class
的所有方法(包括静态方法和实例方法)都是不可枚举的; -
es6的
class
的多有方法(包括静态方法和实例方法)都没有原型对象prototype
,所以也没有[[construct]]
,不能使用new
来调用; -
es6必须使用
new
来调用class
; -
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
本文地址:https://blog.csdn.net/DxCaesar/article/details/107381805