1、Boolean和Number运算
console.log(Boolean([]))//true,while([])相当于while(Boolean([]))console.log(Boolean(''))//falseconsole.log(Boolean(0))//falseconsole.log(Boolean(null))//falseconsole.log(Boolean(undefined))//falseconsole.log(Boolean(NaN))//false
console.log(Number([]))//0console.log(Number(''))//0console.log(Number(null))//0console.log(Number(undefined))//NaNconsole.log(Number(NaN))//NaN
console.log(null==undefined)//trueconsole.log(null===undefined)//falseconsole.log([]==true?true:false)//false,空数组console.log([1]==true?true:false)//true,非空数组
2、数组差值时的map陷阱
想象一下你有这样的代码:
var a = [1, 2, 3];
a)这会导致崩溃吗?
a[10] = 99;
b)这个输出是什么?
console.log(a[6]);
a)它不会崩溃。 JavaScript引擎将使阵列插槽3至9成为“空插槽”。
b)在这里,a [6]将输出未定义的值,但时隙仍为空,而不是未定义的。在某些情况下,这可能是一个重要的细微差别。例如,使用map()时,map()的输出中的空插槽将保持为空,但未定义的插槽将使用传递给它的函数重映射:
var b = [undefined]; b[2] = 1;console.log(b); // (3) [undefined, empty × 1, 1]console.log(b.map(e => 7)); // (3) [7, empty × 1, 7]
3、typeof undefined == typeof NULL
的值是什么?console.log(typeof typeof 1);
返回什么
该表达式将被评估为true,因为NULL将被视为任何其他未定义的变量。
注意:JavaScript区分大小写,我们在这里使用NULL而不是null。
console.log(typeof undefined)//'undefined'console.log(typeof Undefined)//'undefined'console.log(typeof UNDEFINED)//'undefined'console.log(typeof null)//'object'console.log(typeof Null)//'undefined'console.log(typeof NULL)//'undefined'
console.log(typeof typeof 1);//'string'
4、以下代码输出什么
var b = 1; function outer() { var b = 2 function inner() { b++; console.log(b) var b = 3; console.log(b) } inner(); } outer();
输出:
NaN3
上述代码inner()函数相当于
function inner () {//变量提升 var b; // b is undefined b++; // b is NaN console.log(b); b = 3; // b is 3 console.log(b); // output "3"}
5、你如何克隆一个对象?
var obj = {a: 1 ,b: 2}//Object.assign(目标,源1,源2)var objclone = Object.assign({},obj);
现在objclone的值是{a:1,b:2},但指向与obj不同的对象。
但请注意潜在的缺陷:Object.clone()只会执行浅拷贝,而不是深拷贝。这意味着嵌套的对象不会被复制。他们仍然引用与原始相同的嵌套对象:
let obj = { a: 1, b: 2, c: { age: 30 } };var objclone = Object.assign({},obj);console.log('objclone: ', objclone); obj.c.age = 45;console.log('After Change - obj: ', obj.c.age); // 45 - This also changesconsole.log('After Change - objclone: ', objclone.c.age); // 45
6、考虑下面的代码。输出是什么,为什么?
(function () { try { throw new Error(); } catch (x) { var x = 1, y = 2; console.log(x); } console.log(x); console.log(y); })();//输出1undefined2
var语句被提升(没有它们的值初始化)到它所属的全局或函数作用域的顶部,即使它位于with或catch块内。但是,错误的标识符只在catch块内部可见。它相当于:
(function () { var x, y; // outer and hoisted try { throw new Error(); } catch (x /* inner */) { x = 1; // inner x, not the outer one y = 2; // there is only one y, which is in the outer scope console.log(x /* inner */); } console.log(x); console.log(y); })();
7、以下代码的输出是什么?
var length = 10;function fn() { console.log(this.length); console.log(this) }var obj = { length: 5, method: function(fn) { fn(); arguments[0](); } }; obj.method(fn, 1);
输出:
10Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} 2Arguments(2) [ƒ, 1, callee: ƒ, Symbol(Symbol.iterator): ƒ]
首先,由于fn作为函数方法的参数传递,函数fn的作用域(this)是窗口。 var length = 10;在窗口级别声明。它也可以作为window.length或length或this.length来访问(当这个===窗口时)。
方法绑定到Object obj,obj.method用参数fn和1调用。虽然方法只接受一个参数,但调用它时已经传递了两个参数;第一个是函数回调,其他只是一个数字。
当在内部方法中调用fn()时,该函数在全局级别作为参数传递,this.length将有权访问在Object obj中定义的var length = 10(全局声明)而不是length = 5.
现在,我们知道我们可以使用arguments []数组访问JavaScript函数中的任意数量的参数。因此arguments[0]只不过是调用fn()。在fn里面,这个函数的作用域成为参数数组,并且记录参数[]的长度将返回2。
8、以下代码的输出是什么?
var a={}, b={key:'b'}, c={key:'c'}; a[b]=123; a[c]=456;console.log(a[b]);//456
原因如下:设置对象属性时,JavaScript会隐式地将参数值串联起来(相同的键值后者覆盖前者)。在这种情况下,由于b和c都是对象,它们都将被转换为“[object Object]”。因此,a [b]和a [c]都等价于[“[object Object]”],并且可以互换使用。因此,设置或引用[c]与设置或引用[b]完全相同。
作者:fenerchen
链接:https://www.jianshu.com/p/d50015adad69
热门评论
你好,能帮忙解释下:JavaScript引擎将使阵列插槽3至9成为“空插槽”。这句话中的“空插槽”是怎么回事吗?