JavaScript

来源:互联网 发布:win10不支持的软件 编辑:程序博客网 时间:2024/06/10 11:51

困惑一:

先看一个例子:

  1. function test(){  
  2.     message = "hi";  
  3. }  
  4. test();  
  5. alert(message);  
会输出字符串“hi"

在函数内部使用var定义的变量是局部变量,省略var操作符的变量是全局变量。

困惑二:

  1. alert(undefined == null)  
结果是”true"

我们知道在js中分为基本类型和引用类型,基本类型包括number、string、boolean、undefined、null.如果一个基本类型没有初始化则会是undefined类型,而null代表空指针。实际上undefined值是派生自null的,因此返回true.

困惑三:

  1. alert(isNaN(NaN));   //true  
  2. alert(isNaN(10));    //false  
  3. alert(isNaN("10"));    //false  自动类型转换  
  4. alert(isNaN("blue"));   //true  
  5. alert(isNaN(true));    //false  自动类型转换  
NaN指非数值(Not a Number)是一个特殊的数值,在ECMAScript中,任何数值除以0返回NaN,而且任何涉及NaN的操作都会返回NaN. NaN与任何值不等,包括自身。

  1. alert(NaN == NaN);  // false   
困惑四:

  1. for(var propName in window){  
  2.     document.write(propName);  
  3. }  
For - in 语句是一种精准的迭代语句,可以用来枚举对象的属性,类似于java中的for( String s : String[])

困惑五:

  1. var qs = location.search.substring(1);  
  2. var hostName = location.hostname;  
  3. var url = location.href;  
  4.   
  5. //等价于下面  
  6.   
  7. with(location){  
  8.     var qs = search.substring(1);  
  9.     var hostName = hostname;  
  10.     var url = href;  
  11. }  
with语句的作用是将代码的作用域设置到一个特定的对象中,主要目的是为了简化多次编写同一个对象的工作。

困惑六:

  1. function howManyArgs(){  
  2.     alert(arguments.length);  
  3. }  
  4.   
  5. howManyArgs("String", 45);  //2  
  6. howManyArgs();  //0  
  7. howManyArgs(12);   //1  
ECMAScript中的参数在内部是用一个数组来表示的,函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(如果没有参数的话)。

命名的参数只提供便利,但不是必须的。再看下面例子

  1. function doAdd(num1, num2){  
  2.     arguments[1] = 10;  
  3.     alert(arguments[0] + num2);  
  4. }  
因为arguments对象中的值会自动反映到对应的命名参数,所以num2会变成10,但是他们的内存空间是独立的(不是引用),另外arguments对象的长度是由传入的参数个数决定的,不是由定义函数时的命名参数个数决定的。

困惑七:

  1. for(var i=0; i<10; i++){  
  2.       
  3. }  
  4. alert(i);   //输出结果为 10  
JavaScript没有块级作用域。


困惑一:

  1. var obj1 = new Object();  
  2. var obj2 = obj1;  
  3. obj1.name = "阳光小强";  
  4. alert(obj2.name);     //输出结果:阳光小强  
JavaScript中的5个基本类型:Undefined、Null、Boolean、Number和String都是按值访问的,可以操作保存在变量中的实际的值,内存空间如下:

  1. var num1 = 5;  
  2. var num2 = num1;  

引用类型的值是保存在内存中的对象,JavaScript不允许访问内存中的位置,也就是说不能直接操作对象的内存空间,引用类型赋值操作实际上是建立了新的引用。


困惑二:

JavaScript中是如何回收内存的?

JavaScript具有自动垃圾收集机制,不再使用的内存资源会被系统释放。具体到浏览器中的实现,通常有两个策略:

1、标记清除:

JavaScript中最常用的垃圾收集方式是标记清除。


当变量进入环境(例如,在函数中声明一个变量)时,就将这个变量标记为“进入环境”,当变量离开环境时,则将其标记为“离开环境”,则此时可回收。垃圾回收器会定时回收资源。

2、引用计数:

另一种不太常见的垃圾收集策略叫引用计数。


