06 js面试题整理

186 阅读3分钟

1、写出执行结果并解释原因

function side(arr) {
  arr[0] = arr[2];
}
function a(a, b, c = 3) {
  c = 10;
  side(arguments);
  return a + b + c;
}
let result = a(1, 1, 1);
console.log(result);

结果:12

原因:函数a加了默认值(c=3),转为严格模式,此时参数arguments与参数a、b、c没有绑定关系,即修改c=10不会影响arguments中c的值。最终a函数里a=b=1,c=10,所以1+1+10=12

上述写法等同于:

"use strict"
function side(arr) {
  arr[0] = arr[2];
}
function a(a, b, c) {
  c = 10;
  side(arguments);
  return a + b + c;
}
let result = a(1, 1, 1);
console.log(result);

如果去掉默认值:

function side(arr) {
  arr[0] = arr[2];
}
function a(a, b, c) {
  c = 10;
  side(arguments);
  return a + b + c;
}
let result = a(1, 1, 1);
console.log(result);

结果为21,此时修改c的值会影响arguments,所以a=c=10,a+b+c=10+1+10=21

再看:

let arr = [4,5,6];
function a(array) {
  // 这里arr和array指向内存中的同一个地址,a地址.此时对array进行添加,修改,删除的操作会影响arr
  array[0] = 10;
  // 重新给array赋值,指向了新地址 —— b地址,就切断了与a地址的联系
  // 所以这里重新赋值并不会改变arr的值
  array= [7,8,9] 
}
a(arr)
console.log(arr); // [10,8,9]

js传递参数均为值传递(都是栈内数据的拷贝),但是要分简单数据类型和复杂数据类型(object),简单数据类型传的是值本身 (因为直接把值存在栈内),复杂数据类型传的是对象在内存里面的地址(因为复杂对象存在堆内,所以在栈里存对象所在的堆地址)。

2、写出执行结果并解释原因

var min = Math.min();
max = Math.max();
console.log(min < max);

结果:false

原因:Math.max返回给定的一组数字中的最大值。如果给定的参数中至少有一个参数无法被转换成数字,则会返回 NaN;如果没有参数,返回 Infinity。而Math.min 没有传递参数时返回的是-Infinity。

3、写出执行结果并解释原因

var a = [0];
if (a) {
  console.log(a == true);
} else {
  console.log(a);
}

结果:false

原因:当a出现在if的条件中时,转为布尔值,Boolean([0]) 转为true;而[0] == true比较,当==一边是Object的话,会调用该Object的toString()方法转成字符串(不过在数组的toString方法中会调用自己的join方法),所以当数组从非 primitive 转为 primitive 的时候[0]会先变成"0",string 和 boolean 比较的时候,两个都先转为 number 类型再比较,最后就是 0==1 的比较了,结果即为false。

若:

var a = [1];
if (a) {
  console.log(a == true);
} else {
  console.log(a);
}

结果为true,因为[1]隐式调用join转为"1",Number(1) == Number(true)结果为true

[Array.prototype.toString](262.ecma-international.org/12.0/#sec-o…)

!会把值转为布尔值

4、写出执行结果并解释原因

(function () {
  var a = (b = 5);
})();

console.log(b); 
console.log(a); 

结果:5 Uncaught ReferenceError: a is not defined

原因:因为a在函数内部使用var声明,所以a属于局部变量(若去掉var则为全局变量,可以打印出a的值)而b属于全局变量。

注意:如果在严格模式下,输出b时就会报错,错误结果为Uncaught ReferenceError: b is not defined;因为严格模式下,需要显示的引用全局作用域。因此需要写成:

(function () {
  "use strict";
  var a = (window.b = 5);
  // 等同于
  //var a = window.b = 5;
})();
console.log(b); // 5

5、写出执行结果并解释原因

var company = {
  address: "beijing",
};
var yideng = Object.create(company);
console.log(yideng);
delete yideng.address;
console.log(yideng.address);

结果:beijing

原因: yideng 通过 prototype 继承了 company的 address。yideng自己并没有address属性。所以delete操作符的作用是无效的。

打印yideng的结果为:

[Object.create](developer.mozilla.org/zh-CN/docs/…)

6、写出执行结果并解释原因

var foo = function bar() {
  return 12;
};
console.log(typeof bar());

结果:Uncaught ReferenceError: bar is not defined

原因:命名函数表达式函数只能在函数体内有效

比如:

var foo = function bar(){
    console.log(typeof bar); // function
};
foo()