- 介绍一下 JS 的基本数据类型。
1 | Undefined、Null、Boolean、Number、String、Symbol(ES6新增) |
- 如何控制alert中的换行?
1 | \n alert(“p\np”); |
- null 和 undefined 有何区别?
null 表示一个对象被定义了,值为“空值”;
undefined 表示不存在这个值。
typeof undefined //“undefined”
undefined :是一个表示”无”的原始值或者说表示”缺少值”,就是此处应该有一个值,但是还没有定义。当尝试读取时会返回 undefined; 例如变量被声明了,但没有赋值时,就等于undefined。
typeof null //“object” null : 是一个对象(空对象, 没有任何属性和方法); 例如作为函数的参数,表示该函数的参数不是对象;
注意: 在验证null时,一定要使用 === ,因为 == 无法分别 null 和 undefined
- call和apply,bind的作用是什么?区别是什么?
call和apply的功能基本相同,都是实现继承或者转换对象指针的作用;
唯一不通的是前者参数是罗列出来的,后者是存到数组中的;
call或apply功能就是实现继承的;与面向对象的继承extends功能相似;但写法不同;
语法:
.call(对象[,参数1,参数2,….]);//此地参数是指的是对象的参数,非方法的参数;
.apply(对象,参数数组)//参数数组的形式:[参数1,参数2,……]通过bind改变this作用域会返回一个新的函数,这个函数不会马上执行
- push()-pop()-shift()-unshift()分别是什么功能?
push 方法 将新元素添加到一个数组中,并返回数组的新长度值。 var a=[1,2,3,4]; a.push(5);
pop 方法 移除数组中的最后一个元素并返回该元素。 var a=[1,2,3,4]; a.pop();
shift 方法 移除数组中的第一个元素并返回该元素。 var a=[1,2]; alert(a.shift());
unshift 方法 将指定的元素插入数组开始位置并返回该数组。
- new 操作符具体干了什么呢?
1、创建了一个空对象
var obj = new object();
2、设置原型链
obj.proto = fn.prototype;
3、让fn的this指向obj,并执行fn的函数体
var result = fn.call(obj);
4、判断fn的返回值类型,如果是值类型,返回obj。如果是引用类型,就返回这个引用类型的对象
if (typeof(result) == “object”){
fnObj = result;
} else {
fnObj = obj;
}
- 闭包
一句话可以概括:闭包就是能够读取其他函数内部变量的函数,或者子函数在外调用,子函数所在的父函数的作用域不会被释放。
- 如何理解 JavaScript 的原型
所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(null除外)
所有的引用类型(数组、对象、函数),都有一个proto属性,属性值是一个普通的对象
所有的函数,都有一个prototype属性,属性值也是一个普通的对象
所有的引用类型(数组、对象、函数),proto属性值指向它的构造函数的prototype属性值
当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的proto(即它的构造函数的prototype)中寻找。
- JavaScript 中,有一个函数,执行对象查找时,永远不会去查找原型,这个函数是哪个?
hasOwnProperty
//
JavaScript 中 hasOwnProperty 函数方法是返回一个布尔值,指出一个对象是否具有指定名称的属性。此方法无法检查该对象的原型链中是否具有该属性;该属性必须是对象本身的一个成员。
//
使用方法:object.hasOwnProperty(proName)其中参数object是必选项,一个对象的实例。proName是必选项,一个属性名称的字符串值。
//
如果 object 具有指定名称的属性,那么JavaScript中hasOwnProperty函数方法返回 true,反之则返回 false。
- JavaScript 有几种类型的值?能否画一下它们的内存图?
- 栈:原始数据类型(Undefined,Null,Boolean,Number,String)
- 堆:引用数据类型(对象、数组、函数) 两种类型的区别:
//存储位置不同
- 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
- 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
- JavaScript 如何实现继承?
1 | ES5 |
- Ajax 是什么?如何创建一个 Ajax ?
ajax的全称:Asynchronous Javascript And XML,异步传输+js+xml。
所谓异步,在这里简单地解释就是:向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果它自己会根据设定进行后续操作,与此同时,页面是不会发生整页刷新的,提高了用户体验。
//
(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象
(2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息
(3)设置响应HTTP请求状态变化的函数
(4)发送HTTP请求
(5)获取异步调用返回的数据
(6)使用JavaScript和DOM实现局部刷新
1
2
3
4
5
6
7
8
9 > var xmlHttp = new XMLHttpRequest();
> xmlHttp.open("GET",demo.php,"true");
> xmlHttp.send();
> xmlHttp.onreadystatechange = function() {
> if(xmlHttp.readyState === 4 & xmlHttp.status=== 200){
> ...
> }
> }
>
前端中的事件流
HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件onclick、页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念。
什么是事件流:事件流描述的是从页面中接收事件的顺序,DOM2级事件流包括下面几个阶段。
- 事件捕获阶段
- 处于目标阶段
- 事件冒泡阶段
addEventListener:addEventListener 是DOM2 级事件新增的指定事件处理程序的操作,这个方法接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
IE只支持事件冒泡。
如何让事件先冒泡后捕获
在DOM标准事件模型中,是先捕获后冒泡。但是如果要实现先冒泡后捕获的效果,对于同一个事件,监听捕获和冒泡,分别对应相应的处理函数,监听到捕获事件,先暂缓执行,直到冒泡事件被捕获后再执行捕获之间。
- 事件委托
- 简介:事件委托指的是,不在事件的发生地(直接dom)上设置监听函数,而是在其父元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判断事件发生元素DOM的类型,来做出不同的响应。
- 举例:最经典的就是ul和li标签的事件监听,比如我们在添加事件时候,采用事件委托机制,不会在li标签上直接添加,而是在ul父元素上添加。
- 好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发机制。
- 如何实现sleep的效果(es5或者es6)
(1)while循环的方式
1
2
3
4
5
6
7> function sleep(ms){
> var start=Date.now(),expire=start+ms;
> while(Date.now()<expire);
> console.log('1111');
> return;
> }
>
执行sleep(1000)之后,休眠了1000ms之后输出了1111。上述循环的方式缺点很明显,容易造成死循环。
(2)通过promise来实现
1
2
3
4
5
6
7
8
9
10
11
12
13 function sleep(ms){
var temple=new Promise(
(resolve)=>{
console.log(111);setTimeout(resolve,ms)
});
return temple
}
sleep(500).then(function(){
//console.log(222)
})
//先输出了111,延迟500ms后输出222
复制代码
(3)通过async封装
1
2
3
4
5
6
7
8
9
10
11
12 > function sleep(ms){
> return new Promise((resolve)=>setTimeout(resolve,ms));
> }
> async function test(){
> var temple=await sleep(1000);
> console.log(1111)
> return temple
> }
> test();
> //延迟1000ms输出了1111
> 复制代码
>
(4).通过generate来实现
1
2
3
4
5
6
7
8 > function* sleep(ms){
> yield new Promise(function(resolve,reject){
> console.log(111);
> setTimeout(resolve,ms);
> })
> }
> sleep(500).next().value.then(function(){console.log(2222)})
>
- 简单的实现一个promise
首先明确什么是promiseA+规范,参考规范的地址:
如何实现一个promise,参考文章:
1 | function myPromise(constructor){ |
- 请编写一个JavaScript函数 parseQueryString,它的用途是把URL参数解析为一个对象,如:
var url = “http://witmax.cn/index.php?key0=0&key1=1&key2=2″;
1 | function parseQueryString(url){ |
- 如何获取光标的水平位置?
1 | function getX(e){ |
- 如何规避javascript多人开发函数重名问题?
1 | (1) 可以开发前规定命名规范,根据不同开发人员开发的功能在函数前加前缀 |
- AJAX请求总共有多少种CALLBACK
1 | Ajax请求总共有八种Callback |
- 数组去重
1 | 方法一: |
- 快速排序:
1 | function quickSort(arr){ |
- 深克隆原理
1 | Object.clone=function(obj){//深克隆 |
bind函数的实现原理
1 | Function.prototype.bind2=function(obj/*,参数列表*/){ |
- 字符串转数字的方法
js提供了parseInt()和parseFloat()两个转换函数
强制类型转换
ECMAScript中可用的3种强制类型转换如下: Boolean(value)——把给定的值转换成Boolean型; Number(value)——把给定的值转换成数字(可以是整数或浮点数); String(value)——把给定的值转换成字符串。
利用js变量弱类型转换
- 重绘和回流(考察频率:中)
- 重绘:当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
- 回流:当Render Tree(DOM)中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。
- 回流要比重绘消耗性能开支更大。
- 回流必将引起重绘,重绘不一定会引起回流。
- 请给出异步加载js方案,不少于两种
1 | 异步加载方式: |
Promise Promise是 CommonJS 提出来的这一种规范,有多个版本,在 ES6 当中已经纳入规范,原生支持 Promise 对象,非 ES6 环境可以用类似 Bluebird、Q 这类库来支持。 Promise 可以将回调变成链式调用写法,流程更加清晰,代码更加优雅。 简单归纳下 Promise:三个状态、两个过程、一个方法,快速记忆方法:3-2-1 三个状态:pending、fulfilled、rejected 两个过程: pending→fulfilled(resolve) pending→rejected(reject) 一个方法:then 当然还有其他概念,如catch、 Promise.all/race,这里就不展开了。