javascript里函数提升与逻辑运算

<span style="white-space:pre">	</span>f = function() {
		return true;
	};
	g = function() {
		return false;
	};
	(function aa() {
		if (g() && [] == ![]) {
			f = function f() {
				return false;
			};
			function g() {
				return true;
			}
		}
	})();
	alert(f()); // true or false ?

以上例子是网友们的,自己研究一下,觉得分析过程是这样的,自己作个记录,有错的地方希望大神们不吝赐教!

例子来源

http://bbs.csdn.net/topics/390601168#new_post




<!-- 
个人觉得这个题目的答案是false
1.函数提升问题:ES中函数声明会提升(连同函数体),重定义的会覆盖之前的,函数表达式会像变量那样(只提升声明,不提升初始化)
2.运算符优先级问题:等性运算(==)高于逻辑运算,故if (g() && [] == ![]) ==>if (g() && ([] == ![]))
3.隐式转换问题:[] == ![],首先是![]运算,!后是对象,返回false;其次是等性比较,一个对象和一个boolean的等性比较
  先将boolean转换成数字,false:0;然后对象转换成数字''==0,[]==0,+[]==0,......都是true(具体过程很复杂,有兴趣的去看ES里的GetValue)
4.这个是闭包吗?按哪个定义呢?按w3c的像是简单的闭包,按另外一个定义(类似于:函数局部变量被一个外界引用的函数使用,那么这个局部变量一直存在内存里,.....),这不算闭包了吧。
以上是关键点,最后得到结果是false。
 -->


<!-- 
注意:ECMAScript中
[] == false; //true
![] == false; //true
[] == []; //false
'' == false; //true
[] == ''; //true
[] == 0; //true
(![] == false) && ([] == false) && ([] !=[]) && ([] == ![])的值???  //true 为什么?往后看,对应比较




以下是w3cschool中的:


ECMAScript中的逻辑非(!):
逻辑 NOT 运算符返回的一定是 Boolean 值。逻辑 NOT 运算符的行为如下:


如果运算数是对象,返回 false 
如果运算数是数字 0,返回 true 
如果运算数是 0 以外的任何数字,返回 false 
如果运算数是 null,返回 true 
如果运算数是 NaN,返回 true 
如果运算数是 undefined,发生错误


ECMAScript中的逻辑AND(&&):
逻辑 AND 运算的运算数可以是任何类型的,不止是 Boolean 值。如果某个运算数不是原始的 Boolean 型值,逻辑 AND 运算并不一定返回 Boolean 值:


如果一个运算数是对象,另一个是 Boolean 值,返回该对象。 
如果两个运算数都是对象,返回第二个对象。 
如果某个运算数是 null,返回 null。 
如果某个运算数是 NaN,返回 NaN。 
如果某个运算数是 undefined,发生错误。
 
与 Java 中的逻辑 AND 运算相似,ECMAScript 中的逻辑 AND 运算也是简便运算,即如果第一个运算数决定了结果,就不再计算第二个运算数。


ECMAScript中的逻辑OR(||):
与逻辑 AND 运算符相似,如果某个运算数不是 Boolean 值,逻辑 OR 运算并不一定返回 Boolean 值:


如果一个运算数是对象,另一个是 Boolean 值,返回该对象。 
如果两个运算数都是对象,返回第一个对象。 
如果某个运算数是 null,返回 null。 
如果某个运算数是 NaN,返回 NaN。 
如果某个运算数是 undefined,发生错误。 
与逻辑 AND 运算符一样,逻辑 OR 运算也是简便运算。


ECMAScript 等性运算符:
ECMAScript 提供了两套等性运算符:等号和非等号用于处理原始值,全等号和非全等号用于处理对象。
等号和非等号
在 ECMAScript 中,等号由双等号(==)表示,当且仅当两个运算数相等时,它返回 true。非等号由感叹号加等号(!=)表示,当且仅当两个运算数不相等时,它返回 true。为确定两个运算数是否相等,这两个运算符都会进行类型转换。


执行类型转换的规则如下:


如果一个运算数是 Boolean 值,在检查相等性之前,把它转换成数字值。false 转换成 0,true 为 1。 
如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。 
如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。 
如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字。 
在比较时,该运算符还遵守下列规则:


值 null 和 undefined 相等。 
在检查相等性时,不能把 null 和 undefined 转换成其他值。 
如果某个运算数是 NaN,等号将返回 false,非等号将返回 true。 
如果两个运算数都是对象,那么比较的是它们的引用值。如果两个运算数指向同一对象,那么等号返回 true,否则两个运算数不等。 
重要提示:即使两个数都是 NaN,等号仍然返回 false,因为根据规则,NaN 不等于 NaN。


下表列出了一些特殊情况,以及它们的结果:


表达式 值 
null == undefined true 
"NaN" == NaN false 
5 == NaN false 
NaN == NaN false 
NaN != NaN true 
false == 0 true 
true == 1 true 
true == 2 false 
undefined == 0 false 
null == 0 false 
"5" == 5 true 


全等号和非全等号
等号和非等号的同类运算符是全等号和非全等号。这两个运算符所做的与等号和非等号相同,只是它们在检查相等性前,不执行类型转换。


全等号由三个等号表示(===),只有在无需类型转换运算数就相等的情况下,才返回 true。


例如:


var sNum = "66";
var iNum = 66;
alert(sNum == iNum); //输出 "true"
alert(sNum === iNum); //输出 "false"
在这段代码中,第一个 alert 使用等号来比较字符串 "66" 和数字 66,输出 "true"。如前所述,这是因为字符串 "66" 将被转换成数字 66,,
然后才与另一个数字 66 进行比较。第二个 alert 使用全等号在没有类型转换的情况下比较字符串和数字,当然,字符串不等于数字,所以输出 "false"。


非全等号由感叹号加两个等号(!==)表示,只有在无需类型转换运算数不相等的情况下,才返回 true。


例如:


var sNum = "66";
var iNum = 66;
alert(sNum != iNum); //输出 "false"
alert(sNum !== iNum); //输出 "true"
这里,第一个 alert 使用非等号,把字符串 "66" 转换成数字 66,使得它与第二个运算数 66 相等。因此,计算结果为 "false",因为两个运算数是相等的。
第二个 alert 使用的非全等号。该运算是在问:"sNum" 与 "iNum" 不同吗?这个问题的答案是:是的(true),因为 sNum 是字符串,而 iNum 是数字,它们当然不同。


-->







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值