参加了一次面试,简单聊过之后,做了几道题,看着都是熟悉又陌生。哈哈,总结一下今天遇到的题
一:
let object = { a : 0 };
function fn(obj) {
obj.a = 1;
obj = { a : 2 }
obj.b = 2
}
fn(object);
console.log(object);
个人理解,函数实参相当于在函数内部声明了一个局部变量,但未赋值,传入实参时为其赋值,该局部变量会在函数执行完毕后被回收,所以上面的代码可以理解:
let object = { a : 0 };
function fn(obj) {
var obj; //首先声明一个局部变量
obj = object //传入的实参为其赋值
obj.a = 1; //因为对象是引用数据类型,他们指向同一个地址,因此对obj的修改相当于对object的修改 此时object为{ a : 1 }
obj = { a : 2 } //将函数内部的变量obj指向新的地址,此时obj的修改不再影响全局的object
obj.b = 2 //同样不影响全局的object
}
fn(object);
console.log(object); // { a : 1 }
看下对于基本数据类型:
var x = 6;
function fun(x) {
x = 11; //只是局部变量由传入的6改变为了11,全局变量不受影响
}
fun(x);
console.log(x) //6
二、隐式类型转换
console.log('123' == 123)
console.log('' == null)
console.log('' == 0)
console.log([] == 0)
console.log([] == '')
console.log([] == ![])
console.log(null == undefined)
大家可以先想想答案
写一下== 和 !==的隐式转换
如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值 false转为0 true转为1
如果一个操作数是字符串,另一个是数值,则将字符串转换为数值
如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型数值按照前面的规则进行比较,如果得到的不是基本数据类型,则再次调用对象的toString()方法
进行比较时遵循下列基本规则:
null和undefined是相等的
要比较相等性之前,不能将null和undefined转换为其他任何值
只要有一个操作数是NaN,则== 一定返回false, !==一定返回true.因为NaN不等于任何值,包括其本身
如果两个操作数都是对象,则比较它们是不是用一个对象,如果都指向同一个对象,则==返回true,否则就是false
console.log('123' == 123) //true 没什么问题,字符串转数值
console.log('' == null) //false null不可转为任何值
console.log('' == 0) // Number('') => 0 因此返回true
console.log([] == 0)
console.log([] == '')
console.log([] == ![])
console.log(null == undefined) //true JS规定的
console.log([] == 0)
首先调用[].valueOf(),发现还是空数组
再次调用toString()方法
此时转换成了空字符串,此时表达式就变成了:
console.log('' == 0) //true
console.log([] == '')
同样的道理,空数组会被转换为空字符串
console.log('' == '') //true
console.log([] == ![])
先考虑优先级: !优先级大于 == ,先将空数组转为false,就变成了
console.log([] == false) //布尔值会被转为数字
console.log([] == 0 ) //true
三、闭包
let x = 5;
function fn(x) {
return function (y) {
console.log(y + (++x))
}
}
let f = fn(6); // 相当于在外部函数中声明了一个变量x,并赋值为6,而内部函数需要引用该变量,所以没有被回收
f(7); //传了内部函数需要的y 就是console.log( 7 + (++6))
console.log(x) //现在自身作用域找变量,自身没有才去外部作用域查找,因此全局的X没有用到,还是5
四、事件循环
console.log(1);
async function foo() {
console.log(2);
await console.log(3)
console.log(4)
}
setTimeout(() => {
console.log(5)
},0)
foo()
new Promise((resolve , reject) => {
console.log(6)
resolve();
}).then( () => {
console.log(7)
})
console.log(8)
说实话对这个的理解还不是很透彻,研究一下,之后详细记录
在这里:Javascript同步、异步与事件循环
看下运行结果