JS篇

  1. 变量提升遇到的一些简单的code题
  1. 说一下对闭包的理解,以及在什么场景下会用到闭包?

什么是闭包
函数嵌套函数,内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制所回收
闭包的好处
希望一个变量长期驻扎在内存当中
避免全局变量的污染
私有成员的存在
用法
模块化代码
在循环中直接找到对应元素的索引

  1. 说一下你对原型与原型链的了解度,有几种方式可以实现继承,用原型实现继承有什么缺点,怎么解决?

原型对象是构造函数的一个实例(Person.prototype.constructor)
所有的原型对象都有一个constructor属性,指向prototype属性所在的函数

Person.prototype.constructor == Person;
person1.proto == Person.prototype;
person1.constructor == Person;

原型链
由于proto是任何对象都有的属性,而js里万物皆对象,所以会形成一条—proto连起来的链条,递归访问proto必须最终到头,并且值为null

  1. iframe的缺点有哪些
    1、页面样式调试麻烦,出现多个滚动条;
    2、浏览器的后退按钮失效;
    3、过多会增加服务器的HTTP请求;
    4、小型的移动设备无法完全显示框架;
    5、产生多个页面,不易管理;
    6、不容易打印;
    7、代码复杂,无法被一些搜索引擎解读。

  2. ajax原生写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var XHR = window.XMLHttpRequest ? (new XMLHttpRequest()) : (new ActiveXObject("Microsoft.XMLHTTP")) ;

//XHR = new XMLHttpRequest(); // 非IE内核
//XHR = new ActiveXObject("Microsoft.XMLHTTP"); ie7及以上版本

