JS例题。


在这里插入图片描述

前言:这些都是自己日常收藏的觉得比较复杂一点、题目挺绕的、大家日常容易忽略的小知识点的题目。🥺

1. 👩🏻‍💻下面的两个哪个是无限循环的??(答案:第二个无限循环)

//第一个:
function ball(i) {
  i=3;
  return i+2
}
for (var i =0; i < 10; i++){
  console.log(ball(i))
}
//第二个:
function bar(a) {
  i = 3; 
  console.log( a + i );
}
for (var i=0; i<10; i++) {
  bar( i * 2 ); 
}

第一个、?在这里插入图片描述
解析:var定义的变量会存在变量提升,则会提升到最前端。function()函数定义并不会执行,当执行for循环后;
i = 0 执行ball(i),将i作为形参传入ball函数,此时由于i = 3,会先在该运算环境中寻找i,在arguments中找到i,则将3赋值给ireturn 3+2 = 5,则console.log(5);我在可以看到下图中我将arguments打印出来的结果。
i = 1,解析过程与i=0过程一样。
…后面的都一样。
在这里插入图片描述
第二个、?在这里插入图片描述
解析:var变量提升,提升到最代码前面;
此时执行第一次循环,i = 0,然后执行bar循环,i * 2 = 0传入函数中,由于实参是a,此时a = 0,执行i = 3,此时在改作用域并没有找到i,就会往外找一层,此时找到i,改变值,全局的i变为了3,return 0 + 3 =3;
第二次循环,此时的i = 3,先执行i++i = 4满足条件,再执行ball函数,与第一次相同操作,i = 3会将全居i变为3,此时a = 4*2 = 8,return 8+4 = 11
第三次循环,此时的i = 3,执行i++,i=4满足条件,…(与第二步一样的操作)

2. 【原型链方法】👩‍💻下面的题输出结果是什么??

