面试题整理

1. ['1', '2', '3'].map(parseInt)输出结果

['1', '2', '3'].map(parseInt);    // [1,NaN,NaN]

这道题需要理解两个点:

①.parseInt(string, radix)

接收两个参数,第一个表示被处理的值(字符串),第二个表示为解析时的基数。
radix 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。

②.代码实际执行的以下代码

['1', '2', '3'].map((item, index) => {
    return parseInt(item, index)
})
parseInt('1', 0)   // 1
parseInt('2', 1)   // NaN
parseInt('3', 2)   // NaN, 3 不是二进制 string要符合基数的规范

同样的经典题

['10','10','10','10','10'].map(parseInt)
// =>
parseInt('10', 0) // 10
parseInt('10', 1) // NaN
parseInt('10', 2) // 2, 
parseInt('10', 3) // 3, 
parseInt('10', 4) // 4, 

// 所以['10','10','10','10','10'].map(parseInt)  => [10,NaN,2,3,4];

 

2.实现一个函数:输入一个整数,求该整数的二进制表达中有多少个1?

方法1:

function fun1(num){
    return new Number(num).toString(2).split('').filter(item => item == 1).length 
}
fun1(9)   // 2

方法2:

function fun2(num){
    var len = 0;
    while(num > 0) {
        var a = num % 2;
        num = (num - a) / 2;
        if(a === 1) {
            len++;
        }
    }
    return len;
}
fun2(9)

 

3.实现一个函数:给定一个字符串,找出出现次数最多的字符及次数

function getMaxStr(str) {
    let json = {};
    for(let i =0;i<str.length;i++){
        if(json[str[i]]) {
            json[str[i]]++
        }else {
            json[str[i]] = 1;
        }
    }
    let maxNum = 0;
    let maxStr = '';
    for(let key in json){
        if(json[key] > maxNum){
            maxNum = json[key];
            maxStr = key;
        }
    }
    console.log(`出现次数最多的字符是${maxStr},出现次数是${maxNum}`)
}
getMaxStr('ddddssfes')    // 出现次数最多的字符是d,出现次数是4

 

4.this指向理解

var a = 1;
var obj = {
    a: 2,
    func1: ()=>{console.log(this.a)},
    func2: function(){console.log(this.a)}
}

var obj2 = {a: 3};
console.log(obj.func1())    // 1
console.log(obj.func2())    // 2
obj.func2.apply(obj2)       // 3
var newFunc = obj.func2;
newFunc()    //1

tips: 函数直接被调用时this则指向window,函数作为某对象的方法调用时,this指向该对象,而箭头函数没有执行上下文,取决于他就近的外面的一层非箭头函数的函数。

箭头函数的this看外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window

 

5.下面三段代码分别输出什么?并且什么时候输出什么?

for (var i = 0; i < 5; i++) {
  setTimeout(function () {
    console.log(i)
  }, 1000 * i)
} 
// 在极短的一段时间内输出5,随后每隔一秒输出一个5
// 5 5 5 5 5
// for循环结束后才到宏观任务setTimeout,这时候i的值已经变为5了
for (let i = 0; i < 5; i++) { setTimeout(function () { console.log(i) }, 1000 * i) } // 在极短的一段时间内输出0,随后每隔一秒结果加1 // 0 1 2 3 4
// let i 是块作用域
for (var i = 0; i < 5; i++) { (function (i) { setTimeout(function () { console.log(i) }, 1000 * i) })(i) } // 在极短的一段时间内输出0,随后每隔一秒结果加1 // 0 1 2 3 4
// 立即执行函数,创建了属于自己的作用域,因此每一次执行都是不同的i

事件运行机制

 

6.自由变量理解 

var x = 10
function fn() {
  console.log(x)
}
function show(f) {
  var x = 20
  (function() {
    f() //10,而不是20
  })()
}
show(fn)

什么是自由变量? --当前作用域没有定义的变量,这成为自由变量 

var a = 100
function fx() {
    var b = 200
    console.log(a) // 这里的a在这里就是一个自由变量
    console.log(b)
}
fx()

在fn函数中,取自由变量x的值时,要到哪个作用域中取?--要到创建fn函数的那个作用域中取,无论fn函数将在哪里调用。

要到创建这个函数的那个域。作用域中取值,这里强调的是“创建”,而不是“调用”,切记切记——其实这就是所谓的"静态作用域"。

 

7. 闭包的理解

function outer(){
  var num=0;//内部变量
  return function add(){//通过return返回add函数,就可以在outer函数外访问了
      num++;//内部函数有引用,作为add函数的一部分了
      console.log(num);
  };
}
var func1=outer();
func1();
//实际上是调用add函数, 输出1 func1();//输出2 因为outer函数内部的私有作用域会一直被占用 var func2=outer(); func2();// 输出1 每次重新引用函数的时候,闭包是全新的。 func2();// 输出2

一般情况下,函数执行会形成一个新的私有的作用域,当私有作用域中的代码执行完成后,我们当前作用域都会主动的进行释放和销毁。但当遇到函数执行返回了一个引用数据类型的值,并且在函数的外面被一个其他的东西给接收了,这种情况下一般形成的私有作用域都不会销毁。

所谓内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。闭包不能滥用,否则会导致内存泄露,影响网页的性能。闭包使用完了后,要立即释放资源,将引用变量指向null。

 

 

 

 

 

 

 

 

未完,待续...

 

转载于:https://www.cnblogs.com/kewenxin/p/11535611.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值