if(XHR){
XHR.open("get",url);
XHR.onreadystatechange = function () {
// readyState值说明
// 0,初始化,XHR对象已经创建,还未执行open
// 1,载入,已经调用open方法,但是还没发送请求
// 2,载入完成,请求已经发送完成
// 3,交互,可以接收到部分数据

// status值说明
// 200:成功
// 404:路径错误
// 500:服务器内部错误
if (XHR.readyState == 4 && XHR.status == 200) {
//XHR.responseText 返回的数据
// 主动释放,JS本身也会回收的
XHR = null;
}
};
XHR.send();
}
  1. 为什么会有同源策略
    同源策略是浏览器上为安全性考虑实施的非常重要的安全策略。
    何谓同源:
    URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。
    同源策略:
    浏览器的同源策略,限制了来自不同源的”document”或脚本,对当前”document”读取或设置某些属性。 (白帽子讲web安全[1])
    从一个域上加载的脚本不允许访问另外一个域的文档属性。
  1. 跨域的方式有哪几种?
    1.document.domain=’www.baidu.com' 子域和子域之间
    2.服务端代理:XMLHttpRequest代理文件
    3.script标签:jsonp
    4.window.postMessage()
    5.webSocket
  1. 如何判断两个对象相等

  2. 对象的深拷贝
    var newObject = JSON.parse(JSON.stringify(oldObject))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function deepClone(values) {
var copy;

// Handle the 3 simple types, and null or undefined
if (null == values || "object" != typeof values) return values;

// Handle Date
if (values instanceof Date) {
copy = new Date();
copy.setTime(values.getTime());
return copy;
}

// Handle Array
if (values instanceof Array) {
copy = [];
for (var i = 0, len = values.length; i < len; i++) {
copy[i] = deepClone(values[i]);
}
return copy;
}

// Handle Object
if (values instanceof Object) {
copy = {};
for (var attr in values) {
if (values.hasOwnProperty(attr)) copy[attr] = deepClone(values[attr]);
}
return copy;
}

throw new Error("Unable to copy values! Its type isn't supported.");
}
  1. 从发送一个url地址到返回页面发生了什么
    DNS解析

    TCP连接

    发送HTTP请求

    服务器处理请求并返回HTTP报文

    浏览器解析渲染页面

    连接结束

  2. 用一句代码写出下面函数的函数体,实现输出三个数中的最大值

    1
    2
    3
    4
    5
    6
    7
    function maxNumber(a,b,c){
    return a>b?(a>c?a:c):(b>c?b:c)
    }

    a大于b => a 或者 b
    a大于c => a 或者 c
    b大于c => b 或者 c
  1. var str = ‘abdcdefg’ 请至少用两种方法在str中截取字符串‘cd’, 并在控制台输出
    1
    2
    3
    4
    var str = 'abcdefg';
    console.log(str.substr(2,2))
    console.log(str.substring(2,4))
    console.log(str.slice(2,4))
  1. var arr = [1,3,2,4,2,22,1] 消除arr的重复项,并按从小到大的顺序排序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    var arr = [1,3,2,4,2,22,1];
    var arr1 = arr.sort();
    var arr2 = [];
    for(var i=0;i<arr1.length;i++){
    if(arr1[i] !== arr2[arr2.length - 1]){
    arr2.push(arr1[i])
    }
    }
    console.log(arr2)

    function fn(arr){
    arr.sort();
    var a = [arr[0]];
    console.log(a)
    for(var i=0;i<arr.length;i++){
    if(arr[i] !== a[a.length-1]){
    a.push(arr[i])
    }
    }
    return a;
    }

    function fn2(arr){
    var a = [arr[0]];
    for(var i=1;i<arr.length;i++){
    if(arr.indexOf(arr[i]) == i){
    a.push(arr[i])
    }
    }

    return a
    }
    eq(a)
    数组排序
    function eq(arr){
    if(arr.length <=1){
    return arr;
    }
    var num = Math.floor(arr.length/2)
    var numValue = arr.splice(num, 1);
    var left = [];
    var right = [];
    for(var i=0;i<arr.length;i++){
    if(arr[i]<numValue){
    left.push(arr[i])
    }else{
    right.push(arr[i])
    }
    }
    return eq(left).concat([numValue]),eq(right)
    }
  2. 在字符串类型的原型上扩展一个myRest方法,实现目标字符串倒置

    1
    2
    3
    4
    5
    function myRest(str){
    var arr = str.split('');
    arr.reverse();
    return arr.join('')
    }
  1. 写出下面代码的输出:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    for(var i=0;i<3;i++){
    setTimeout(function(){
    console.log(i)
    },1000)
    }
    // 3;
    // 3;
    // 3;

  1. 下面代码输出什么内容;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var name = 'window';
    var object = {
    name: 'object',
    getName: function(){
    console.log(this.name);
    return function(){
    console.log(this.name);
    }
    }
    }
    object.getName()();

    先打印出了object 然后是window
    this的指向改变
  2. 下面代码控制台会有几次输出,分别输出什么

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    console.log(ppx);
    var ppx = "x";
    function f1(){
    console.log(ppx);
    var ppx = 'y';
    function ppx(){
    console.log(ppx);
    }
    console.log(ppx);
    ppx();
    }
    f1();

    // undefined function ppx(){} y 报错
  3. 下面代码在控制台输出什么

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    (function(){
    console.log(1);
    setTimeout(function(){
    console.log(2)
    },1000);
    setTimeout(function(){
    console.log(3)
    },0);
    console.log(4)
    })()
    // 1 4 3 2
1
2
3
4
5

var a = 100;
var b = a;
a = 200;
console.log(a)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

function Elem(id){
this.elem = document.getElementById(id);
}
Elem.prototype.html = function(val){
var elem = this.elem;
if(val){
elem.innerHTML = val
return this
}else{
return elem.innerHTML
}
}

Elem.prototype.on = function(type, fn){
var elem = this.elem
elem.addEventListener(type, fn)
return this
}
var div1 = new Elem('div1')
console.log(div1.html())

div1.html('<p>hell world<p>')
div1.on('click',function(){
alert('clicked')
})