! 与 !!、new Function、&& 和 ||
1、! 与 !!
- ‘!’ 可将变量转换成boolean类型,null、undefined和空字符串取反都为false,其余都为true。
在javascript中:
以下内容会被当成false处理:"" , false , 0 , null , undefined , NaN
console.log(!undefined); // true
console.log(!null); // true
console.log(!''); // true
console.log(!' ') // false
console.log(!0) // true
console.log(!0) // true
console.log(!NaN) // true
- ‘!!’ 常常用来做类型判断,在第一步!(变量)之后再做逻辑取反运算,在js中新手常常会写这样臃肿的代码:
判断变量a为非空,未定义或者非空串才能执行方法体的内容
// 新手判断 a 有内容或非空
var a;
if(a!=null&&typeof(a)!=undefined&&a!=''){
//a有内容才执行的代码
}
// 老手
if(!!a){
//a有内容才执行的代码...
}
2、new Function()将字符串转为对象
- 在JS中将字符串 “type: ‘progressbar’,data:demo3” 神奇的变为对象
var s=(new Function("return ({" + "type:'progressbar',data:'demo3'" + "})"))();
console.log(s); // Object { type: "progressbar", data: "demo3" }
// 文章1
var message = new Function('msg','alert(msg)');
// 等价于:
function message(msg) {
alert(msg);
}
// 文章2
var a = 'global scope'
function b(){
var a = 'local scope'
eval('console.log(a)'); //local scope
(new Function('','console.log(a)'))() //global scope
}
b();
// eval中的代码执行时的作用域为当前作用域。它可以访问到函数中的局部变量。
// new Function中的代码执行时的作用域为全局作用域,不论它的在哪个地方调用的。所以它访问的
// 是全局变量a。它根本无法访问b函数内的局部变量。
那么(1、)中的代码改写为如下,结果没有发生改变。
var s=(new Function("","return ({" + "type:'progressbar',data:'demo3'" + "})"))();
console.log(s); // Object { type: "progressbar", data: "demo3" }
那么将文章2中代码改写为下
var a = 'local scope';
function b() {
(new Function('console.log(a)'))() //global scope
}
b(); // local scope
结果依旧没有改变。那么测试以下代码
1、
var cc= new Function('aa','console.log(aa)');
cc('孙悟空'); // 孙悟空
2、
var cc1= new Function('','console.log("牛魔王")');
cc1('孙悟空'); // 牛魔王
3、
var cc2= new Function('console.log("猪八戒")');
cc2('孙悟空'); // 猪八戒
由此可见,当new Function 创建的函数并不需要参数时,Function 的第一个参数可写可不写;
以上代码均在火狐浏览器中测试。
文章一引用:https://www.cnblogs.com/pizitai/p/6427433.html
文章二引用:https://www.cnblogs.com/zhangfengyang/p/5526024.html
3、彻底理解 js 中 && 和 ||
- 现象:
javascript中,&&和||的用法比较神奇,经常用在对象上,例如a || b,如果a不存在,则返回b。a && b,如果a存在,则返回b,否则返回a。
光这样看,感觉他的概念还挺复杂的,这样去想的话,不但会在脑子里多出一个无用的概念,而且越记越混乱。看问题还是要看本质。 - 本质:
本质是什么呢?&& 和 || 的作用只有一个(定义):
进行布尔值的且和或的运算。当运算到某一个变量就得出最终结果之后,就返回哪个变量。 - 说明:
在javascript中:
以下内容会被当成false处理:"" , false , 0 , null , undefined , NaN
其他都是true。注意:字符串"false"也会被当做true处理,在未转型的情况下他是字符串,属于一个对象,所以是true。
所以:
a || b:如果a是true,那么b不管是true还是false,都返回true。因此不用判断b了,这个时候刚好判断到a,因此返回a。
如果a是false,那么就要判断b,如果b是true,那么返回true,如果b是false,返回false,其实不就是返回b了吗。
a && b:如果a是false,那么b不管是true还是false,都返回false,因此不用判断b了,这个时候刚好判断到a,因此返回a。
如果a是true,那么就要在判断b,和刚刚一样,不管b是true是false,都返回b。 - 来个复杂的例子(注意一点:在js中&&运算符优先级大于||)
假设:
var a=new Object(),b=0,c=Number.NaN,d=1,e="Hello";
console.log(a || b && c || d && e); // Object {}
- 表达式从左往右执行,先&&后||
5.1、(b && c):b是false,此时不需要判断c,因为不管c是true是false,最终结果一定是false,因此返回当前判断对象b,也就是0;
5.2 、(d && e):d是true,这个时候判断e,此时不管e是true,是false,返回结果一定是e,e为true,因此返回"Hello";
5.3、(a || b):a是true,此时不管b是true是false,结果都是true,所以不判断b,所以返回当前判断对象a,因此返回new Object();
5.4、(a || e):同上,因此返回a。
这个表达式最终结果为a,也就是new Object()