Javascript基础入门
一. 数据类型
Undefined类型:只有一个值,即特殊的undefined。在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined
Null类型:只有一个值,即null。从逻辑的角度看,null值表示一个空对象引用,而这也是使用typeof操作符检测null值时会返回”object”的原因,如果定义的变量准备用来保存对象,那么最好将该变量的值初始化为null,这样只要检查null的值就知道对象是否已经保存一个对象的引用。
Boolean类型:两个字面量值”true”和”false”。
数据类型 | 转换为true | 转换为false |
Boolean | true | false |
String | 任何非空字符 | “”空字符 |
Number | 任何非零数字值 | 0和NaN |
Object | 任何对象 | null |
Undefined | Not applicable(不适用) | undefined |
Number类型
NaN:即非数值(Not aNumber) 是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数未返回的情况(这样就不会抛异常)。
**任何与NaN操作都会返回NaN,这个特点在多步计算机中可能会导致问题,其次任何的NaN与任何值都不想等,包括NaN本身。
使用isNaN()可以确定该参数是否”不是数值”,该参数类型可以是对象,当参数为对象的时候,首先会调用对象的valueof(),然后确定该方法的返回值是否可以转为数值,如果不能,则基于这个返回值在调用toString(),在测返回值。
--数值转换
1.Boolean,true和false将分别转换为1和0。
2.null值,返回0。
3.undefined,返回NaN。
4.如果是字符串:如果字符串中包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值。如果字符串中包含有效的浮点格式,则将其转换为对应的浮点数值。如果字符串中包含十六进制格式,则将其转换为相同大小的十进制数值。如果是字符串是空,则将其转换我0。如果字符串不包含在上述中,则将返回NaN
5.parseInt()函数在转换字符串是,更多的是看其是否在符合数值模式,它会忽略字符串前面的空格,直到找到第一个非空字符,,如果第一个不是数字字符或负号,parseof()就会返回NaN;也就是说,用parseof()转换空字符串会返回NaN(Number()对空字符串返回0)。如果第一个是数字字符,parseof()会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符。同理于parseFloat()。
String类型:表示有0或多个16位unicode字符组成的字符序列。在ECMAScript中字符串是不可变的,也就是说,字符串一旦创建,他们的值就是不能改变的。要改变某个变量的保存的字符串,首先要销毁原来的字符串,然后再用另一个不包含新值的字符串填充该变量。
1. toString():多数情况下调用toString()不用传参,但是在调用数值的toString()时,可以传递一个参数;输出数值的基数;默认情况下,toString()方法返回的是以十进制格式返回数值的字符串表示。而通过基数,toString()可以输出多样的有效进制格式。
Object类型:定义一组数据和功能的集合。
1. Object的每个实列都具有下列属性和方法
1.1. Constructor:保存找用于创建当前对象的函数。
1.2. hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性名(propertyName)必寻以字符串形式指定。
1.3. isPrototypeOf(object):用于检查传入的对象是否是另一个对象的原型。
1.4. propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举,与hasOwnProperty一样,作为参数的属性名必须是以字符串形式指定。
1.5. toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
1.6. toString():返回对象的字符串表示。
1.7. valueof():返回对象的字符串、数值或布尔值表示。通常与toString()的返回值相同
JavaScript数据类型:
二. 操作符
1. 相等操作符
1.1相等于不想等:(==)如果两个操作数相等,则返回true。(!=)如果两个操作数不想等,则返回true,这两个操作符都会先转换操作数(通常称为强制转型),然后在比较他们的相等性。
比较规则:
如果有一个操作数是布尔值,true转换为1,false转换为0。
如果有一个操作是字符串,一个是数值,将字符串转换为数值在比较。
如果有一个操作数是对象,另一个不是,将调用对象的valueof(),得到的基本数据类型按照前面进行比较。
null和undefined是相等的。
如果有一个操作符是NaN,则(==)返会false,而(!=)返回true,即使两个操作符都是NaN,相等操作符也返回false,应为NaN不等于NaN。
如果两个都是对象,则比较他们是不是同一个对象,如果连个操作数都指向同一个对象,则相等操作符返回true;否则,返回false。
2全等和不全等
2.1.全等操作符由(===)表示,两个操作数在未经转换的情况下相等就返回ture
2.1.null== undefined会返回true,因为他们是类似的值;但null == undefined会返回false,因为他们是不同类型的值。
Function类型
ECMAScript中的函数在定义时不必指定是否返回值,实际上,任何函数在任何时候都可以通过return语句跟要返回的值来实现返回值。
1. 函数的参数:ECMAScript函数的一个重要特点就是:命名的参数只提供便利,但不是必须的,实际上,在函数体内,可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。argumnets它的值永远与对应命名参数的值保持同步如:
2. function doAdd(num1,num2){
arguments[1] =10;
alert(arguments[0]+ num2);
}
argumnets对象中的值会自动反映到对应的命名参数,所以修改arguments的值,也会修改num2,不过,并不是说,读取这两个值会访问相同的内存空间,他们的内存空间是独立的,但他们的值是同步的,这种影响是单向的,即修改num2的值会改变arguments[1]的值,但是num2必须不为undefined。通过检查传入参数的类型,个数,可以模仿方法的重载。
二.引用类型和基本类型
1.参数的传递:ECMAScript中所有的函数参数的传递都是值传递。类似java中参数的传递。如:
function setName(obj){
obj.name= “xiao”;
obj= new Object();
obj.name= “ling”;
}
var person = new Object();
setName(person);
alert(person.name);
在函数的内部修改参数的值,但原始的引用依然保持不变,实际上,当在函数的内部重写obj时,这个变量的引用就是局部对象,而这个局部对象会在函数执行完成立即被销毁。
3. 执行环境及作用域
3.1.定义了变量或函数有权访问的其他数据,决定了他们各自的行为。每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中。
3.2.全局执行环境是最外围的一个执行环境,根据ECMAScript实现的宿主环境不同,所执行环境对象也不一样,在WEB浏览器中,全局环境被认为是window对象,因此所有的全局便利和函数都是作为window对象的属性和方法创建的,在某个执行环境中的所有代码执行完毕之后,该环境被销毁,保存其中的所有变量和函数定义也随之销毁(全局执行环境直到应用程序退出时才被销毁)。
3.3.每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中,而在函数执行后,栈将其环境弹出,把控制权返回给之前的环境。
3.4.当代码在一个环境中执行时,会创建变量对象的一个作用于链(scope chain)。作用于链的用途,就是保证对执行环境有权访问的所有变量和函数的有序访问。在作用域链的前端,始终是当前执行的代码所在的执行环境的变量对象。如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象最开始只包含一个变量,即arguments对象(这个对象在全局环境中是不存在的)。作用域链中的下一个变量对象来自包含(外部)环境,而在下一个变量对象则来自下一个包含对象,这样一直延续到全局执行环境,全局执行环境的变量对象始终都是在作用域链中的最后对象。
3.5.查询标识符:当在某个环境中读取或写入引用一个标识符时,必须通过索搜来确定标识符实际代表是什么。搜索过程从作用域链的最前端开始,向上逐级查询与给定名字匹配的标识符。如果在全局环境中也没有找到这个标识符,则意味着该变量未声明。如图所示:
环境之间的联系是线性,有次序的。每个环境可以向上搜索作用域链,以查询变量和函数名,但任何环境都不能通过向下搜索作用域链而进入另一个执行环境。
3.6. JavaScript没有块级作用域,使用var声明的变量会自动被添加到最近的环境。
3.7. 一旦数据不在使用,最好通过将其值设置为null来释放期应用,即解除引用。
3.8. javascript严格区分大小写。
3.9. 当JS执行流进入函数时,JavaScript引擎在内部创建一个对象,叫做Variable Object。对应函数的每一个参数,在Variable Object上添加一个属性,属性的名字、值与参数的名字、值相同。函数中每声明一个变量,也会在Variable Object上添加一个属性,名字就是变量名,因此为变量赋值就是给Variable Object对应的属性赋值。在函数中访问参数或者局部变量时,就是在variable Object上搜索相应的属性,返回其值。
一般情况下Variable Object是一个内部对象,JS代码中无法直接访问。规范中对其实现方式也不做要求,因此它可能只是引擎内部的一种数据结构。
3.10. JavaScript的运行环境都必须存在一个唯一的全局对象-Global Object,例如HTML中的window对象。Global Object是一个宿主对象,除了作为JavaScript运行时的全局容器应具备的职责外,ECMA规范对它没有额外要求。它包Math、String、Date、parseInt等JavaScript中内置的全局对象、函数(都作为Global Object的属性),还可以包含其它宿主环境需要的一些属性。
3.11. Variable Object也叫做Activation Object(因为有一些差异存在,所以规范中重新取一个名字以示区别,Global Code/Eval Code中叫VariableObject,Function Code中就叫做Activation Object)。
每次进入函数执行都会创建一个新的Activation Object对象,然后创建一个arguments对象并设置为ActivationObject的属性,再进行Variable Instantiation处理。
在退出函数时,Activation Object会被丢弃(并不是内存释放,只是可以被垃圾回收了)。
3.12. Scope/ScopeChain
首先Scope Chain是一个类似链表/堆栈的结构,里面每个元素基本都是Variable Object/Activation Object。
其次存在执行上下文的地方都有当前Scope Chain,可以理解为ScopeChain就是执行上下文的具体表现形式。
Global Code
Scope Chain只包含一个对象,即Global Object。在开始JavaScript代码的执行之前,引擎会创建好这个Scope Chain结构。
FunctionCode
函数对象在内部都有一个[[Scope]]属性,用来记录该函数所处位置的Scope Chain。
创建函数对象时,引擎会将当前执行环境的Scope Chain传给Function的[[Construct]]方法。[[Construct]]会创建一个新的ScopeChain,内容与传入的Scope Chain完全一样,并赋给被创建函数的内部[[Scope]]属性。在前面函数对象创建过程一节中,这个处理位于步骤4和5之间。
进入函数调用时,也会创建一个新的Scope Chain,包括同一个函数的递归调用,退出函数时这个Scope Chain被丢弃。新建的ScopeChain第一个对象是Activation Object,接下来的内容与内部[[Scope]]上存储的ScopeChain内容完全一样。
Eval Code
进入Eval Code执行时会创建一个新的Scope Chain,内容与当前执行上下文的Scope Chain完全一样。