网络科技

    今日:865| 主题:245806
收藏本版
互联网、科技极客的综合动态。

[其他] 你应该知道的 JavaScript

[复制链接]
嫉妒恨 发表于 2016-10-3 20:01:20
65 2

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
  1. if (!("a" in window)) {
  2. var a = 1;
  3. }
  4. alert(a);
复制代码
       这个奇怪的代码似乎是这样: “如果window 没有属性    a, 定义一个变量    a并且赋值1”, 你可能会认为应该alert 1。 实际上,alert的是”undefined”。 为了理解发生了什么,你应该知道JavaScript的四件事。  
    首先, 所有的全局变量都是window的属性。      var a = 1完全等价于      window.a = 1。   
    第二, 所有的变量声明都会被提升(hositing)至所在作用域的顶部, 这个是JavaScript一大特性。看看,下面的这个例子
            
  1. alert("a" in window);
  2. var a;
复制代码
       上面的例子会alert出”true”即使变量声明在    alert()之后。这是因为JavaScript引擎会首先扫描所有变量生命并把他们    hositing至作用域顶部。上面那段代码相当于这样:  
           
  1. var a;
  2. alert("a" in window);
复制代码
       第三件事你应该理解只有变量声明被hositing而变量初始化没有  
           
  1. var a = 1;
复制代码
       你可以拆分看待上面的代码  
           
  1. var a;
  2. a = 1;
复制代码
       实际上JavaScript引擎也是这么做的, 当有变量声明并初始化,JavaScript会自动拆分变量声明和变量初始化。那为什么没有提升(hositing)变量初始化? 因为这样会影响变量值在代码执行期间,导致不可预料的结果。
  最后一点是JavaScript Scoping, 很多新手不能理解甚至很多有经验的JavaScript程序员也不能完全理解scoping。JavaScript的scoping如此复杂原因是他看起来像C系语言的成员, 看看下面的C程序:  
           
  1. #include <stdio。h>
  2. int main(){
  3. int x = 1;
  4. printf("%d", x); // 1
  5. if (1) {
  6. int x = 2;
  7. printf("%d", x); // 2
  8. }
  9. printf("%d", x); // 1
  10. }
复制代码
       上面输出的是    121这是因为C系语言有    块级作用域(block-level scope),但JavaScript却不是这样。  
           
  1. var x = 1;
  2. console。log(x); // 1
  3. if (true) {
  4. var x = 2;
  5. console。log(x); // 2
  6. }
  7. console。log(x); // 2
复制代码
       上面console出    122, 这是因为JavaScript是    函数级作用域(function-level scope), 像if语句是不会创建新的作用域的。只有函数才会创建新的作用域。  
  如果你理解上面四点,那么上面的例子你肯定可以知道为什么alert的是”undefined”, 上述的代码实际上是这样执行的。
           
  1. var a;
  2. if (!("a" in window)) {
  3. a = 1;
  4. }
  5. alert(a);
复制代码
       不难看出alert的是”undefined”, 声明了变量    a, 所有    !("a" in window)的是结果是false; 变量声明了但是没有初始化, 所以alert “undefined”。  
  Code Two  

           
  1. var a = 1,
  2. b = function a(x){
  3. x && a(--x);
  4. };
  5. alert(a);
复制代码
       这段代码看起来比实际上复杂得多。结果是alert “1”。 不用太困惑。同样的,这段代码需要你知道关于JavaScript的三件事。
  首先, 变量声明提升。上一个例子已经讲过。第二个方面是函数声明提升。所有的函数声明同变量声明一样都会被提升至当前的作用域顶部。
  很重要的一点是,一个函数声明如下:  
           
  1. function functionName(arg1, arg2){
  2. // function body
  3. }
复制代码
       对应是函数表达式, 其实也就是变量初始化赋值。  
           
  1. alert("a" in window);
  2. var a;
  3. 0
复制代码
       函数表达式并不会被提升。这其实也就是变量初始化。
  第三点就是你必须知道和理解函数声明会覆盖了变量声明但没有覆盖变量初始化。为了理解这一点,看看下面的例子  
           
  1. alert("a" in window);
  2. var a;
  3. 1
