作用域:指的是变量和函数的访问范围,也就是说作用域控制着变量的可见性和生命周期,包括局部作用那个与和全局作用域;
局部作用域:指的是一般只在固定代码片内可以访问的作用域,常见的在函数内部定义的变量或函数;
全局作用域:指的是在代码任何地方都可以访问的变量或对象。
例如在下面函数中,alert(a1)首先在fun2函数区域寻找有定义的a1变量,如果有,就使用fun2函数中定义的变量a1,如果没找到,就继续一层一层向父级函数找,在fun1中找到了,就使用fun1中定义的变量a1。
var a1 = 12;
function fun1(){
var a2 = "ab";
function fun2(){
var s3 = 100;
alert(a1);
}
fun2();//调用函数
}
fun1();//调用函数
作用域链:在JS中当查询一个变量x时,首先会查找作用域链的第一个对象,如果在第一个对象中没有找到变量x的定义,就会依次向上一个(父级)对象中取查找。
在上述代码中,作用域链依次是fun1,fun2,window.
注意:在javascript中,直接定义的变量,就是全局的window
全局作用域分为以下几种情形:
1)函数内部,局部变量的优先级比同名的全局变量优先级高
var a4 = 123;
function fun3(){
var a4 = 10000;//该变量的优先级要比同名的全局变量a4的优先级要高
alert(a4);
}
fun3();
2)在JS中没有块级作用域
var a5 = "string";
if (true){
var a6 = 123;
for(var a7 = 1;a7 < 4;a7 ++){
console.log("123");
}
}
以上代码中,a5,a6,a7作用域都是一样的,都是作用于window下的全局变量
3)最外层函数中声明的变量在本函数以及子函数都可以访问得到
function fun4(){
var a9 = "w";
function fun5(){
var a10 = 11;
a9 = "string";
alert(a9);
}
fun5();
var a11 = a10 + 1;
}
fun4();
局部变量的优先级高于全局变量,所以输出a9值为string,当在fun4()中调用a10时会显示a10没有定义,说明a10仅对当前函数可见,对父级函数是不可见的。
4)未使用var关键字定义的变量是全局变量
function fun6(){
a10 = 123;//声明了全局变量a10并赋值
}
alert(a10);//可以访问变量a10
注意:JS官方规定可以未使用的var关键字直接定义变量,但是浏览器解析时报错,所以禁止这种方式定义全局变量.
5)全局变量都是window对象属性
var a11 = 1000;
alert(a11);//1000
等价于
var a11 = 1000;
alert(window.all);
6) 作用域链的问题
var a12 = 12;
function fun7(){
alert(a12);//undefined
var a12 = 1000;
}
fun7();//调用
若把var a12 = 1000;换成a12 = 1000;其输出结果为
第一种情况解释:变量a12首先在fun7()中寻找有没有定义的a12变量,找到了但是在函数输出之后,所以会返回一个undefined的值;
第二种情况解释:变量a12首先在fun7()中寻找有没有定义的a12变量,没有定义的a1变量,就向父级找,找到了定义了的var a12 = 12变量,使用这个函数里面定义的变量。
所谓对象就是一种无序的数据集合,由若干个键值对(属性-值)构成
var a = {} //特点:书写简洁,常用来创建对象
var b = new Object()
var c = Object.create(null) //通过构造函数创造对象实例
1)符合规范的对象键名都是字符串,加不加””和’’都可以
var obj = {
"p":"hello world"
};
var obj1 = {
p:"hello world"
};
alert(obj.p+"\n"+obj1.p);
2)如果键名不符合标示符的条件(如第一个字符为数字或者含有恐吓或运算符等),则必须加上双引号或单引号,否则会出错
var obj2 = {
1p:"hellow world";
};
var obj2 = {
1p:"hellow world";
1+p:"hellow world";
};
不同变量名指向了同一个对象,那么他们都是这个对象的引用,也就是他们都是这个对象的引用,也就是他们共同指向了同一块内存区域,修改其中的一个变量的值,都会改变其他变量的值
var obj3 = {};
var obj4 = obj3;
obj4.str = "123";
alert(obj3.str);
例如代码
{name:"zhangsan"}
1)如果像上面写法,JS是无法判断这个到底是表达式,还是语句(代码块),产生歧义
2)如果该代码出现在首行,也就是首行是{},一律解释为语句(代码块)
3)如果要解释为表达式(对象),则必须加上圆括号 ({name:"zhangsan"})
2.6 对象的属性
1)通过(.)读取对象属性值
var obj5 = {
name:"张三"
};
alert(obj5.name);
2)通过下标读取属性的值
var obj5 = {
name:"张三"
};
alert(obj5["name"]);
注意:
读取的属性如果是字符串类一定要加""或'',否则报错;
读取的属性如果是数字可加可不加
3)对象的属性赋值
var obj6 = {
a:"name"
};
obj6.a = "zhangsan";
obj6['a'] = "zhangsan";//或者
4)对象的属性查看.使用object.keys方法获取
var obj7 = {
name:"zhangsan",
age:23,
sex:"男",
weight:"50KG"
};
var keys = Object.keys(obj7);
console.log(keys);
也可以采用in属性方法获取obj7的值
for(var i in obj7){
alert(i);//打印的是对象中的属性(key)
alert(obj7[i]);//打印的是属性值(value)
}
字符串就是将0个或多个排在一起的字符,放在单引号或双引号之间,单个字母、单个数组或单个符号都可以称之为字符串
1)单引号里面可以嵌套双引号,但是不可以嵌套单引号;双引号里面可以嵌套单引号,但是不可以嵌套双引号
2)字符串连接
可以使用\将不在同一行的的字符串连接成一行
var str7 = "helloworld helloworld\"
"helloworld helloworld\"
"helloworld helloworld";
也可以使用字符+将多个字符串链接成一行
var str7 = "helloworld helloworld"
+"helloworld helloworld"
+"helloworld helloworld";
1)包括:
\0 null
\b 后退键
\f 换页符
\n 换行符
\r 回车
\t 制表符
\v 垂直制表符
\' 输出单引号
\" 输出双银行
\ 连接符
转义字符为单独一个字符,在字符串中占一个长度
2)反斜杠的使用
\HHH 反斜杠后面跟3个八进制位(000--377);
var str8 = '\251';
\xHH 反斜杠后面跟2个十六进制位(00--FF);
var str9 = '\xFF';
\uXXX 反斜杠后面跟4哥16进制位(0000---FFFF);
var str10 = '\u0001';//常见于unload编码格式
注意:
1.在计算字符串长度时,上面的三种情况,也是当做一个字符参与字符串长度计算
2.算字符串长度,其实是计算的字符串字符的个数
3.所有转义字符只对控制台打印起作用.
1)字符串可以视为字符数组,因此可以通过数组的下标形式来访问字符串中的字符(下标从0开始)
var str10 = "hello world";
alert(str10[6]);//值:w
2)字符串毕竟不是数组,无法通过下标形式来改变字符串中的某个字符
str10[6] = 'H';//错误,无法修改
3)字符串的length属性不可设置
strll.length = 2;//错误
1)Javascript使用的是Unicode字符集,也就是在javascript内部,所有的字符都是用Unicode表示
2)Javascript不仅能用Unicode储存字符,还允许程序中使用Unicode来表示字符,
3)形式;/uXXXXX;其中XXXX表示Unicode编码,例如"\uFFFF";
1)自变量创建
var str1 = "hello world";
2)构造函数创建字符串对象
var str2 = new String("hello world");
该方法中的参数是一系列Unicode的码点(例如:'\u0012'码点:0012),返回对应的字符串,
传入参数的值不能超过0xFFFF大小,
该方法定义在对象本身,而不是创建对象实例方法上面
var str = String.fromCharCode(0x12,0x45,0x67,0x122,0xfe);
alert(str);
注意:String.fromCharCode 而不是str.fromCharCode
1)length 返回字符串的长度
2)charAt() 返回指定位置的字符,参数从0开始
var str1 = "hello";
var res1 = str1.charAt(1);//res1 = e
console.log("res1="+res1);
注意,该方法等效于用数组下标方式返回字符,但是如果参数为负数或者超过字符串长度,charAt将返回空字符串
该函数返回给定位置字符Unicode的码点(10进制表示),刚好是String.fromCharCode()的逆操作
var str2 = "acd";
var res3 = str2.charCodeAt(2);u
alert(res3);//100
逆操作:
var resu3 = String.fromCharCode(100);//把100转化为Unicode字符d
alert(res3);
concat中参数可以写多个字符串
var str3 = "hello";
var str4 = "world";
var str5 = "zhang";
var str6 = "san";
var res11 = str3.concat(str4,str5,str6);
alert(res11);//输出helloworldzhangsan
var res12 = "abc".concat();
alert(res12);//输出abc
用于从原来字符串中取出子字符串并返回
1)slice()中有2个参数,第一个参数字符串的起始位置,第2个参数子字符串的结束位置
var str7 = "hello world";
var res14 = str7.slice(6,11);
alert(res14);
2)如果slice省略第二个参数,则表示字符串一直到整个字符串结束位置
var res15 = str7.slice(6);
alert(res15);//输出结果也为world
3) 如果该函数只有一个参数,且为负值,则从字符串结尾开始(从右向左)计算位置
var res16 = str7.slice(-5);//
alert(res16);//输出world
var res17 = str7.slice(12,5);//返回空字符串
alert(res17);//输出为空
从原字符串中取出子字符串,跟slice使用一样,一般优先使用slice函数
var str8 = "helloworld";
var str18 = str8.substring(0,5);//输出hello
如果该函数的第一个参数大于第二个参数,系统会自动调换2个数的位置
var str18 = str8.substring(5,0);
var res20 = str8.substring(0,-4);//会把-4变成0,返回为空字符串
从原字符串取出子字符串,并返回
1)两个参数(第一个参数:字符的起始位置;第2个参数:取出字符的个数)情况
var res22 = "asdfghjkl".substr(2,5);//dfghj
2)省略第二个参数表示一直到字符串的结束
var res22 = "asdfghjkl".substr(4);//ghjkl
3)如果第一个参数是负数,从右向左计数
var res23 = "asdfghjkl".substr(-2);//kl
4)该函数两个参数都是负值,第二个参数值是负值,则会自动转换为0
1)这两个方法用于确定一个字符串在另外一个字符串中的起始位置,都返回一个整数,表示匹配的开始位置,如果返回-1表示不匹配
2)区别在于indexOf()从字符串的头部开始匹配;lastIndexOf()从字符串的尾部开始匹配
var stri = "adcdssed".indexOf("cds");//从左到右第一次出现的位置
var stri1 = "aslskkd".lastIndexOf("s");//从右到左第一次出现的位置
alert(stri);//输出2
alert(stri1);//输出3