Ajax 板


LINE

※ 引述《lunamiou (○苗○乌)》之铭言: : 看书的前面写到 : var firstName = null; 这行後面 = null 是无意义的, 因为变数宣告在 javascript 有一个动作叫做 hoisting, hoisting 就是 interpreter(解译器) 会先扫过目前的 scope(作用域), 将所有 var 关键字抓出来,然後将每个变数宣告建立其专属空间。 考虑以下程式码: function foo() { bar = 2; var bar; console.log(bar); } foo(); // print 2 console.log(bar); // will throw an error 在直观上我们会认为当执行 function foo 时, 因为尚未宣告 bar 就直接赋值,因此 bar 会成为全域变数 而造成可能的全域变数污染。 但其实不然,因为 hoisting 的关系所以在执行 function foo 时, 变数 bar 会先被宣告并赋值 undefined 再从第一行执行。 另外这个 hoisting 对 function declartion(函数宣告)也是具有作用的 考虑以下程式码: console.log(foo()); // print 'bar' function foo() { return 'bar'; } 对於写过 C/C++ 的程式设计师来说,这是违反传统观念的, 因为 foo 在被宣告前就被使用,理论上在这里会喷错误, 但因为 hoisting 的关系,所以是可以正常执行的。 回到原题, var firstName = null; 为什麽我说没意义,是因为当关键字 var 出现时,其後跟着的变数 会在该 scope 开始执行前先被宣告并赋值 undefined, (注意 hoisting 只对变数做宣告而忽略等号右边) 此时当解译器执行到 firstName = null 时 会把 firstName 赋值 null, 可以说这是多此一举, 除非令 firstName = null 是你有意为之并且有特殊用途的。 考虑以下程式码: function foo() { console.log(bar); // print undefined bar = 1; console.log(bar); // print 1 var bar = 2; console.log(bar); // print 2 } foo(); console.log(bar); // will throw an error 所以既然变数宣告会被 hoist, 那不如一开始写的时候就先把变数宣告好, 也就是所有变数在使用 var 宣告时,一律放置在该 function 第一行, 至於要不要在宣告时赋值随便你。 如果是想释放变数储存空间的话,是可以在该变数使用完後 令其等於 null, 这样 JavaScript 引擎会自动作 garbage collection. : 上面的程式一般用於初始化变数,表示尚不需要为该变数赋与一个实际值; : 例如下面的程式,Object的一个实例info_obj的属性message尚未初始化, : 那麽,其值就是null: : var info_obj = new Object(); : info_obj.message; : alert(info_obj.message == null); //true 当然是 true 阿,这叫自动型态转换,谢谢 这本书可以丢了,真的 同样的例子,考虑 alert(info_obj.message === null); 结果就会不一样了 (茶) 至於 undefined == null 是怎麽成为 true 的, 是有听说这是历史共业啦 (感谢 IE), 不过我倾向这是未定义行为,应该要避开。 如上要判断 object property 是否有值的话,我会建议用 !!info_obj.message 一个 ! 代表 not, 把 true 变 false, 反之亦然 所以上面那行的诠释为: info_obj.message 未被赋值,其值为 undefined -> 自动型态转换为 false -> not false 转换为 true -> not true 转换为 false 当然如果 info_obj.message 本身就有值而且为 0, [], '' ... 等等 会被自动转换为 false 的值,此时就要有额外的策略去判断, 但在大部分应用中其实是不影响结果的。 如果这不是你要的结果,那可以用 obj.message === undefined 来判断, 但要注意 undefined 值有可能会被覆盖,这点可以透过用 closure 解决: (function (undefined) { .... }()); 不传入任何参数的话, undefined 值当然就是 undefined 了 (好饶舌 XD) 类似的用法可以参考 jQuery 原始码,在此以 2.0.2为代表: http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.js 可以看到程式开头即为 closure 形式: (function( window, undefined ) { 而结尾为: })( window ); 会传入 window 主要是效能问题,因为加了一层 closure 等於多了一层作用域, 让 window 成为 local 变数,就可以省下解译器往上层作用域寻找的时间。 其原因为当解译器在当前作用域找不到变数时,会往上一作用域搜寻。 : undefined 常数 : undefined常数用於尚未初始化的变数或未初始化的 : 动态物件属性的特殊值。 : 例如下面的两个变数都是undefined : var firstName; : var lastName; : 这个跟null有差别吗? undefined 与 null 做不严谨相等比较 (==) 时为 true, 但做 === 时就不会返回 true, 这绝对是地雷,恭喜你踩到了 \:D/ == 与 === 的差别在於前者会做自动型态转换,後者不会, 因此若等号两边型态不同,後者会直接返回 false. 考虑以下程式码: console.log(undefined == null); // print true console.log(undefined === null); // print false console.log(0 == false); // print true console.log(0 === false); // print false 另外要注意一点,undefined 是可以被覆盖的,也就是说: function foo() { var undefined = 10; console.log(undefined); } foo(); // print 10 console.log(undefined); // print undefined 好消息是在新版浏览器中 global object (全域物件,在浏览器环境中即为 window) 下的 undefined 是 read only 唯读变数, 但在旧版浏览器中要小心全域变数 undefined 是有可能被窜改的。 undefined 的正身便是在全域物件下的变数 undefined, 如果以下叙述执行当下的作用域(包含其上层作用域)里并没有对 undefined 赋予其他值,那麽所有 foo === undefined 等价於 foo === window.undefined. 另外为什麽说 undefined 是全域物件的变数而不是全域物件的属性, 其实当然是可以这样叫的,所有全域变数都是全域物件的一个属性。 : 再看下面的程式,user是Object类别的一个实例,该实例的sex属性如果 : 未初始化,那麽其属性值为undefined,而非null,因为Object并非动态 : 类别。例如下面的程式: : var user = new Object(); : alert(user.sex); //输出undefined : ---------------------------- : 以上看完还是疑惑,什麽样的结果是null,什麽会是undefined呢? : 这本书写的「类别」是什麽意思,英文的原文会是? Class 但一般称此为 Constructor (建构式),比较不常称 Class, 这是要跟使用 Class 的物件导向语言作区别。 所以说以下程式码: function Person(name, gender, age) { this.name = name; this.gender = gender; this.age = age; } Person.prototype.sayHello = function () { console.log('My name is ' + this.name + ". I'm " + this.gender + ". I'm " + this.age + (this.age === 1) ? ' year' : ' years' + ' old.'); } var jack = new Person('jack', 'male', 20); Person 称为 Constructor (建构式) 或称 Class (类别), jack 称为 Instance of constructor Person (Person 建构式的实例), jack.name, jack.gender, jack.age 称为 Property (属性), jack.sayHello 称为 Method (方法). : 另外「动态物件属性」、「动态类别」的意思分别是? : 小的才学疏浅,这边看了几次还是不太懂, 对不起我也不懂... 麻烦给一下上下文,谢谢 QQ : 还请大家指教一下,感激感激~~~ <(__ __)> 以上,不知道 console.log 是甚麽也可以用 alert() 代替 延伸阅读: https://developer.mozilla.org/en-US/docs/Web/ JavaScript/Reference/Statements/var ( 缩网址:http://ppt.cc/CNFY ) http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html http://stackoverflow.com/questions/6429225/javascript-null-or-undefined --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.117.183.96
1F:→ s25g5d4:哭哭 打到一半PTT断线 还好有暂存档 可是P币变少了 12/02 12:13
※ 编辑: s25g5d4 来自: 140.117.183.96 (12/02 12:14) ※ 编辑: s25g5d4 来自: 140.117.183.96 (12/02 12:15) ※ 编辑: s25g5d4 来自: 140.117.183.96 (12/02 12:36)
2F:推 danny8376:用心推 不过... !!info_obj.message <- 这样也是未定义 12/02 14:49
3F:→ danny8376:真想避免所谓的未定义行为请用typeof去判断... 12/02 14:49
4F:→ danny8376:不过... 对obj(?这样用到也没啥问题... JS其实有些地方 12/02 14:54
5F:→ danny8376:真的是颇麻烦 OTZ 12/02 14:54
这算是未定义行为阿... QQ 也是可以写 obj.message === undefined 啦 但就是怕 undefined 被窜改,这点可以透过 closure 解决: (function (undefined) { ... }()); 不传入任何参数,这样 undefined 就会是 undefined 了~
6F:→ danny8376:而undefined这东西... 主要是因为他实际上 12/02 14:55
7F:→ danny8376:完整是window.undefined 实质上也就是个全域变数 12/02 14:55
8F:→ danny8376:但这全域一般来说应该都是readonly才是 12/02 14:56
对,但这点下面也有人提到旧版的浏览器是可能被覆盖的
9F:推 mrbigmouth:不对喔 你可以写var undefined=123; XD 12/02 15:10
10F:→ danny8376:楼上 再怎改window.undefined都不会变啊... 12/02 17:02
11F:→ danny8376:readonly的是window.undefined 又不是local... 12/02 17:03
12F:推 mrbigmouth:readonly是旧版js没有的功能 至少我刚模拟IE7,8都是能 12/02 17:17
13F:→ mrbigmouth:改的 12/02 17:17
14F:→ mrbigmouth:何况在local改变undefined的值是能成功的 12/02 17:18
15F:→ mrbigmouth:因此还是不要太相信undefined真的是undefined比较好 12/02 17:18
16F:推 akiratw:有看过用 void 0 来取代 undefined 的 12/02 17:24
这我没看过,详细希望 -- 话说最後一段有个好大的错误都没人纠正...XD 整篇文章我重新修正一遍了,请各位板友有时间再重看一遍并订正我,谢谢 :D ※ 编辑: s25g5d4 来自: 140.117.183.96 (12/02 18:00)
17F:推 akiratw:void 是运算子,後面不管接什麽都会回传真正的 undefined 12/02 18:03
18F:→ akiratw:所以可以用 if (foo === void 0) 来检查是否 undefined 12/02 18:04
19F:→ akiratw:而不会有 undefined 被复写的疑虑 12/02 18:05
20F:→ s25g5d4:这好酷... XDD 12/02 18:09
21F:→ danny8376:mrbigmouth IE是啥 早就随他了XD 12/02 21:45
22F:→ danny8376:local的问题... 大多时候都能自己掌控吧XD 12/02 21:45
23F:→ danny8376:不过像很多lib都会自己在定义一次undefined就是www 12/02 21:46
24F:→ danny8376:s25g5d4 看到最後一段就感觉好多 直接end了XDD 12/02 21:47
25F:→ danny8376:不过void这部分 a tag的inline看很多了 12/02 21:48
26F:→ danny8376:script里倒是没看过www 12/02 21:48
27F:→ danny8376:原PO修文有提到closure了www 12/02 21:50
28F:推 tomin:推 写得很详细 12/02 21:53







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Boy-Girl站内搜寻

TOP