关于JS的面试题
一、在对象中调用外面的箭头函数,this指向问题
const showThis = () => {
console.log(this)
}
var obj = {
showThis: showThis
}
showThis()
obj.showThis()
两者都指向window,因为箭头函数中的this为大括号外面的this。
var obj = {
showThis: () => {
console.log(this)
}
}
obj.showThis()
这个也指向window
二、JS中小数相加问题
0.1 + 0.2 等于 0.3 吗?为什么?解决方案?
1.使用toFixed
限制有效位数
(0.1 + 0.2).toFixed(1) // 0.3
2.先转换成整数再运算
function addNum(num1, num2) {
let sq1, sq2, multiple;
try {
sq1 = num1.toString().split(".")[1].length;
} catch (e) {
sq1 = 0;
}
try {
sq2 = num2.toString().split(".")[1].length;
} catch (e) {
sq2 = 0;
}
multiple = Math.pow(10, Math.max(sq1, sq2));
return (num1 * multiple + num2 * multiple) / multiple;
}
三、调用对象中的函数,this指向
var bar = {
myName: "bar",
printName: function() {
console.log(myName)
console.log(this)
}
}
function foo() {
let myName = "foo"
return bar.printName
}
let myName = "global"
let _printName = foo()
_printName() // global window
bar.printName() // global bar{}
获取到对象中的函数是一个函数地址,当执行这个函数时是在全局执行的,所以this
指向的是widow
,打印的myName
也应该在全局作用域中找。
第二个:把bar.printName()当成fn(),那么可以看出这个函数打印的是全局变量
四、将对象中的key转化为驼峰命名
{ red_apple:'111', blue_apple:{ green_apple:{ orange_apple:'222' } } }
function name2Tt(obj) {
// 1.遍历keys,对每个key查找‘_’的位置,将后一个字符变为大写
// 2.若有剩余字符再拼接上,继续查找下一个‘_’
// 3.由于每次遍历key都会变,且需要一个新的keyName,所以需要两个变量保存旧key和新key
// 4.递归当前key值
// 递归出口
if (obj.__proto__ !== Object.prototype) {
return;
}
const keys = Object.keys(obj);
for (let key of keys) {
let oldKey, newKey;
let pos;
oldKey = key;
while ((pos = key.indexOf('_')) !== -1) {
newKey = key.substring(0, pos);
if (key.length > pos + 1) {
newKey += key.charAt(pos + 1).toUpperCase();
}
if (key.length > pos + 2) {
newKey += key.substring(pos + 2);
}
key = newKey;
}
if (newKey !== '') {
obj[newKey] = obj[oldKey];
delete obj[oldKey];
name2Tt(obj[newKey]);
} else {
name2Tt(obj[oldKey]);
}
}
}