定义变量是通过var关键字来定义一个变量,若变量不通过var定义,则视为全局变量。
var name;//变量声明
var age;//变量声明
var add;//变量声明
var name="AFADF",age=23,add=false;
变量名的规则:
var name ="hello";
var name = "world";
变量在使用前需要初始化,给它一个值。
变量声明时未初始化,那么它的值是undefined,什么也不是。既不是字符串,也不是数值,也不是对像。
var name="朱元璋"; //变量声明时初始化
var age=78; //变量声明时初始化
var name; //变量声明时无值,undefined
name="朱元璋"; //初始化
若按照变量作用域和变量生命周期来划分,可将变量分为全局变量和局部变量。
从作用域角度,全局变量位于作用域链的最顶端;从变量生命周期角度,全局变量生存期为整个程序生命周期,即直到程序结束,全局变量才销毁。
var address = "北京";//全局变量
function GetUserInfo() {
var userName = "小王";//userName局部变量
return userName +"-"+ address;
}
console.log(GetUserInfo());//小王-北京
console.log(address);//北京
从作用域角度,局部变量位于特定的局部域,如特定的函数内部;从变量生命周期角度,局部变量声明周期只在其所处的特定作用域内,超出该作用域,就失效。如函数变量,直在函数内部有效。
function GetUserInfo() {
var userName = "我是小王";
return userName;
}
console.log(GetUserInfo());//我是小王
console.log(userName);//报错:userName is not defined
JS中的变量作用域是通过this指针,从当前的作用域开始,从当前作用域由内向外查找,直到找到位置,这里分为几个逻辑:
.从当前作用域由内向外查找,若找到,就停止查找,否则,继续查找,直到查到window全局作用域为止,若任然未找到,则会出错,提示该变量未定义;
当内部作用域变量名与外部作用域变量名相同时,内部作用域的覆盖外部作用域。
var dateTime='2018-09-16';
function GetUserInfo(){
var age=120;
var name="中国";
function printme(){
var name="hello";
var address="中国";
//中国-拳王-2018-06-05
console.log(address+"-"+name+
"-"+age+"-"+dateTime);
}
return printme();
}
GetUserInfo();//中国-hello-2018-09-16
作用域有三层:全局,GetUserInfo()函数内,printme()函数内。在printme()函数中,在调用log()函数时,name变量用本作用域中的name(=“hello”),age在本域中无此变量,则用外层的age变量,dateTime变量在本域中和外层域中都没有这个变量,在再外层的外层中去查找。
定义全局变量的另一种方式,就是不使用关键字var
function GlobalParam() {
userName = "hello";// 在函数中定义一个全局变量
}
GlobalParam();
console.log(userName);//hello
var maxNum = 100;
for (var i = 0; i < maxNum; i++) {
var sum = 0;// 这个变量,在外层是可以访问到的
sum = sum + i;
}
console.log(sum);//99。因为JavaScript没有块级作用域,因此能在for语句外部访问变量sum
{
var test = "hello";
}
console.log(test ); // "hello", 在C++和C#等开发语言不同。
js中的变量虽然不区分类型,但是实际上Ecmascript包含两种类型,基本类型和引用类型.
基本类型有5种:Undefined,Null,Boolean,Number,String,基本类型是按值访问的,因为可以操作保存在变量中的实际的值。
引用类型的值是保存在内存中的对象。与其他语言不同,JavaScript 不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用(也称为句柄)而不是实际的对象.
每个对象中都有一个引用次数,跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减 1。当这个值的引用次数变成 0 时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾收集器下次再运行时,它就会释放那些引用次数为零的值所占用的内存。
垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。
function mem_leaks(){
leak_str = 'xxxxxx';//leak_str 成为一个全局变量,不会被回收
}
var leaks = (function(){
var leak = 'xxxxxx';// 被闭包所引用,不会被回收
return function(){
console.log(leak);
}
})()
对象是组成类型,一个对象是多个原始类型的值的集合,可以看作是一个存放各种值的容器。对象是最复杂的数据类型,又可以分成三个子类型:
狭义的对象(object)
数组(array)
函数(function)
狭义的对象和数组是两种不同的数据组合方式,除非特别声明,一般而言“对象”都特指狭义的对象。函数其实是处理数据的方法,JavaScript 把它当成一种数据类型,可以赋值给变量,这为编程带来了很大的灵活性,也为 JavaScript 的“函数式编程”奠定了基础。
NaN 属性是代表非数字值的特殊值。该属性用于指示某个值不是数字。可以把 Number 对象设置为该值,来指示其不是数字值。
使用 isNaN() 来判断一个值是否是数字。原因是 NaN 与所有值都不相等,包括它自己。
isNaN() 函数可用于判断其参数是否是 NaN,该值表示一个非法的数字(比如被 0 除后得到的结果)。
console.log(typeof Number.NaN === 'number'); // true
null的类型,使用typeof时返回的是object,只把它当作object的一种特殊值。
不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型,null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回“object”。
console.log(typeof null);// object
都可以表示“没有”,含义非常相似。将一个变量赋值为undefined或null,老实说,语法效果几乎没区别。实际的区别是:null是一个表示“空”的对象,转为数值时为0;undefined是一个表示"此处无定义"的原始值,转为数值时为NaN。
注意:
JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是:
字面量是由语法表达式定义的常量;或通过由一定字词组成的语词表达式定义的常量。
var arr = ["a", "b", "c"];
var a=[3];
布尔字面量
true和false。
不要混淆作为布尔对象的真和假与布尔类型的原始值true和false。布尔对象是原始布尔数据类型的一个包装器。
整数字面量
整数可以用十进制(基数为10)、十六进制(基数为16)、八进制(基数为8)以及二进制(基数为2)表示。
十六进制整数以0x(或0X)开头,可以包含数字(0-9)和字母 a~f 或 A~F。
0, 117, -345 (十进制, 基数为10)
015, 0001, -0o77 (八进制, 基数为8)
0x1123, 0x00111, -0xF1A7 (十六进制, 基数为16或"hex")
0b11, 0b0011, -0b11 (二进制, 基数为2)
一个十进制整数,可以带正负号(即前缀“+”或“ - ”),
小数点(“.”),
小数部分(由一串十进制数表示),
指数部分。
指数部分以“e”或“E”开头,后面跟着一个整数,可以有正负号(即前缀“+”或“-”)。浮点数字面量至少有一位数字,而且必须带小数点或者“e”(大写“E”也可)。
简言之,其语法是:
[(+|-)][digits][.digits][(E|e)[(+|-)]digits]
3.14
-.2345789 // -0.23456789
-3.12e+12 // -3.12*1012
.1e-23 // 0.1*10-23=10-24=1e-24
对象字面量
对象字面值是封闭在花括号对({})中的一个对象的零个或多个"属性名-值"对的(元素)列表。你不能在一条语句的开头就使用对象字面值,这将导致错误或产生超出预料的行为, 因为此时左花括号({)会被认为是一个语句块的起始符号。
RegExp 字面值
一个正则表达式是字符被斜线(译注:正斜杠“/”)围成的表达式。
var re = /ab+c/;
""
''
"adfadf"
'12312'
"123564564"
javaScript是一种动态类型语言,声明变量时可以不必指定数据类型,而数据类型会在代码执行时会根据需要自动转换。
在包含的数字和字符串的表达式中使用加法运算符(+),JavaScript 会把数字转换成字符串。
var a = "1234"+56; // 123456
在涉及其它运算符(减号’-’)时,JavaScript语言不会把数字变为字符串。
var a = "100" - 10// 90
var a = "10" * 10// 100
var a = "10" / 2// 5