跟踪记录每个值被引用的次数,当这个值的应用次数变成0时,就会释放。IE中有一部分对象并不是原生的JavaScript对象。BOM和DOM中的对象就是使用C++以COM(组件对象模型)对象的形式实现的,而COM对象的垃圾回收机制采用的就是引用计数策略,这样会存在循环引用问题。

  1. var element = document.getElementById("som_element");  
  2. var myObject = new Object();  
  3. myObject.element = element;  
  4. element.someOject = myObject;  
为了解决上述问题,IE9把BOM和DOM对象都转换成了真正的JavaScript对象。

困惑三:

  1. var colors = ["red""blue""green"];  
  2. colors.length = 2;  
  3. alert(colors[2]);  //输出: undefined  
数组的length属性不是只读的,可以设置该属性,从数组末尾移除项。

困惑四:

  1. var colors = ["red""blue""green"];  
  2. alert(colors.toString());        //red,blue,green  
  3. alert(colors.valueOf());        //red,blue,green  
  4. alert(colors);                  //red,blue,green  

alert()方法接收的是一个字符串,为了创建字符串会调用每一项的toString方法。

另外,toLocaleString()方法经常也会返回与toString()和valueOf()方法相同的值,但也不是总是如此。

  1. var person1 = {  
  2.     toLocaleString : function(){  
  3.         return "Nikolaos";  
  4.     },  
  5.     toString : function(){  
  6.         return "Nicholas";  
  7.     }  
  8. };  
  9.   
  10. var person2 = {  
  11.     toLocaleString : function(){  
  12.         return "Grigorios";  
  13.     },  
  14.     toString : function(){  
  15.         return "Greg";  
  16.     }  
  17. };  
  18.   
  19. var people = [person1, person2];  
  20. alert(people);      //Nicholas, Greg  
  21. alert(people.toString()); //Nicholas, Greg  
  22. alert(people.toLocaleString()) //Nikolaos, Grigorios  
与前面两个方法唯一的不同在于,为了取得每一项的值,会调用每一项的toLocaleString方法,而不是toString方法。

数组继承的toLocaleString()、toString()、valueOf方法,在默认情况下都以逗号分隔,使用join()方法可以构建不同的分隔符字符串。

  1. var colors = ["red""green""blue"];  
  2. alert(colors.join(","));   //red,green,blue  
  3. alert(colors.join("||"))   //red||green||blue  
困惑五:

  1. var colors = ["red""blue"];  
  2. colors.push("brown");  
  3. colors[3] = "black";  
  4. alert(colors.length);   //4  
  5.   
  6. var item = colors.pop();  
  7. alert(item);  //"black"  
ECMAScript数组也提供了一种让数组的行为类似于其他数据结构的方法。数组可以像栈一样,压栈和出栈。

  1. var colors = new Array();  
  2. var count = colors.push("red""green");  
  3. alert(count);  //2  
  4.   
  5. count = colors.push("black");  
  6. alert(count);   //3  
  7.   
  8. var item = colors.pop();  
  9. alert(item);      //"black"  
  10. alert(colors.length);  //2  
可以将栈方法和数组方法连用。

同样也支持队列数据结构的访问规则,如下:

  1. var colors = new Array();  
  2. var count = colors.push("red""green");  
  3. alert(count);  
  4.   
  5. count = colors.push("black");  
  6. alert(count);  
  7.   
  8. var item = colors.shift();  
  9. alert(item);   //"red"  
  10. alert(colors.length); //2  
困惑六:

  1. alert(sum(10, 10));  
  2. function sum(num1, num2){  
  3.     return num1 + num2;  
  4. }  
上面代码可以执行,执行结果为20,将上面代码稍微修改一下,如下:

  1. alert(sum(10, 10));  
  2. var sum = function (num1, num2){  
  3.     return num1 + num2;  
  4. }  

不能执行,错误: undefined is not a function 

解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问),上面第二个例子不能执行的原因是函数位于一个初始化语句中,而不是一个函数声明。


0 0
原创粉丝点击