前端面试杂记 -- 攻克前端面试(javascript)

1.switch语句部分和case语句部分都可以使用表达式

swith(1+3){
    case 2+2 :
        console.log("表达式执行了...");
    break;
    default:
        console.log("表达式没有执行...");
}
// 结果   表达式执行了...

2.switch语句和case语句部分进行结果比较时采用的是严格的比较(===) 而不是(==)既不会发生类型转化

var x = 1;
switch (x) {  
case true:    console.log('x 发生类型转换');    
break;  
default:    console.log('x 没有发生类型转换');
}// x 没有发生类型转换

3.label标签

javascript语言允许,语句的前面带有标签,相当于定位符,用于调转到程序的任意位置。标签的格式如下  label:语句。

标签可以是任意的标识符,但不能是保留字,语句部分可以是任意语句。

标签通常与break语句和continue语句配合使用,跳出特定的循环。

top:  for (var i = 0; i < 3; i++){   
 for (var j = 0; j < 3; j++){    
   if (i === 1 && j === 1) break top;    
     console.log('i=' + i + ', j=' + j);
    }
  }// i=0, j=0// i=0, j=1// i=0, j=2// i=1, j=0

上面代码为一个双重循环区块,break命令后面加上了top标签(注意,top不用加引号),满足条件时,直接跳出双层循环。如果break语句后面不使用标签,则只能跳出内层循环,进入下一次的外层循环。

标签也可以用于跳出代码块。

foo: {  console.log(1);  
break 
foo;  console.log('本行不会输出');
}console.log(2);// 1// 2

上面代码执行到break foo,就会跳出区块

continue语句也可以与标签配合使用。

top:  
for (var i = 0; i < 3; i++){    
for (var j = 0; j < 3; j++){     
 if (i === 1 && j === 1) continue top;      
console.log('i=' + i + ', j=' + j);
    }
  }
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
// i=2, j=0

上面代码中,continue命令后面有一个标签名,满足条件时,会跳过当前循环,直接进入下一轮外层循环。如果continue语句后面不使用标签,则只能进入下一轮的内层循环。

4.整数和浮点数

在javascript中,所有的数字都是以64位浮点数的形式储存,即使整数也是如此。所以1和1.0是相同的,是同一个数字

1 === 1.0 // true

这就是说,JavaScript 语言的底层根本没有整数,所有数字都是小数(64位浮点数)。容易造成混淆的是,某些运算只有整数才能完成,此时 JavaScript 会自动把64位浮点数,转成32位整数,然后再进行运算。

由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心

0.1 + 0.2 === 0.3
// false
0.3 / 0.1
// 2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1)
// false

5.删除数组中的指定的元素  翻遍所有的API也没有现有的方法

let arr = [1, 3, 4, 6, 7, 8, 9, "xixi", "ysys"];
 Array.prototype.remove = function (val) {
            var index = this.indexOf(val);
            if (index > -1) {
                this.splice(index, 1);
            }
        };
arr.remove("xixi");
console.log(arr)//[1, 3, 4, 6, 7, 8, 9, "ysys"]

6.容易入坑的隐式转换

false == ""  // true
false == []  // true
false == {}  // false
"" == 0      // true
"" == []     // true
"" == {}     // false
0 == []      // true
0 == {}      // false
0 == null    // false

Number({})   // NaN
Number([])   // 0
Number(null) // 0

7.ES6的let和const都是新引入的关键字,他们不会被提升,而且是块级作用域。

 let g1 = 'global 1'
        let g2 = 'global 2'
        {
            /* Creating a new block scope */
            g1 = 'new global 1'
            let g2 = 'local global 2'
            console.log(g1)
            // 'new global 1'
            console.log(g2)
            // 'local global 2'
            //console.log(g3)
            // ReferenceError: g3 is not defined
            let g3 = 'I am not hoisted';
        }
        console.log(g1)
        // 'new global 1'
        console.log(g2)
        // 'global 2'
        console.log(g3)
        // Uncaught ReferenceError: g3 is not defined

8.const也是面试中的一个坑,我们都常说使用const声明的变量是常量,它的值不可以更改。准确的说他不可以被重新赋值,但是可以更改。

const tryMe = 'initial assignment';
tryMe = 'this has been reassigned';  
// TypeError: Assignment to constant variable.
// You cannot reassign but you can change it…
const array = ['Ted', 'is', 'awesome!'];
array[0] = 'Barney';
array[3] = 'Suit up!';
console.log(array);     
// [“Barney”, “is”, “awesome!”, “Suit up!”]
const airplane = {};
airplane.wings = 2;
airplane.passengers = 200;
console.log(airplane);   
// {passengers: 200, wings: 2}

9.使用三种方式实现深度克隆(什么三种?我一种都不知道?没错是的,三种方式)

   如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,如果B没变,那就是深拷贝。

第一种 (方式一)
function deepClone(origin, target) {
    var target = target || {},
        toStr = Object.prototype.toString,
        arrStr = "[object Array]";
    for (var prop in origin) {
        if (origin.hasOwnPropertype(prop)) {
            if (origin[prop] !== "null" && typeof (origin[prop]) == 'object') {
                if (toStr.call(origin[prop]) == arrStr) {
                    target[prop] = [];
                } else {
                    target[prop] = {};
                }
            } else {
                target[prop] = origin[prop];
            }
        }
    }
    return target;
}

第一种 (方式二)
function deepClone(obj){
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                //判断obj子元素是否为对象,如果是,递归复制
                if(obj[key]&&typeof obj[key] ==="object"){
                    objClone[key] = deepClone(obj[key]);
                }else{
                    //如果不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}  
第二种 使用序列化和反序列化
function deepClone(obj){
    let _obj = JSON.stringify(obj),
        objClone = JSON.parse(_obj);
    return objClone
}   
第三种 使用JQ的extend()方法
/*$.extend( [deep ], target, object1 [, objectN ] )

deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝

target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。

object1  objectN可选。 Object类型 第一个以及第N个被合并的对象。**/
let a=[0,1,[2,3],4],
    b=$.extend(true,[],a);
a[0]=1;
a[2][0]=1;
console.log(a,b);

 

10.本地存储

###本地存储异同

- 共同点

- localStorage和sessionStorage和cookie共同点

  - 同域(同源策略)限制:同源策略:请求与响应的 协议、域名、端口都相同 则时同源,否则为 跨源/跨域
  - 存储的内容都会转为字符串格式
  - 都有存储大小限制

- localStorage和sessionStorage共同点

  - API相同
  - 存储大小限制一样基本类似
  - 无个数限制

- 不同点

- localStorage

  - 没有有效期,除非删除,否则一直存在
  - 同域下页面共享
  - 支持 storage 事件

- sessionStorage

  - 浏览器关闭,自动销毁
  - 页面私有
  - 不支持 storage 事件

- cookie

  - 浏览器也会在每次请求的时候主动组织所有域下的cookie到请求头 cookie 中,发送给服务器端
  - 浏览器会主动存储接收到的 set-cookie 头信息的值
  - 可以设置 http-only 属性为 true 来禁止客户端代码(js)修改该值
  - 可以设置有效期 (默认浏览器关闭自动销毁)(不同浏览器有所不同)
  - 同域下个数有限制,最好不要超过50个(不同浏览器有所不同)
  - 单个cookie内容大小有限制,最好不要超过4000字节(不同浏览器有所不同)

 

 

 

 

 

 

 

 

 

持续更新中...

  • 10
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值