function Foo() {
    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
Foo.prototype.a = function() {
    console.log(3)
}
Foo.a = function() {
    console.log(4)
}
Foo.a();
let obj = new Foo();
obj.a();
Foo.a();

执行结果:?
在这里插入图片描述

3. 【[‘1’, ‘2’, ‘3’].map(parseInt)】👩🏼‍💻下面输出结果是什么??

console.log(['1', '2', '3'].map(parseInt));

执行结果:?
在这里插入图片描述
解析:map函数的回调函数会自动传入三个参数,数组元素,元素索引,数组本身,此时parseInt需要两个参数,一个作为字符串,第二个参数会作为基数;
所以第一次,parseInt函数会接受两个参数,(1, 0),此时1作为字符串,0作为基数,根据下图MDN的解释,当0作为基数,则1会按照10进制解析,返回1;
第二次循环,传入参数(2, 1),基数为1(1进制)表示的数中,最大值小于2,所以无法解析,返回NaN;
第三次循环,传入参数(3, 2),基数是2(2进制)表示的数应该要小于2,所以无法解析,返回NaN。

在这里插入图片描述
戳这里,map函数详解 | 戳这里,parseInt函数详解

4. 【[1,5,20,10].sort(function(a, b){return a - b})】👩🏽‍💻以下的执行结果是什么??

[1,5,20,10].sort(function(a, b){return a - b}); //[1, 5, 10, 20]

解析:一下是MDN关于sort(compareFunction(a,b))的详解;
在这里插入图片描述

5. 【原型链】👩🏾‍💻以下关于原型链的问题

var a = new String('hah');
var b = new String('hah');
var c = 'hah'
console.log(a == b); //false
console.log(a == c); //true
console.log(a === c);//false

解析:

  • 两个对象是不相等的
  • 等于只会判断值是否相等,此时a和c的值是相等的
  • 三等需判断值和类型都是否相等

6. 【变量提升】👩🏿‍💻以下输出什么?

<script>
    console.log(fun)
    console.log(person)
</script>
<script>
    console.log(person)
    console.log(fun)
    var person = "Eric";
    console.log(person)
    function fun() {
        console.log(person)
        var person = "Tom";
        console.log(person)
    }
    fun()
    console.log(person)
</script>

在这里插入图片描述

  • 报错 :由于fun没有定义,则会报错,且会阻断执行,所以第二个console.log不会输出
  • console.log(person); console.log(fun)的输出:到第二个script,是一个执行域,所以进行变量提升,将func和person提升到最前面,变量不会赋值,但是函数声明式会将其函数体一同提升(函数表达式不会提升函数体),则输出undefined和一个函数体。
  • console.log(person)此时已经赋值,则输出Eric
  • 执行func(),此时发现又是一个执行域,则进行变量提升,将var person,提升至前面,则console.log(person)输出undefined,赋值后会输出Tom
  • 当函数执行结束后,则该函数体的person变量被回收,则console.log(person)会找到该执行域的person,此时为Eric

7. 【变量赋值】🍩判断下面输出是什么?

  • 例子1
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
console.log(a.x);
console.log(b);

在这里插入图片描述
在这里插入图片描述

  • 例子2
let a = 12,
  b = 12;
function fn() {
  // console.log(a, b); // Uncaught ReferenceError: Cannot access 'a' before initialization at fn
  console.log(b); // 12 获取的全局变量的b
  let a = (b = 13); // 将13赋值给全局变量b,且定义了一个fn的局部变量a,赋值给13
  console.log(a, b); // 13 13
}
fn();
console.log(a, b); // 12 13 // 全局变量a,b
  • 例子3
let i = 1;
let fn = (i) => (n) => console.log(n + ++i);
let f = fn(1);
f(2); // 4 fn的i为1,n为2,函数先执行i+1,再输出2+2=4
fn(3)(4); // 8 fn的i为3,n为4,函数先执行i+1,再输出4+4=8
f(5); // 8 fn的i受f(2)的影响已经为2,n为5,函数先执行i+1,再输出5+3=8
console.log(i); // 1
  • 例子4
var n = 0;
function a() {
  var n = 10;
  function b() {
    n++;
    console.log(n);
  }
  b();
  return b;
}
var c = a(); // 11 b函数中的n为局部变量10
c(); // 12 b函数中的n形成闭包,n为11
console.log(n); // 全局变量n不变,为0

8. 【闭包】 🥟判断以下代码的输入输出?

借鉴有关闭包的文章

function fun(n,o) {
  console.log(o);
  return {
    fun:function(m){
      return fun(m,n);
    }
  };
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1); c.fun(2); c.fun(3);

在这里插入图片描述
解析:

  • 第一个比较好理解就是返回fun(0)之后a的值就是fun: function(){...}函数,该函数内部m是后续传入的值,n是利用闭包,实现父函数的值n为第一次传入的值0;
  • 第二个链式调用,首先是未定义返回undefined,返回的是func function(){...}; n = 0,fun(1)调用之后,m=1; n=0;,fun(2)返回的是函数中m=2, n=1,fun(3)调用之后m=3, n=2
  • 按照上面的推论

其实不难,就是需要注意m,n值的变化以及理解闭包。

9.🙆🏿‍♀️实现一个二进制加法,输入输出均为二进制字符串

binaryAdd('1010', '111')  // '10001'
function binaryAdd(num1, num2) {
	// 两个字符创最大的长度
	let maxLen = Math.max(num1.length, num2.length)
	// 字符串补位并转为数组
	let arr1 = num1.padStart(maxLen, '0').split('')
	let arr2 = num2.padStart(maxLen, '0').split('')
	// 记录是否有进位
	let tmp = 0
	// 存储结果
	let res = []
	while(arr1.length) {
		// 从末位往前逐位相加
		let sum = +arr1.pop() + +arr2.pop() + tmp
		// 如果和大于1,则需要往前进一位
		if (sum > 1) {
			tmp = 1
			res.unshift(sum % 2)
		} else {
			tmp = 0
			res.unshift(sum)
		}
	}
	// 如果还存在进位,则需要往前补一位
	if (tmp > 0) res.unshift(tmp)
	return res.join('')
}

10. 【变量提升/静态方法/实例方法/原型方法调用】

function Foo() {
  getName = function () {
    console.log(1);
  };
  return this;
}
Foo.getName = function () {
  console.log(2);
};
Foo.prototype.getName = function () {
  console.log(3);
};
var getName = function () {
  console.log(4);
};
function getName() {
  console.log(5);
}

Foo.getName(); // 2 解析:调用函数的静态方法
getName(); // 4 解析:函数表达式会覆盖函数声明式方法
Foo().getName(); // 1 解析:调用函数自身的方法
getName(); // 1 解析: 受前一行代码执行影响相当于调用this.getName(), 其中this指向window,因为Foo方法里面定义getName的时候没有声明, 所以变成了全局变量
new Foo.getName(); // 2 解析:相当于执行new (Foo.getName)()
new Foo().getName(); // 3 解析:调用函数的实例方法, 相当于执行(new Foo()).getName()
new new Foo().getName(); // 3 解析:相当于执行new (new Foo()).getName)()
// 操作运算符的优先级: () > new > .

11. 将对象当数组使用,调用push()

var obj = {
  2: 3,
  3: 4,
  length: 2,
  push: Array.prototype.push,
};
obj.push(1);
obj.push(2);
console.log(obj);
// {2: 1, 3: 2, length: 4, push: ƒ} 解析:因为对象的length为2,所以push 1 2 会覆盖2 3 的值

// 对比
var obj = {
  length: 2,
  push: Array.prototype.push,
};
obj.push(1);
obj.push(2);
obj.push(3);
console.log(obj);
// {2: 1, 3: 2, 4: 3, length: 5, push: ƒ}

12. 【递归/微任务/宏任务】

function fn() {
  fn();
}
fn(); // Uncaught RangeError: Maximum call stack size exceeded

var num = 0;
function fn() {
  console.log(num++);
  setTimeout(fn, 1000);
}
fn(); // 1 2 3 ...可以正常执行,为什么?
// 解析:原因是因为setTImeout属于异步宏任务,不在主线程栈内存中

13. 【eventloop】promise常见执行顺序题

eventloop

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值