复制代码
         上面的      value作为      function而结束了,即使变量声明出现在函数声明之后。在这种情况下函数声明会获得更高的优先权。   
    但是下面的例子会有不同的结果。
            
  1. alert("a" in window);
  2. var a;
  3. 2
复制代码
       现在    value的值为1, 变量初始化覆盖的函数声明。  
  我们再看一个例子:  
           
  1. alert("a" in window);
  2. var a;
  3. 3
复制代码
       上面的例子会alert 1, 上面的这段代码实际执行是这样的,  
           
  1. alert("a" in window);
  2. var a;
  3. 4
复制代码
       这样你应该就不难理解为什么会是1了吧。
  回到Code Two, 那个函数实际上是函数表达式即使有函数名    a, 有名称的函数表达式并不会被认为是函数声明因此不会被覆盖变量声明。不过,你可能会发现包含函数表达式的变量是    b, 而函数表达式的名称是    a。 不同浏览器会做不同的处理,IE会认为    function a() {}是函数声明,因此它会被变量初始化覆盖,意味这当调用    a(--x)是会抛出一个错误。其他浏览器允许在函数里调用    a(--x)即使函数外部    a的类型的number。 同时,在IE中调用    b(2)会抛出一个error但是在其他浏览器中抛出    undefined。  
  Code Two 可以简化为更加正确并容易理解的代码,如下:  
           
  1. alert("a" in window);
  2. var a;
  3. 5
复制代码
       Code Three  

           
  1. alert("a" in window);
  2. var a;
  3. 6
复制代码
       这段代码相对简单, 你只需回答是3, 或是 10。 ECMA-262, 3rd Edition, 10。1。8节解释关于    arguments对象:  
  For each non-negative integer, arg, less than the value of the length property, a property is created with name ToString(arg) and property attributes { DontEnum }。 The initial value of this property is the value of the corresponding actual parameter supplied by the caller。 The first actual parameter value corresponds to arg = 0, the second to arg = 1, and so on。 In the case when arg is less than the number of formal parameters for the Function object, this property shares its value with the corresponding property of the activation object。 This means that changing this property changes the corresponding property of the activation object and vice versa。
    简而言之, 每一个参数在      arguments对象中都是一个同名的副本。也就是   
          arguments[0]指向x,      arguments[1]指向y, 而      arguments[2]指向a。 当传入的参数是      b(1, 2, 3, 4)时,      arguments[3]没有指向那个变量,但是它的值为4。   
    显而易见,alert 的是10。
  Code Four  

           
  1. alert("a" in window);
  2. var a;
  3. 7
复制代码
       你应该理解关于JavaScript的两个方面。
  首先, 你应该理解    this对象是什么。 看看下面的例子:  
           
  1. alert("a" in window);
  2. var a;
  3. 8
复制代码
       在上面的代码中,    this指向    object对象, 所以结果是    true   
在全局作用域中,    this指向    window,因此下面的    this指向的则是    window  
           
  1. alert("a" in window);
  2. var a;
  3. 9
复制代码
       理解了第一点你才能理解第二点,    call()是干嘛的。 通过    call()可以重新定义函数的执行环境,即    this的指向, 第一个参数将成为this的指向对象, 随后的参数将作为参数传入函数。  
           
  1. var a;
  2. alert("a" in window);
  3. 0
复制代码
       当执行    method.call(document)时,    this指向的将是    document。  
  当传入函数为    null或    undefined时会怎样呢?  
  If thisArg is    nullor    undefined, the called function is passed the global object as the this value。 Otherwise, the called function is passed ToObject(thisArg) as the this value。  
  所以此时传入的是    window  
  PS: 还有一个    apply()与    call()类似,不过只有两个参数,第二参数应该是数组。  
  理解上面讲的,很容易就可以知道答案是 5
友荐云推荐




上一篇:Google&#x27;s big hardware event: What to expect
下一篇:Which? says iPhone 7 has worst battery-life of all current flagship smartphones
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

求_Smooth 发表于 2016-10-3 21:19:12
大人,此事必有蹊跷!
回复 支持 反对

使用道具 举报

森浓不绿 发表于 2016-10-5 18:09:23
duang
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表