JAVASCRIPT
1.变量
1.1概念
变量源于数学,是计算机语言中存储计算结果或表示值抽象概念
计算机有个地方叫内存,变量都会将值存入到内存中,变量就是指向这个值的名字
1.2命名规则
1. 由字母数字下划线和$组成
2. 不能以数字开头
3. 严格区分大小写
4. 不能使用关键字和保留字
关键字和保留字
ECMA-262第3版描述的关键字
break | do | instanceof | typeof |
---|---|---|---|
case | else | new | var |
catch | finally | return | void |
continue | for | switch | while |
debugger* | function | this | with |
default | if | throw | delete |
in | try |
ECMA-262第3版描述的保留字
abstract | enum | int | short |
---|---|---|---|
boolean | export | interface | static |
byte | extends | long | super |
char | final | native | synchronized |
class | float | package | throws |
const | goto | private | transient |
debugger | implements | protected | volatile |
double | import | public |
ECMA-262第5版本非严格模式
class | enum | extends | super |
---|---|---|---|
const | export | import |
ECMA-262第5版严格模式
implements | package | public | interface |
---|---|---|---|
private | static | let | protected |
yield |
2.数据类型
2.1字符串string
- 概念:由零个或者多个16位Unicode字符组成的字符序列。
- 定义方式:使用单引号''和双引号""定义字符串
单双引号的特点
- 单双引号没有区别,都不解析变量
- 单双引号可以相互嵌套
- 不可以嵌套自身,除非使用转义字符\转义
// 单引号
var str1 = '老板,瓜甜吗?';
// 双引号
var str2 = "滚犊子,这是苦瓜";
// 关于单引号嵌套双引号
var str3 = '王健林说:"先定一个小目标,先赚它一个亿"';
// 双引号嵌套单引号
var str4 = "俊哥说自己很'帅',大家都笑了";
// 关于嵌套自身
var str5 = ''单引号'' // 最外层的一组单引号定义字符串,内层的一组单引号作为普通单引号字符串,为了避免语法报错和歧义,使用转义字符转义
特点:
1. 字符串是不可以改变的,一旦创建,值不能改变,如果改变,要先销毁原来的字符串,用新值填充
var name = '俊哥'; name += '很帅'; // 俊哥很帅
2.转为字符串
第一种方法: str.toString() 除null和undefined之外,所有的数据都可以通过 数据.toString()转为字符串 //会报错 第二种方法: String():将任何值都可以转为字符串 对象=>字符串:[Object Object] 其他数据=>原型输出
3.特殊字符串
\n 换行 \t 制表符 \r 回车 \ 斜杠(\有转义的意思,需要展示,使用\转义自身) \unnnn 16进制代码nnnn表示一个Unicode字符(n为0-F)
2.2 数值(Number)
1. 整数
// 十进制
var num1 = 12;
// 八进制(第一位必须是0)
// 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24
var num2 = 070; // 等价于 十进制56
注意:八进制在严格模式下报错
// 十六进制(第一位必须是0x)
// 0 1 2 3 4 5 6 7 8 9 a b c d e f 10
var num3 = 0xA; // 等价于 十进制10
注意:八进制和十六进制的数值最终都会转换为十进制数值进行 算数计算
2. 浮点数
var num1 = 1.1;
var num2 = 0.8;
var num3 = .4; // 不推荐
注意:
1. 0.1 + 0.2 = 0.30000000000000004
2. 0.8 - 0.2 = 0.20000000000000007
这是基于IEEE754的数值进行计算的通病,有计算损耗
所以:请不要使用浮点数进行精确计算
3. NaN(Not a Number)
概念:表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)
3 - 'a' // 不知道结果,NaN
4 * 'b' // 不知道结果,NaN
5 / 'z' // 不知道结果,NaN
4 + 'x' // 结果:4x(此时+ 是连接运算符)
4. 其他数据转换为数值
Number转换规则
字符串=>数值 ''=>0 纯数字字符串=>原型输出(***) 普通字符串=>NaN(***) '0xf'=>15(支持十六进制字符串转换为十进制) 布尔值=>数值(***) true=>1 false=>0 数值=>数值 原型输出 null=>0(***) undefined=>NaN(***) 对象=>数值 调用对象的valueOf()方法进行检测,检测结果是NaN 继续调用对象toString()方法,再按前面的规则返回字符串值
parseInt转换规则
从第一个字符开始查找,直到找到第一个非法数字截止,找到的即是转换结果 'abc'=>NaN '23ab'=>23 true=>NaN null=>NaN '32.18'=>32 undefined=>NaN 特殊: '0xf'=>15(可以转换16进制) 进制之间的转换 parseInt('10',2) // 2 parseInt('10',8) // 8 parseInt('10',10) // 10 parseInt('10',16) // 16 parseInt('AF',16) // 175
parseFloat转换规则
从第一个字符开始查找,直到找到第一个非法字符(除数字和第一个小数点)截止,找到的即是转换结果 'abc'=>NaN '23ab'=>23 true=>NaN null=>NaN undefined=>NaN 25=>25 '32.18'=>32.18
2.3 布尔值(Boolean)
true:真
false:假
只有以下7个值转换为布尔值为假,其他为真
'' //空字符 0 0.0 NaN false null undefined
2.4 未定义(undefined)
- 未定义的变量
- 定义但是未赋值的变量
// 定义但是未赋值
var str;
console.log(str); // undefined
// 由typeof 检测未定义的变量
console.log(typeof abc); // undefined
如果不用typeof检测,直接打印输出一个未定义的变量,在JS中会直接报错
注意:两种未定义的情况
console.log(a); //如果a在整个代码中都未定义过,那么JS报错a is not defined
console.log(a); //程序都是顺序执行,虽然a还是未定义,但是整个代码中有a的存在,程序不会报错,执行出来是undefined
var a;
跟函数比较相似
浏览器在执行script代码的时候,先将script内部的函数和变量值全部"登记",然后才去执行具体的每一行代码
执行到console.log(abc)的时候,没有"登记"过abc,则abc直接报错,说没有定义该变量,而且终止了代码的执行
执行到第一个console.log(a)的时候,曾经"登记"过a变量,但是a变量在下面定义的,于是浏览器认为说a属于定义了但是未赋值的状态,就赋值为undefined, 不会报错
函数跟变量不一样的地方是:
函数提前登记之后,可以直接提前调用,但是变量值提前调用只是不报错,拿不到下面定义的值
2.5 对象(object)
null
console.log(typeof null);
array数组
var arr = ['a','b','c']; console.log(typeof arr);
对象
var obj = {}; console.log(typeof obj);
属性Object.keys(传入的对象); 并且以数组形式输出
var obj = {a:1,b:2,c:3}
Object.keys(obj) //['a','b','c']
2.6 函数(function)
function demo(){}console.log(typeof demo); // function
3. 运算符
3.1 算术运算符
1. 普通算数运算符: + - * / %
var num1 = 8;
var num2 = 5;
console.log(num1 + num2); // 13
console.log(num1 - num2); // 3
console.log(num1 * num2); // 40
console.log(num1 / num2); // 1.6
console.log(num1 % num2); // 3 等价于 8/5=1...3
注意:当/ % 的除数为0时,5/0 5%0 测试结果为Infinity Infinity 无穷大的意思
当/ % 的除数为0时 测试类型是 typeof(5/0) 或typeof(5%0) 为NaN
2. 特殊算数运算符: ++ --
- 认识++和--
// ++:让自身自增1
var num1 = 5;
num1++;
console.log(num1); // 6
var num2 = 8;
++num2;
console.log(9);
// --:让自身自减1
var num3 = 4;
num3--;
console.log(num3); // 3
var num4 = 2;
--num4;
console.log(num4); // 1
总结:
1.i++,i-- 是先运算在+ -
++i,--i是先+ -,再运算
2. 不管++在变量之前,还是在变量之后,都是让自身增加1
不管--在变量之前,还是在变量之后,都是让自身减小1
- 区分++/--在前和在后的区别
var num1 = 5;
// num1++:++在变量num1之后,先执行console.log,再执行自身自增1
console.log(num1++); // 5
console.log(num1); // 6
var num2 = 3;
// ++num2:++在变量num2之前,先执行自身自增1,在执行console.log
console.log(++num2); // 4
console.log(num2); // 4
// 举例
var num3 = 4;
var num4 = 8;
// 解释:num4++(++在后),num4会先和num3运算得出计算结果,然后自身再自增1为9,所以+运算的结果是12,运算结束num4的值变为9
console.log(num3 + num4++); // 12
console.log(num3,num4); // 4 9
总结:
2. ++在变量前,先自增1再运算
++在变量后,先运算再自增1
--在变量前,自减1再运算
--在变量后,先运算再自减1
==============================================
注意:这里大家会考虑,都算完了,再自减1有毛线的作用?
减1之后,对之后的运算会产生影响,请看例子
var num5 = 1;
var num6 = 3;
console.log(num5 + num6++ + num6); // 1 + 3 + 4 = 8
第一个+运算执行的是:1 + 3
num6++:自身自增1
第二个+运算执行的是:4 + 4(中间num6++,num6变为了4)
==============================================
3.2 赋值运算符 = += -= *= /= %=
// 将4赋值给num变量
var num = 4;
console.log(num); // 4
// 将num1自增5,再赋值给自身
var num1 = 3;
num1 += 5; // 等价于 num1 = num1 + 5
console.log(num1); // 8
// 将num2自减5,再赋值给自身
var num2 = 14;
num2 -= 5; // 等价于 num2 = num2 - 5
console.log(num2); // 9
// 将num3自乘5,再赋值给自身
var num3 = 3;
num3 *= 5; // 等价于 num3 = num3 * 5
console.log(num3); // 15
// 将num4自除5,再赋值给自身
var num4 = 10;
num4 /= 5; // 等价于 num4 = num4 / 5
console.log(num4); // 2
console.log(typeof 7/0) //NaN
// 获取num5跟5取余的结果,再赋值给自身
var num5 = 13;
num5 %= 5; // 等价于 num5 = num5 % 5
console.log(num); // 3
console.log(typeof 7%0) //NaN
3.3 比较运算符 == === != !== > < <= > >=
1. 相等比较:== ===
var num1 = 3;
var num2 = 3;
console.log(num1 == num2); // true
var num3 = 4;
var num4 = 2;
console.log(num3 == num4); // false
var num5 = 7;
var num6 = '7';
// ==:只比较值大小,不比较类型
console.log(num5 == num6); // true
var num7 = 7;
var num8 = '7';
// ===:比较值和类型,都相等结果为true
console.log(num7 === num8); // false
// 特例
console.log(null == undefined); // true
console.log(null === undefined); // false
null==0 //false
0==undefined //false
2. 不相等比较: != !==
var num1 = 4;
var num2 = 5;
console.log(num1 == num2); // false
// num1和num2不相等返回true
console.log(num1 != num2); // true
var num3 = 3;
var num4 = '3';
console.log(num3 === num4); // false
// num3和num4值和类型有一个不相等返回true
console.log(num3 !== num4); // true
3. 大于小于比较: > >= < <=
var num1 = 5;
var num2 = 19;
console.log(num1 > num2); // false
// num1>num2成立或者num1==num2成立都可以返回true
console.log(num1 >= num2); // false
console.log(num1 < num2); // true
// num1<num2成立或者num1==num2成立都可以返回true
console.log(num1 <= num2); // true
3.4 逻辑运算符
1. 逻辑与:&& - 两真为真,其余都为假
console.log(true && true) // true
console.log(true && false) // false
console.log(false && true) // false
console.log(false && false) // false
本质是:
// 将&&两侧的值"隐式"转为布尔值进行判断
console.log(3 && 'a') // a
console.log('abc' && 23) // 23
console.log('abcd' && null); // null
console.log(0 && '么么哒') // 0
***console.log(undefined && null) // undefined***
***注意:
如果&&两侧都为真,那么以后面的为结果;
如果&&两侧都为假,那么以前面的为结果。
2. 逻辑或:|| - 两假为假,其余都为真
console.log(true || true); // true
console.log(true || false); // true
console.log(false || true); // true
console.log(false || false);// false
本质是:
console.log(23 || 8); // 23
console.log('ab' || null) // ab
console.log(undefined && '萌萌哒'); // 萌萌哒
console.log(null && undefined); // undefined
*注意:
如果||两侧都为真,那么以前面的为结果
如果||两侧都为假,那么以后面的为结果
3. 取反
console.log(!true); // false
console.log(!false);// true
本质是:
console.log(!23); // false
console.log(!null); // true
console.log(!0); // true
3.5 条件运算符(三元运算符)
var result = 布尔值 ? 布尔值为真走这 : 布尔值为假走这;
var result = 5 > 3 ? '婚姻大事全凭父母做主' : '小女子还想侍奉父母两年';
console.log(result); // 婚姻大事全凭父母做主
3.6 特殊的+:连接运算符
1.特殊1:+
var num1 = 3;
var num2 = 'a';
var num3 = 8;
console.log(num1 - num2); // NaN
console.log(num1 * num2); // NaN
console.log(num1 / num2); // NaN
// +两边有非数字'a',取连接运算
console.log(num1 + num2); // 3a
// +两边是纯数字,取加法运算
console.log(num1 + num3); // 11
var num4 = 5;
num4 += 13; // num4的值为18
num4 += 'abc'; // num4的值变为18abc
2. 特殊2:- * /
var num1 = 12;
var num2 = '5';
console.log(num1 - num2); // 7
console.log(num1 * num2); // 60
console.log(num1 / num2); // 2.4
console.log(num1 % num2); // 2
总结:
除+之外,其余的运算符,在进行纯数字运算的时候,正常运算
3.特殊的+
var num1 = '5';
// 将字符串类型的num1变为数字
console.log(+num1); // 5
console.log(+num1+12); // 17
console.log(3+ +num1); // 8
总结:
在纯数字字符串前多写一个+,可以将字符串类型的数字变为数值类型的数字
3.7 运算符优先级
优先级 | 运算符 |
---|---|
12 | 成员访问(obj.username)、数组访问(arr[1])、new(new Person)、函数调用(demo()) |
11 | 后置递增(num++),后置递减(num--) |
10 | 取反(!) 前置递增(++num) 前置递减(—num) typeof void delete |
9 | 乘法(*) 除法(/) 取余(%) |
8 | 加法(+) 减法(-) |
7 | < <= > >= in instanceof |
6 | == != === !== |
5 | 逻辑与(&&) |
4 | 逻辑或(||) |
3 | 三元运算符(? :) |
2 | 赋值运算符(= += -= *= /= %=) |
1 | 逗号(,) |
4.流程控制
4.1 顺序分支
代码从上向下执行
4.2 条件分支
1. if条件分支(具体值和范围判断都可)
// 定义变量
var age = 24;
// 只有if判断
if (age < 18) {
console.log('小弟弟,你好小');
}
// if...else...判断
if (age < 18) {
// 当年龄小于18岁的时候,执行此段代码
console.log('年龄小于18岁');
} else {
// 当年龄大于等于18岁的时候,执行此段代码
console.log('年龄大于18岁');
}
// if...else if...else...
if (age < 18) {
console.log('年龄小于18岁');
} else if (age >= 18 && age < 24) {
console.log('年龄在18(包含)到24(不包含)岁之间');
} else if (age >= 24 && age < 30) {
console.log('年龄在24(包含)到30(不包含)岁之间');
} else {
console.log('年龄大于等于30岁');
}
2. switch语句(具体值判断)
// 将数值转换为具体的星期
var week = 3;
switch (week) {
case 1:
console.log('星期一');
break;
case 2:
console.log('星期二');
break;
case 3:
console.log('星期三');
break;
case 4:
console.log('星期四');
break;
case 5:
console.log('星期五');
break;
case 6:
console.log('星期六');
break;
case 7:
console.log('星期日');
break;
default:
console.log('输入的数据有误');
}
利用break进行合理的合并处理
var month = 1;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
console.log('31天');
break;
case 4:
case 6:
case 9:
case 11:
console.log('30天');
break;
case 2:
console.log('28天');
break;
default:
console.log('输入的月份有问题');
}
月份是1 3 5 7 8 10 12的时候,程序输出31天,并break(打断),不再执行下面的代码
月份是4 6 9 11的时候,程序输出30天,并break(打断),不再执行下面的代码
如果都不是,程序输出"输入的月份有问题"
if (month == 1) {
} else if (month == 2) {
} else if (month == 3) {
}
4.3 流程控制-循环语句
1. for循环
for (var i = 0; i < 10; i++) {
console.log(i);
}
2. while循环
var i = 0;
while (i < 10) {
console.log(i);
i++;
}
3. do...while循环
var i = 0;
do {
console.log(i);
i++;
} while (i < 10);
无论条件是否成立,都先执行一次do中的代码
4. break和continue语句
***break 如果在多层循环嵌套中,是终止当前层循环
*continue 是跳出当前循环,继续执行当前层循环的下一次循环
// break:终止循环
for (var i = 0; i < 10; i++) {
if (i == 4) {
break;
}
console.log(i);
}
// 最终的结果是:0 1 2 3
// 跳过当前循环继续执行下一次的循环
for (var i = 0; i < 10; i++) {
if (i == 4) {
continue;
}
console.log(i);
}
// 最终的结果是:0 1 2 3 5 6 7 8 9
5.函数
5.1 功能(为什么用)
- 减少代码重复书写的次数
- 提升开发效率,缩短开发时间
5.2 函数定义
1. 函数申明
// 1.定义普通函数
function demo(){
console.log('第一种定义函数方式');
}
// 调用函数
demo();
2. 匿名函数
// 使用1:函数表达式
var fun = function(){
console.log('第二种定义函数方式');
}
// 匿名函数第一种调用方式
fun();
// 使用2:匿名函数自调用
(function(){
console.log('匿名函数自调用');
})();
// 使用3:作为其他函数的参数
setTimeout(function(){
console.log('1s之后显示在控制栏');
}, 1000)
3. 使用Function构造函数
var fun = new Function('x','y','console.log(x+y)');
fun(3,8)
4. 箭头函数(ES6)
// 下面三个函数是一致的
var fun = function(a,b){return a+b;}
var fun = (a,b)=>a+b;
var fun = (a,b)=>{return a+b};
// 调用函数
fun(3,9);
5.3 特点
函数名定义规则
- 由字母数字下划线$组成
- 不能以数字开头
- 不能使用系统关键字和保留字命名
定义函数而不调用没有意义
调用特点:同一个
因为浏览器内核对JS代码有预解析,将JS代码先读一遍,如果看到有函数,将函数登记一下,再从第一行开始执行,执行到调用的函数时,内核发现调用了该函数,就可正常调用。
<script> // 在同一个script标签内,函数可以先调用再定义 demo(); function demo(){ console.log('demo函数'); } </script>
<script> // 在同一个script标签内,函数表达式定义方式不能提前调用 fun(); var fun = function(){ console.log('函数表达式方式'); } </script>
<script> // 报错,而且不影响下面script标签内的代码执行 demo(); </script> <script> function demo(){ console.log('第二个script内的demo函数'); } </script> <script> // 正常调用 demo(); </script> // 一个页面中可以有多个<script>标签,在其中一个<script>定义函数,当前函数所在的<script>中的下一个<script>中调用上一个<script>中的函数,可以执行,但是如果当前<script>中定义的函数,在当前的<script>的上一个<script>中调用,会报错,但是不会影响到下面的<script>标签中的代码执行。+
同名函数会覆盖,不会报错 注意:在同一个
变量的作用域
- 在函数外声明的变量为全局变量,函数内可以直接调用
- 在函数内使用var声明的变量为局部变量,只能在函数内调用
- 在函数内不使用var,直接定义变量为全局变量(不推荐定义方式)
6.参数个数
- 形参 > 实参:多余的形参的值为undefined
- 实参 > 形参:多余的实参被忽略
argument函数内置对象 :由函数参数组成的数组
return 关键字
- 返回值
- 终止函数运行
call()/apply()
function demo(a,b){ console.log(a+b); }
// 格式不同,但结果一致
demo(2,4)
demo.call(null,2,4)
demo.apply(null,[2,4])
// 区别:
function demo(){console.log(this.username)}
var obj1 = {username:"zhangsan"}
var obj2 = {username:"lisi"}
demo.call(obj1) // zhangsan this指向obj1
demo.call(obj2) // lisi this指向obj2
5.4 函数结果值两种类型
1.功能函数 执行一个功能,而不需要返回值
function test(){
alert('ok');
}
var t = test();//先弹出ok
alert(t); //在弹出undefined; 一共弹出两次
2.返回值函数
function demo(){
return 'ok';
}
var d = demo();
alert(d); // ok 一共弹出一次
5.5 回调函数 callback
概念:函数A作为参数(函数引用)传递到另一个函数B中,并且这个函数B执行函数A。我们就说函数A叫做回调函数
理解:调用函数之后,该函数都不知道要做什么,就使用回调函数,让回调函数根据实际情况来写代码
// 一个函数 + 多个回调函数
function demo(m,n,cb){
var res = m + n;
cb(m+n);
}
// 调用demo之后,得到的结果是 打印、弹出、输出、写入DOM不知道,通过回调函数处理
demo(3,5,function(res){console.log(res);});
demo(3,5,function(res){alert(res);})
demo(3,5,function(res){document.write(res);})
demo(3,5,function(res){document.getElementById('box').innerHTML = res;})
// 如果同时存在alert,document.write和console.log ,无论先后书写顺序,执行顺序都是
alert > console.log > document.write;
function calc(a,b,res){
res(a,b);
}
//调用
calc(1,3,function(i,j){
console.log(i+j);
})
// 1=>a 3=>b function(i,j)=>res
5.6 递归函数
- 自己调用自己
- 必须有终止条件
// 代码理解
function demo(m){
console.log(m);
// 特点1:必须有终止条件(没有则是死循环)
if (m > 0) {
// 特点2:必须是自己调用自己
demo(m-1);
}
// 因为递归函数demo()的调用,让此处的打印一直处于等待状态,直到递归调用结束,就会调用这里的打印,而且是从内向外打印
console.log(m);
}
function demo(m){
console.log(m);
if(m>0){
demo(m-1);
}
console.log(m);
}
demo(3);
//结果
3 2 1 0 0 1 2 3
m=3 ,输出第一句console.log,m=3,然后m>0,此时下面的console.log的值存到内存中,但是先不执行,类似于入栈,此时m=3在内存的最底层。
然后m=2,输出第一句console.log ,m=2,然后m>0,此时下面的console.log的值存到内存中,但是先不执行,类似于入栈,此时m=2在m=3的上面。
然后m=1,输出第一句console.log ,m=1,然后m>0,此时下面的console.log的值存到内存中,但是先不执行,类似于入栈,此时m=1在m=2的上面。
然后m=0,输出第一句的console.log, m=0,判断m不大于0,不执行demo(m-1),然后输出最后一句的console.log m=0,
入栈的情况如下
m=1
m=2
m=3
内存中先执行的在最下面
最后,把内存中堆栈的内容输出,从上向下输出m=1,m=2,m=3
5.7 系统函数
eval():解析字符串,将JS字符串作为代码执行
var str = "var a = 3"; console.log(a); //a is not defined 报错
var str = "var a = 3"; eval(str); console.log(a); //3
encodeURI():编码URL地址,不会对ASCII字母、数字、~!@#$&*()=:/,;?+'编码
- 编码:就是把汉字转换为十六进制显示
- 解码:就是把十六进制转换为汉字显示
decodeURI():解码URL地址
encodeURIComponent:编码URL地址,不会对ASCII字母、数字、~!*()'编码
decodeURIComponent: 解码URL地址
escape(): 编码普通字符串
unescape(): 解码普通字符
5.8函数调用
- 函数调用还有两种方式
- 直接在定义的函数形参中写
- 支持高版本浏览器
function getNews(index = '0') // 形参是index 直接给index社会设置默认值
然后调用就不需要在写实参
getNews();
- 支持低版本浏览器,同时也支持高版本浏览器
function getNews(index){
index = index ? index : 0;
}
然后调用就不需要在写实参
getNews();
以上两种形式,相当于
getNews('0'); // 直接调用,给函数传递实参,
6 数组:数据的组合
1. 定义
// 1.数组字面量(***)
var cars = ['BMW', 'BYD', 'Benz'];
// 2.定义空数组
var cars = new Array();
cars[0] = 'BMW';
cars[1] = 'BYD';
cars[2] = 'BenZ';
// 3.定义有20个元素的数组
var arr = new Array(20);
// 4.定义有3个元素的数组
var cars = new Array('BMW', 'BYD', 'Benz');
注意:
1. 省略new可以
var arr = Array();
var arr = Array(20);
var arr = Array('BMW', 'BYD', 'Benz');
2. 特点
可以保存任何类型的数据
var arr = ['a',27,true,null,undefined,[1,2,3],{username:"Jeff"}];
数组元素的索引是从0开始计数的(***)
var arr = ['JavaScript高级程序设计', 'JavaScript设计模式', '深入理解ES6']; // 获取索引为0的值 console.log(arr[0]) // 设置索引为2的值 arr[2] = 'JavaScript语言精粹'; // 设置索引为99的值 arr[99] = 'JavaScript权威指南'; console.log(arr.length); // 100 console.log(arr[67]); // undefined 总结: 1. JS数组的索引一定是连续的 2. 没有定义的值为undefined
arr.length:获取和设置数组元素的长度
var arr = ['BMW', 'BYD', 'Benz']; // 获取数组元素个数(***) console.log(arr.length) // 3 // 利用length给数组末尾添加新值(*) arr[arr.length] = 'Bentley'; console.log(arr); // ['BMW', 'BYD', 'Benz', 'Bentley'] // 设置数组元素长度个数(*) arr.length = 2; console.log(arr); // ['BMW','BYD']
3. 循环数组
for循环(***) - 数组元素累加求和
var arr = ['zhangsan','lisi','wangwu']; for (var i = 0; i < arr.length; i++) { console.log(i,arr[i]); } 优点: 1. 兼容性好,大家都在用 2. 可以使用break和continue终止循环 缺点: 1. 格式复杂,需获取数组的长度
forEach循环(ES5新方法)//建议使用,比for的执行效率高
arr.forEach(function(value,key,arr){ // value:每个数组元素的值 key:每个数组元素的索引 arr:数组 console.log(value,key,arr) }) 优点: 1. 格式简单,不需要数组的长度 缺点: 1. 不可以使用break和continue 2. 不兼容IE8
for…in循环
// 循环获取数组的元素下标和元素(不需要知道数组元素的长度,但是效率比普通for循环差) for (var i in arr) { console.log(i,arr[i]); } 主要是循环对象(索引是字符串,数组的索引是数字) var obj = { "username":"zhangsan", "age":20 }; for(var i in obj) { console.log(i,obj[i]); //i是username和age obj[i]是zhangsan ,20 }
for…of循环(ES6新方法)
for (var value of arr) { console.log(value); } 优点: 1. 格式简单,不需要知道数组的长度 2. 可以使用break和continue 缺点: 1. 方法太新,以后是方向,目前只有最新的谷歌火狐浏览器支持
js知识
console.dir(); //打印目录内容
选择器
document.querySelector("#id");
document.querySelector(".class");
document.querySelector("TagName");
向下取整
Math.floor(x); //向下取整,小于等于x,并且与它最接近的整数
x:任意数值或者表达式
a = Math.floor(1.99); // 结果为1.0
b = Math.floor(1.01); // 结果为1.0
c = Math.floor(1.0); // 结果为1.0
d = Math.floor(-1.01); // 结果为 -2.0
随机数
Math.random(); //返回一个0.0到1.0之间的伪随机数,包含0 不包含1
返回值0<=x <1
封装的随机数函数
function rand(i,j){
return Math.floor(Math.random()*(j-i+1)+i);
}
调用:rand(3,5) //在3-5中随机选择出一个数字,包含3包含5
返回屏幕分辨率,跟窗口大小无关
window.screen.width();
7. 对象 = 属性(变量) + 方法(函数)
7.1. 定义对象
// 第一种:使用{},对象字面量方式定义对象
var obj = {
// 三个属性
username: 'zhangsan',
age: 20,
sex: '男',
// 一个方法
say:function(){
console.log('我的名字是:'+this.username);
console.log('我的性别是:'+this.sex);
console.log('我的年龄是:'+this.age);
},
info:function(){
this.say();//也可以调用当前对象中的方法
}
}
// 第二种:使用new Object定义
var obj = new Object();
// 三个属性
obj.username = '凤姐';
obj.age = 18;
obj.sex = '女';
// 一个方法
obj.say = function(){
console.log('我的名字是:'+this.username);
console.log('我的性别是:'+this.sex);
console.log('我的年龄是:'+this.age);
}
// 第三种
function Person(){
this.username = 'Jeff';
this.age = 18;
this.sex = '男';
this.say = function(){
console.log('我的年龄是:',this.age);
}
}
7.2. 调用对象属性和方法
// 获取对象属性值
console.log(obj.username)
console.log(obj.age)
console.log(obj.sex)
// 修改对象属性
obj.username = '芙蓉姐姐';
// 给对象添加属性
obj.weight = 150;
//添加方法
obj.info= function(){}
// 删除对象属性
delete obj.sex;
// 调用对象方法
obj.say();
//清空对象属性
obj.say = null;
7.3. 对象字面量格式注意
var obj= {
username: 'zhangsan',
age: 20,
sex: '男',
say: function{
console.log('say');
},
eat: function(){
console.log('eat');
}
};
总结:
1.属性名和方法名都必须符合变量的定义规则
2.每个属性和方法的结尾都使用,(最后一个例外,不要加,)
3.属性名和属性值之间,方法名和方法之间使用 : 来连接
4.属性值如果是字符串,必须添加""
7.4. []中括号、方括号获取属性值的特点
var obj = {username:'zhangsan'};
var str = 'username';
// 获取obj的username属性
console.log(obj.username); // zhangsan
console.log(obj['username']); // zhangsan
// obj没有str属性,所以obj.str和obj['str']最终结果都是undefined
console.log(obj.str); // undefined
console.log(obj['str']); // undefined
// obj[str]:str在此处作为变量处理,变量的值是'username'=>obj['username']
console.log(obj[str]); // zhangsan
//因为p['username']和p[str]的值一样,str是变量,str的值是'username'
总结:
1. 除使用变量访问属性(使用[])之外,其余我们一律使用obj.username此结构获取属性值
7.5. 循环对象 for in
// 循环获取对象中的属性和属性值(用于对象中只有属性的对象)
var obj = {username:"zhangsan",age:18,sex:"男"};
for (var i in obj) {
console.log(i,obj[i]);
}
//虽然数组中也可以用for in遍历,但是for in循环数组的话,数组的索引值本身是数值型,用for in遍历后数组的索引值变为字符型,所以for in一般只用于对象的遍历
7.6. 对象与基本类型比较
7.6.1. 基本类型是普通赋值(字符串,数值,布尔值,undefined)
- 特点1:str1和str2是双胞胎关系,两者在赋值之后无任何联系
var str1 = 'hello world';
var str2 = str1;
str2 = 'hello Jeff';
console.log(str1); // hello world
- 特点2:若比较,只比较值得大小
var str1 = 'pig';
var str2 = 'pig';
console.log(str1 == str2); // true
7.6.2. 对象类型是引用赋值(数组,函数,null,{})
- 特点1:obj1和obj2是取别名关系
var obj1 = {username:'zhangsan'};
var obj2 = obj1;
obj2.username = 'lisi';
console.log(obj1); // {username:'lisi'}
- 特点2:obj1和obj2长得一样,但是是不同的对象,通过指针指向的内存中的地址来做比较
var obj1 = {username:'zhangsan'};
var obj2 = {username:'zhangsan'};
console.log(obj1 == obj2); // false
9.内置对象
9.1 Array对象
arr.length:获取数组元素的长度
var arr = ['Tom','John','Amy']; arr.length // 3
arr.concat():合并两个或多个数组,返回一个新数组,不改变原数组
var arr1 = ['a', 'b', 'c']; var arr2 = ['d', 'e', 'f']; var arr3 = arr1.concat(arr2); // [ "a", "b", "c", "d", "e", "f" ]
arr.join(str):将arr以指定字符连接成字符串
var arr = ['Tom','John','Amy']; arr.join('#'); // Tom#John#Amy
arr.push():将新元素添加到一个数组中,并返回数组的新长度值。同时也改变了原数组
var arr = ['Tom','John','Amy']; arr.push('Jack'); // 4 arr // ['Tom','John','Amy','Jack']
arr.pop()移除数组中的最后一个元素,并返回该元素,同时改变原数组
var arr = ['Tom','John','Amy']; arr.pop(); // Amy arr // ['Tom','John']
arr.shift():移除数组中的第一个元素,并返回该元素,同时改变原数组
var arr = ['Tom','John','Amy']; arr.shift(); // Tom arr // ['John','Amy']
arr.unshift():在数组开头处添加指定元素,返回新数组的长度,同时改变原数组
var arr = ['Tom','John','Amy']; arr.unshift('Jack'); // 4 arr // ['Jack',Tom','John','Amy']
arr.sort([函数:排序规则]):排序(默认采用字符串顺序排序,数字排序则需要通过自定义函数实现),同时改变原数组
var arr = ['Tom','John','Amy']; arr.sort(); // ["Amy", "John", "Tom"] arr // 改变原数组:["Amy", "John", "Tom"]
排序函数 //第一种 function asc(a,b){ return a-b; // 升序 } function desc(a,b){ return b - a; //降序 } 调用:arr.sort(asc); //第二种 var res = arr.sort(function(a,b){ return a-b; //升序 }) var res = arr.sort(function(a,b){ return b - a; //降序 })
arr.reverse():数组元素顺序反转,同时改变原数组
var arr = ["Amy", "John", "Tom"]; arr.reverse() // ['Tom', 'John', 'Amy']
arr.indexOf():获取指定元素在数组中的位置(指索引位置),不存在返回-1
var arr = ["Amy", "John", "Tom"]; arr.indexOf('John'); // 1 arr.indexOf('David'); // -1
arr.lastIndexOf():获取指定元素最后一次出现的位置,不存在返回-1
var arr = ["Amy", "John", "Tom", "David", "Tom", "Jeff"]; arr.lastIndexOf('Tom'); // 4 arr.lastIndexOf('James'); // -1
arr.slice(起始位置,[结束位置]):获取数组中指定的片段(不包含结束位置) - 复制数组,如果不写结束位置,只写开始位置,是到数组的最后一个元素(可以理解为,从起始位置开始,获取的个数为结束位置-起始位置),原数组不发生变化
var arr = ["Amy", "John", "Tom", "David", "Jeff"]; arr.slice(2) // ["Tom", "David", "Jeff"] arr // 原数组不发生变化,["Amy", "John", "Tom", "David", "Jeff"] var arr = ["Amy", "John", "Tom", "David", "Jeff"]; arr.slice(2,4) // 不包含结束位置 ["Tom", "David"]
arr.splice(起始位置,长度,元素1,元素2...):从数组中添加,删除,修改元素。
arr.splice(2)//删除索引为2的元素
arr.splice(start,length)
arr.splice(start,length,"要插入的数组元素")
// 从索引2开始删除数组中所有的元素 var arr = ["Amy", "John", "Tom", "David", "Jeff"]; arr.splice(2) // ["Tom", "David", "Jeff"] arr // 原数组发生变化,["Amy", "John"] // 从索引2开始,删除数组中2个元素 var arr = ["Amy", "John", "Tom", "David", "Jeff"]; arr.splice(2,2) // ["Tom", "David"] arr // 原数组发生变化,["Amy", "John", "Jeff"] // 给数组添加元素:从2位置开始增加'jeff','David'两个元素 var arr = ["Amy", "John", "Tom"]; arr.splice(2,0,"Jeff","David"); console.log(arr); // ["Amy", "John", "Jeff", "David", "Tom"] // 给数组修改元素:从2位置开始用("Jeff","David","June")替换("Tom", "Ada") var arr = ["Amy", "John", "Tom", "Ada", "Alice"]; arr.splice(2,2,"Jeff","David","June"); console.log(arr); // ["Amy", "John", "Jeff", "David", "June", "Alice"]
arr.forEach():遍历数组 //建议使用,比for循环效率高,但是不支持IE8及以下版本
var arr = ["Amy", "John", "Tom", "Ada", "Alice"]; arr.forEach(function(value,key,arr){ console.log(value,key,arr); }) // 结果是将数组的值和索引,数组一一遍历出来 Amy 0 ["Amy", "John", "Tom", "Ada", "Alice"] John 1 ["Amy", "John", "Tom", "Ada", "Alice"] Tom 2 ["Amy", "John", "Tom", "Ada", "Alice"] Ada 3 ["Amy", "John", "Tom", "Ada", "Alice"] Alice 4 ["Amy", "John", "Tom", "Ada", "Alice"]
arr.every():检测数值元素的每个元素是否都符合条件。
var arr = [16,22,15,33,38,28]; // 要求:数组中的每个元素的值都必须大于18为true,如果有一个不大于18,返回false其余都为假 arr.every(function(value){ return value > 18; }) // false
arr.some():检测数组元素中是否有元素符合指定条件。
var arr = [16,22,15,33,38,28]; // 要求:数组中的每个元素都小于18为true,其余都为真 arr.some(function(value){ return value > 18; }) // true
arr.map():通过指定函数处理数组的每个元素,并返回处理后的数组
var arr = [16,22,15,33,38,28]; // 要求:数组中的每个元素的值都必须大于18为true,其余都为假 arr.map(function(value){ return value + 10; }) // [26,32,25,43,48,38]
arr.filter():检测数组元素,并返回符合条件所有元素的数组。
var arr = [16,22,15,33,38,28]; // 要求:数组中超过18的元素都被筛选出来 arr.filter(function(value){ return value > 18; }) // [22,33,38,28]
arr instanceof Array:判断arr是否是数组,是返回true,否返回false
Array.isArray():判断是否是一个数组(不支持IE8)
Array.isArray([1, 2, 3]); // true Array.isArray({foo: 123}); // false Array.isArray("foobar"); // false Array.isArray(undefined); // false
array.reduce(callback,initnum):累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){ return accumulator + currentValue; }); // 最终结果:10 accumulator:计算值 currentValue: 当前值 currentIndex: 当前索引值 array: 处理的数组
callback
计算值 当前值 当前索引 处理的数组 返回值 第一次调用 0
1
1
[0, 1, 2, 3, 4]
1
第二次调用 1
2
2
[0, 1, 2, 3, 4]
3
第三次调用 3
3
3
[0, 1, 2, 3, 4]
6
第四次调用 6
4
4
[0, 1, 2, 3, 4]
10
9.2 Boolean对象
var b = new Boolean(false);
console.log(typeof b); //object
console.log(b);//Boolean {[[PrimitiveValue]]: false}
//面试题
var b = new Boolean(false);
if(b){
alert(1);
} else{
alert(2);
}
//结果为1,因为b是一个对象,不是一个假的布尔值,虽然定义了布尔值,但实际还是一个对象,只有布尔值的那七个值为假,其余都为真,所以b为真,执行if语句
9.3 Date对象
- var d = new Date():获取当前的日期对象
new Date() //如果Date()里面不写值,默认为计算机系统的当前时间
new Date(时间戳)
new Date('2016/8/19 5:28:30'):注意这种格式的兼容性 2016-8-19谷歌火狐支持,但是IE不支持 所以尽量使用2016/4/2这种形式,IE也支持
new Date(2016,7,19,5,28,19,178)
var d2 = new Date("2018/15/5 12:00:00");// 定义了无效的月份,JS不会报错,但是执行Invalid Date 无效的日期
console.log(d2); //Invalid Date
d.getFullYear():年
d.getMonth():月(0-11)
虽然获取月份和设置月份是按照索引值0-11,但是如果直接在new Date("2018-12-12")不用按照索引值,直接写1-12个月,如果写0月 反而会显示Invalid Date 无效的日期
d.getDate():日(1-31)
d.getDay();星期几 (0-6)周日为0,周一:1,周六:6 ***只能获取,不能设置
d.getHours():小时(0-23)
d.getMinutes():分钟(0-59)
d.getSeconds():秒数(0-59)
d.getMilliseconds():毫秒
d.getTime():时间戳获取从1970-1-1到计算机的当前时间的毫秒数
var 0date = new Date();
console.log(date);
//给定时间戳对应的时间
var d1 = new Date(10065464065440);
console.log(d1);
console.log(d1.getFullYear()); //2288
- d.toUTCString(); //Thu, 04 Jan 2018 08:48:45 GMT 当前系统时间
- d.toLocaleString();//2018/1/4 下午4:49:20 当前计算机所在的时间,每个浏览区的显示不一样
*****注意:除getDay()获取星期外,每个属性都可以set设置
setFullYear()
setMonth()....
9.4 Math对象
属性
- PI:圆周率
方法
Math.abs():绝对值
Math.ceil():进一取整
Math.floor():舍去取整,向下取整
Math.round():四舍五入取整
Math.max():获取最大值
Math.min():获取最小值
如果需要对数组,获取最大最小值的话 var arr = [1,2,4,5]; console.log(Math.max.apply(null,arr)); //因为apply的形式 apply(null,[1,3]);所以里面可以把数组换为变量
Math.random():获取随机数
function rand(m,n){
return Math.floor(Math.random()*(n-m+1)+m);
}
// 随机颜色
box.style.background = "rgb(" + rand(0, 255) + "," + rand(0, 255) + "," + rand(0, 255) + ")";
9.5 Number对象
MAX_VALUE:最大的数
MIN_VALUE:最小的数
num.toFixed(length):保留指定的小数位 ,保留完小数执行出来的结果为字符串,不是数值型
(0.1 + 0.2).toFixed(2); // 0.30 // 价格与数量相乘很容易得到不精确的结果,保留两位小数点 3.99 * 123 = 490.77000000000004; (3.99 * 123).toFixed(2) = 490.77
9.6 String对象
str.length:字符串的长度(*)
var str = 'hello world'; console.log(str.length); // 11
str.trim():删除字符串两边的空格(***)
var str = ' zhangsan '; console.log(str); // zhangsan
str.concat(str1,str2,...):合并字符串
var str = 'hello'; var res = str.concat(' world'); console.log(res); // hello world
str.split(str,[length]):将字符串以指定字符切割为数组(***)
var str = 'Amy#John#Jeff'; var arr = str.split('#'); console.log(arr); // ['Amy', 'John', 'Jeff']
str.search(str|reg):在字符串中搜索指定字符,返回对应的位置,不存在返回-1(*)
var str = 'this is a lucky dog'; // 在str查找is字符 console.log(str.search('is')); // 2 // 在str中根据正则查找匹配内容 console.log(str.search(/is/)); // 2
str.match(str|reg):在字符串中匹配指定字符,存在返回数组,不存在返回null
var str = 'this is a lucky dog'; console.log(str.match('is')); // ["is", index: 2, input: "this is a lucky dog"] console.log(str.match(/is/)); // ["is", index: 2, input: "this is a lucky dog"]
str.replace(str1|reg,str2):用str2替换str1的值
var str = 'this is a lucky dog'; console.log(str.replace('is', 'are')); // thare is a lucky dog console.log(str.replace(/is/g, 'are')); // thare are a lucky dog
str.slice(start,[end]):获取字符串中指定的片段(不包含结束位置)(***)可以理解为start开始,取end-start的值的个数
var str = 'abcdefg'; // 获取str的从索引1开始到结束位置的字符 console.log(str.slice(1)); // bcdefg // 获取str的从索引1到索引4(不包含)位置的字符 console.log(str.slice(1,4)); // bcd // 获取str的从索引-4到索引-1(不包含)位置的字符 console.log(str.slice(-4,-1)); // def 上面的-4就是获取str.length + (-4) = 3, 7+(-1)=6,所以是str.slice(3,6)
str.substr(start,length):获取字符串start开始,length个字符
var str = 'abcdefg'; console.log(str.substr(2)); // cdefg console.log(str.substr(2,4)); // cdef 注意: 1. start为负值在部分浏览器支持,所以不推荐使用
str.substring(start,end):获取从start位置开始到end位置(不包含)的字符
var str = 'abcdefg'; console.log(str.substring(2)); // cdefg console.log(str.substring(2,4)); // cd 注意: 1. 如果start > end,则交换位置 2. start,end超过str.length,则为str.length 3. start == end,则返回'' 4. 不支持负值,slice的功能比substring()强大
str.indexOf(str):获取字符串中指定字符的位置,不存在返回-1(***)
var str = 'this is a lucky dog'; // 在str查找is字符 console.log(str.indexOf('is')); // 2
str.lastIndexOf(str):获取字符串中指定字符最后出现的位置,不存在返回-1
var str = 'this is a lucky dog'; // 在str查找is字符 console.log(str.lastIndexOf('is')); // 5
str.toUpperCase():转换字符串中的英文单词字母为大写字母
var str = 'This is a beautiful girl'; console.log(str.toUpperCase()); // THIS IS A BEAUTIFUL GIRL
str.toLowerCase():转换字符串中的英文单词字母为小写字母
var str = 'This is a beautiful girl'; console.log(str.toLowerCase()); // this is a beautiful girl
str.charAt(num):获取指定位置的字符
var str = 'hello world'; console.log(str.charAt(6)); // w
str.charCodeAt(num):指定位置的字母对应的Unicode编码
var str = 'hello world'; console.log(str.charCodeAt(6)); // 119 w字母对应的Unicode值为119(开头的 128 个 Unicode 编码单元和 ASCII 字符编码一样) // 简体中文 console.log('我是中国人'.charCodeAt(0)); // 25105 console.log('我是中国人'.charCodeAt(1)); // 26159 console.log('我是中国人'.charCodeAt(2)); // 20013 console.log('我是中国人'.charCodeAt(3)); // 22269 console.log('我是中国人'.charCodeAt(4)); // 20154 // 繁体中文 console.log('我是中國人'.charCodeAt(3)); // 22283 console.log('繁體'.charCodeAt(0)); // 32321 console.log('繁體'.charCodeAt(1)); // 39636
String.fromCharCode():将Unicode编码转为字符
console.log(String.fromCharCode(119)); // 2 console.log(String.fromCharCode(20014)); // 丮 console.log(String.fromCharCode(30014)); // 甾
9.7 RegExp对象
1. 定义
var reg = /表达式/修正符
var reg = new RegExp(表达式,修正符)
var reg = new RegExp('[0-9]{4,8}', 'gi');
var reg = new RegExp('/\w/','gi')
var reg = RegExp(表达式,修正符)
注意:
var str = "user";
var reg = /str/; // 此时的str不是变量,这个解析不了str字符串,只能验证有没有str这个三个字母
var reg = new RegExp(str) //这个可以解析str字符串
比如:
/ab+c/i;
可写成
new RegExp('ab+c', 'i');
new RegExp(/ab+c/, 'i');
RegExp('ab+c', 'i');
RegExp(/ab+c/, 'i');
2. 字符含义
. | 匹配任意单个字符,除行结束符(\n,\r,\u2028,\u2029) |
---|---|
\d | 匹配任意单个阿拉伯数字,等价于 [0-9] |
\D | 匹配任意单个非阿拉伯字符,等价于 [^0-9] |
\w | 匹配任意单个字母,数字,下划线,等价于 [A-Za-z0-9_] |
\W | 匹配除字母数字下划线的任意单个字符,等价于[^a-Za-z0-9_] |
\s | 匹配一个空白符,包括空格、制表符、换页符、换行符和其他 Unicode 空格 等价于[\f\n\r\t\v] |
\S | 匹配一个非空白符。等价于[^\f\n\r\t\v] 例如,/\S\w*/ 匹配 "foo bar" 中的 'foo'。 |
[xyz] | 匹配xyz中任意单个字符 |
[^xyz] | 匹配除xyz之外的任意单个字符 |
注意
/[^0-9]/非数字
/^[0-9]/以数字开头
3.量词
* | 任意数量, 看下面的任意数量介绍 |
---|---|
+ | 至少一次 |
? | 至多一次,可以是0次是1次 var str = " Yang"; var reg = "\w?" console.log(str.match(reg)); //["", index: 0, input: " Yang] 因为?匹配到最少一个,可以是0个,所以匹配的是““ |
*? | 匹配是最小可能匹配的,拒绝贪婪 |
+? | 最小可能匹配的,拒绝贪婪(可以理解为最多只能匹配一次) |
x|y | 匹配x或者y |
x(?=y) | 只有当 x 后面紧跟着 y 时,才匹配 x。 例如,/Jack(?=Sprat)/ 只有在 'Jack' 后面紧跟着 'Sprat' 时,才会匹配它。/Jack(?=Sprat/ |
x(?!y) | 只有当 x 后面不是紧跟着 y 时,才匹配 x 。例如,/\d+(?!\.)/ 只有当一个数字后面没有紧跟着一个小数点时,才会匹配该数字。/\d+(?!\.)/.exec("3.141") 匹配 141 而不是 3.141。因为匹配数字最少为1个,并且后面不能跟着.的数字,匹配不到3是因为后面有. |
x{n} | 匹配n次 |
x{n,} | 匹配至少n次 |
中文 | \u4e00-\u9fa5 |
var reg = /\w{5,}?/ 只匹配5个,拒绝贪婪
var str = " abcd";
var reg = /\w*/;
console.log(str.match(reg));//["", index: 0, input: " abcd"]
//针对*的理解:*是任意数量,第一个字符是空格,\w匹配不到空格的,所以匹配不到任何东西,就是空字符串""
3. 边界
^ | 匹配输入开始 |
---|---|
$ | 匹配输入结尾 |
\b | 匹配一个零宽度单词边界 this is a body /\bis\b/ 只能匹配到单独的is单词 |
\B | 匹配一个非单词边界 thisab /\Bis\B/ |
4. 分组
(x) | 匹配x并且捕获匹配项 例如,/(foo)/ 匹配且捕获 "foo bar." 中的 "foo"。被匹配的子字符串可以在结果数组的元素 [1], ..., [n] 中找到,或在被定义的 RegExp 对象的属性 $1, ..., $9 中找到。 |
---|---|
var str = "He is handsome boy";
var reg = /(hand)(some) boy/;
//执行处reg 的时候就是["handsome boy", "hand", "some", index: 6, input: "He is handsome boy"]
0:handsome boy
1:hand
2:some
var res = str.replace(reg,'$1==$2');
console.log(res);//He is hand==some
//然后把reg的handsome boy替换成$1对应的hand $2对应的some ==是链接,可以为任何形式,注意没有$0,$0是undefiend
6. 模式修正符
可以一起使用
var reg = /is/g
var reg = /is/gi 匹配全局并且忽略大小写
g | 全局匹配,找到所有的匹配,而不是第一个匹配后停止globla |
---|---|
i | 忽略大小写ignore |
m | 多行,将开始和结束字符(^和$)视为在多行上(\n或者\r)工作,而不是只匹配整个输入字符串的最开始和最末尾处。multiple |
7. 正则方法
reg.test(str):检验字符串是否是符合正则表达式,返回结果是true或者false
reg.exec(str):返回一个数组,存放的是匹配的结果。如果找到就显示,如果没有找到匹配,值为null
8.身份证验证正则
//身份证号验证正则
function validateIdCard(idCard){
//15位和18位身份证号码的正则表达式
var regIdCard=/^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;
//如果通过该验证,说明身份证格式正确,但准确性还需计算
if(regIdCard.test(idCard)){
if(idCard.length==18){
var idCardWi=new Array( 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ); //将前17位加权因子保存在数组里
var idCardY=new Array( 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ); //这是除以11后,可能产生的11位余数、验证码,也保存成数组
var idCardWiSum=0; //用来保存前17位各自乖以加权因子后的总和
for(var i=0;i<17;i++){
idCardWiSum+=idCard.substring(i,i+1)*idCardWi[i];
}
var idCardMod=idCardWiSum%11;//计算出校验码所在数组的位置
var idCardLast=idCard.substring(17);//得到最后一位身份证号码
//如果等于2,则说明校验码是10,身份证号码最后一位应该是X
if(idCardMod==2){
if(idCardLast=="X"||idCardLast=="x"){
return true;
}else{
return false;
}
}else{
//用计算出的验证码与最后一位身份证号码匹配,如果一致,说明通过,否则是无效的身份证号码
if(idCardLast==idCardY[idCardMod]){
return true;
}else{
return false;
}
}
}
}else{
return false;
}
}
9.利用正则替换路径问题
/*
* 需求:给图片的src地址前面增加为assets
*
* 1. 将需要匹配的内容原封不动的写入正则表达式
* 2. 将改变的内容替换为.*?
* 3. 将.*?添加(),目的是为了能够将src中的内容单独匹配一次作为匹配结果
* 4.通过replace将内容替换
* content.replace(reg,'<img src="assets/$1" alt="">')
* */
<body>
<ul>
<li class="images"><a href="1.html"><img class="a" src="images/1.jpg" alt="134534"></a></li>
<li><a href="2.html"><img src="images/2.jpg" alt="asdfas2"></a></li>
<li><a href="3.htlm"><img src="images/3.jpg" class="b" alt="3asdf"></a></li>
<li><a href="4.html"><img src="images/4.jpg" alt="45asdf4"></a></li>
<li><a href="5.html"><img src="images/5.jpg" alt="zxcv5" title="abc"></a></li>
</ul>
</body>
<script>
//1。获取ul对象
var ul = document.querySelector('ul');
// 2.获取ul的文本内容,此时就是获取出来ul里所有的内容
var content = ul.innerHTML;
// 3.写正则表达式,先把需要改变的地址原封不动拿过来
// <img src="images/3.jpg" class="b" alt="3asdf">把不一样地方用(.*?)替换,如下
// .匹配的是非空字符*匹配任意数量?拒绝贪婪,匹配任意数量的非空字符,如果不加?,就会匹配到最后
var reg = /<img(.*?)src="(.*?)"(.*?)>/g;
var result = content.replace(reg,'<img$1src="assets/$2"$3>')
console.log(result);
</script>
DOM:document object model文档对象模型
通过document获取到页面内所有的HTML标签,DOM就是描述这些标签之间的关系
document.querySelector('#box')
document.querySelector('.menu')
document.querySelector('li')
<div id="box">
<ul class="menu">
<li></li>
</ul>
</div>
1. 通过DOM获取、增加、修改、删除页面内的标签
1.1获取页面标签
// 根据css选择器获取页面的HTML标签对象(只有一个)
document.querySelector()
// 根据css选择器获取页面的HTML标签对象(数组)
document.querySelectorAll()
注意:如果用document.querySelectorALL("#id"),虽然也可以获取到元素,但是获取的只是一个数组,因为id在真个页面中是唯一的,所以获取id不要用这个
// 根据页面的id,class,标签,name获取dom对象
document.getElementById() // 唯一的一个对戏那个
document.getElementsByTagName() // 数组
document.getElementsByClassName() // 数组(新的特性,IE8不支持)
document.getElementsByName() // 数组
document.title:获取标题
document.documentElement:获取HTML标签
document.body:获取body标签
注意:js中的id可以直接输出调用,例如<div id="box"></div>
console.log(box);
这样可以输出id为box的元素,但是不建议这么使用,可以用于代码调试用
1.2获取表单元素
// 获取表单
console.log(document.forms);
console.log(document.forms[0]);
console.log(document.forms[1]);
console.log(document.forms[2]);
<form action="" name="login"></form>
// 通过name值获取表单
console.log(document.forms.login);
console.log(document.forms.reset);
console.log(document.forms.info);
<form action="" name="login">
<input type="text" name="username">
</form>
// 通过name值获取表单内部元素
console.log(document.forms.login.username);
// 获取a链接
document.links
// 获取图片
document.images
1.3创建元素
// 创建元素
var div = document.createElement('div');
div.innerHTML = '开心';
div.className = 'box';
console.log(div);
// 独特的创建方式
var img = new Image();
img.src = './images/1.jpg';
console.log(img);
1.4获取子节点
ul.children; 支持主流浏览器和IE8
ul.childNodes; 支持所有主流浏览器和IE8,但是IE8中换行也不算子节点元素
这两个都是获取子元素,区别是children 获取的是元素节点,不包括换行,childNodes,换行也算一个子节点。
如下代码
<ul>
<li>人生不只眼前的代码,还有诗和远方1</li>
<li>人生不只眼前的代码,还有诗和远方2</li>
<li class="middle">人生不只眼前的代码,还有诗和远方3</li>
<li>人生不只眼前的代码,还有诗和远方4</li>
<li>人生不只眼前的代码,还有诗和远方5</li>
</ul>
console.log(ul.children);//(5) [li, li, li.middle, li, li]
console.log(ul.childNodes);//[text, li, text, li, text, li.middle, text, li, text, li, text]
1.5获取父标签
子元素.parentNode
1.6获取兄弟节点/子节点
前面兼容主流浏览器,后面兼容IE8
上一个兄弟 middle.previousElementSibling || middle.previousSibling
下一个兄弟 middle.nextElementSibling || middle.nextSibling
第一个孩子 ul.firstElementChild || ul.firstChild
最后一个孩子 ul.lastElementChild || ul.lastChild
1.7标签属性文本
节点名称:nodeName | 节点类型:nodeType | 节点值:nodeValue | |
---|---|---|---|
标签 | 标签名对应的大写字母 | 1 | null |
属性 | 属性名 | 2 | 属性值 |
文本 | #text | 3 | 文本值 |
节点:页面中所有的标签,属性,文本
1.8获取标签的属性
<a href="https://www.baidu.com" title="全国最大的搜索引擎">百度</a>
a.attribute[0] //href="https://www.baidu.com"
a.attribute[1] // title="全国最大的搜索引擎"
a.childNodes[0] // 百度
1.9节点
box.appendChild(子节点):在末尾追加标签
box.insertBefore(新节点, 已经存在的某个子节点):在已经存在的子节点前插入一个新节点
box.replaceChild(新节点,要替换的老节点):用新节点替换老节点
box.removeChild(子节点):删除子节点
cloneNode():克隆标签属性,不克隆事件
cloneNode(true):克隆标签属性和里面内容,不克隆事件
2. 通过DOM获取和修改标签的属性
获取系统属性:
obj.href
obj.src
obj.title
obj.className
obj.value:获取表单元素的值
obj.checked:获取单选和多选是否被选中
select.value 只能获取<option selected>中设置默认选中的value值
注意:这种方法只能获取系统属性,不能获取自定义的属性,获取自定义的属性是undefined
// 修改系统属性
obj.href = '';
获取自定义和系统属性
obj.getAttribute('data-type')
obj.getAttribute('href')
添加/修改自定义属性和系统属性
obj.setAttribute('href','')
obj.setAttribute('data-type','')
// 删除自定义属性和系统属性
obj.removeAttribute('href')
3. 进行事件处理
3.1 鼠标事件(事件都是小写)
onclick:单击事件
ondblclick:双击事件
oncontextmenu:右击事件 [context上下文的意思]
onmouseover/onmouseout 鼠标移入/移出事件
onmouseenter/onmouseleave 鼠标移入/移出事件
onmouserover/onmouseout 和 onmouseenter/onmouseleave 的区别
1、onmouseover、onmouseout:鼠标经过时自身触发事件,经过其子元素时也触发该事件;(父亲有的东西,儿子也有) 2、onmouseenter、onmouseleave:鼠标经过时自身触发事件,经过其子元素时不触发该事件。(父亲的东西就是父亲的,不归儿子所有) ,*****无法取消冒泡******
onmouserover/onmouseout 会触发多次
<div class="big"> <div class="small"></div> </div> //我们的前提,只是先移入大盒子,然后移入小盒子,然后离开 <script> small.onmouseover = function(){ console.log('small over'); } small.onmouseout = function(){ console.log('small out'); } big.onmouseover = function(){ console.log('big over'); } big.onmouseout = function(){ console.log('big out'); } </script> /* big over big out small over big over small out big out big over big out */ // 此时触发了多次
onmouseenter/onmouseleave 只触发一次
//同样的HTML big.onmouseenter = function () { console.log("移入大盒子"); } big.onmouseleave = function () { console.log("移出大盒子"); } small.onmouseenter = function () { console.log("移入小盒子"); } small.onmouseleave = function () { console.log("移出小盒子"); } /* 移入大盒子 移入小盒子 移出小盒子 移出大盒子 */ //此时触发了一次
onmousedown/onmouseup
onmousemove
3.2键盘事件
1.onkeydown 键盘按下
2.onkeyup 键盘弹起
3.onkeypress 键盘按下
e.key // 获取输入的值 不支持IE8-
e.keyCode // 获取对应值的ASCII码值
onkeydown / onkeypress的区别
onkeydown和onkeyup
可以获取键盘上所有的字符 所有字母都按小写字母计算ASCII码值,也是就是A a 都按照65计算,如果是小键盘的1和大键盘的上1 ASCII码值还不一样,大键盘的1的ASCII码值49 ,而小键盘的1,则以97输出
onkeypress
只能获取数字,字母,字符只能获取空格和回车 字母区分大小写计算ASCII码值,大键盘小键盘的数字键的ASCII码值保持一致
3.3 window事件
onscroll
onload
onload:当页面加载完成的时候,执行的事件 注意: 1. HTML标签在后,script获取对象在前,获取不到对象 2. 页面图片,音视频等资源异步加载,不能直接获取图片,音视频相关数据,需要进入浏览器以后再刷新一下才能获取,onload可以解决
onscroll
onscroll document.documentElement.scrollTop || document.body.scrollTop document.documentElement.scrollTop = 200 document.body.scrollTop = 100;
4.onresize:浏览器大小改变的时候,执行的事件
1.改变大小(慢点改变,一直触发,快速改变,只触发几次) 只想改变一次 var timer; window.onresize = function () { // 当窗口每次改变尺寸的时候,先清空定时器通过延时避免onresize多次执行 clearTimeout(timer); // 开启定时器 timer = setTimeout(function () { console.log(1); }, 200); }
5.onerror 注意:触发onerror事件时候不能写onload事件
<img src="../images/11111.jpg" alt="手机">
<script>
var img = document.querySelector("img");
img.onerror = function () {
img.src = "../images/small.jpg";
}
</script>
// 如果img把图片路径引入错误的话,浏览器中会自动显示出alt属性的内容,为了增加用户体验性,我们会把出现错误的图片给替换掉,如果图片显示有误的话,就触发图片的onerror事件
3.4 表单事件
onfocus:聚焦事件
onblur:失去焦点事件
获取用户输入的值:obj.value 单选和多选按钮是否选中:obj.checked
onchange: 改变事件
inputObj.onchange selectObj.onchange
onsubmit:提交事件
提交事件针对表单form.onsubmit
onreset: 重置事件
重置事件针对表单from.onreset
onselect: 当内容被选中的时候
3.5 阻止浏览器的默认行为
默认行为:
a链接的跳转
input框的输入
提交重置按钮的
单击鼠标右键的菜单
e ?e.preventDefault() : window.event.returnValue = false; //只能阻止默认行为,如果阻止input输入,input就不能输入内容,但是通过搜狗输入中文就可以,因为阻止的是浏览器的默认行为。
直接写return false也可以阻止浏览器的默认行为,但是return false 有很大的问题,而且return false以后的代码都不执行,所以不建议用
3.5.1阻止a链接的默认行为
<a href="javascript:void(0);">百度</a>
<a href="javascript:;">百度</a>
3.6阻止冒泡
e ? e.stopPropagation() : window.event.cancelBubble = true;
3.7事件绑定 addEventListener
如果写了两次相同的事件,只会执行最后的一次,因为同名的属性会被覆盖
可以添加事件绑定,或者移除事件绑定
/*
* 添加绑定事件
* @param Object obj:绑定的事件对象
* @param String eventName:绑定的事件名称
* @param function callback:绑定事件执行的函数
* */
function addEvent(obj, eventName, callback) {
if (obj.addEventListener) {
obj.addEventListener(eventName, callback, false);
} else {
obj.attachEvent('on' + eventName, callback);
}
}
/*
* 移除绑定事件
* @param Object obj:移除绑定的事件对象
* @param String eventName:移除绑定的事件名称
* @param function callback:移除绑定事件执行的函数
* */
function removeEvent(obj, eventName, callback) {
if (obj.removeEventListener) {
obj.removeEventListener(eventName, callback, false);
} else {
obj.detachEvent('on' + eventName, callback);
}
}
onclick,onmouseover,onkeydown,onload,onblur,事件称之为DOM0级事件
addEventListener(事件名称, 回调函数,true|false):DOM2级事件
事件名称:不需要加on
回调函数:触发了该事件,则自动执行回调函数
true|false:
true:在捕获阶段执行
false:在冒泡阶段(默认)
onclick的问题,通过addEventListener来解决
问题1:同名的事件会覆盖,通过addEventListener取消
问题2:obj.onclick=null
addEventListener和removeEventListener():可以绑定指定的事件和取消指定的事件
问题3:有些事件只能通过addEventListener来增加
transitionend
animationstart
animationend
3.8事件委托
- 注意:事件委托如果需要兼容IE8,需要把IE8支持的属性写到前面,否则会报错,其他兼容IE8的都是先写主流浏览器支持的属性 再写IE8 ,事件委托相反
IE8 || 主流浏览器
window.event.srcElement||e.target
<ul class="menu">
<li>001</li>
<li>002</li>
<li>003</li>
<li>004</li>
<li>005</li>
</ul>
<script>
window.onload = function () {
var menu = document.querySelector('.menu');
var list = document.querySelectorAll('li');
var newLi = document.createElement('li');
newLi.innerHTML = "006";
menu.appendChild(newLi);
/*list.forEach(function (value,key) {
list[key].onclick = function () {
console.log(this.innerHTML);
}
})*/ // 这样无法获取到最后一个新添加的元素的innnerHTML
menu.onclick = function (e) {
// 事件委托
// IE8 || 主流浏览器
var obj = window.event.srcElement || e.target;
if(obj.nodeName == "LI"){
console.log(window.event.srcElement.innerHTML || e.target.innerHTML);
}
} //通过这种事件委托,来获取新添加的元素的innerHTML
}
</script>
3.9.DOM相关属性
鼠标事件对象
var e = ent || window.event;
浏览器的可视窗口区域
e.clientX
e.clientY
距离页面的坐标
e.pageX
e.pageY
距离鼠标点击的元素
e.offsetX
e.offsetY
获取宽高 包括width+padding+border
box.offsetWidth
box.offsetHeight
//获取宽高,包括width+padding
clientWidth
clientHeight
//获取滚动内容的宽高
scrollWidth
scrollHeight
获取HTML可视区域的宽高
document.documentElement.clientWidth
document.documentElement.clientHeight
获取HTML整体页面的宽高
document.documentElement.scrollWidth
document.documentElement.scrollHeight
//子盒子到祖辈盒子的距离,如果祖辈盒子有定位,以祖辈盒子为准,如果祖辈没有定位,则以页面为准
small.offsetLeft
small.offsetTop
// 获取滚动距离
box.scrollLeft
box.scrollTop
// 修改滚动距离
box.scrollTop = 100;
box.scrollLeft = 100
// 获取页面滚动距离
document.documentElement.scrollTop || document.body.scrollTop;
document.documentElement.scrollLeft || document.body.scrollLeft;
注意:只有scrollTop ,scrollLeft 可以赋值,其他属性只能获取
区别:
pageX pageY 是当页面有横纵滚动条是,是距离页面的,即使有的内容已经滚上(左)面,也可以测出距离页面的距离
clientX clientY 如果出现滚动条,只是测出当前可见区域的距离
1.获取鼠标点击位置距页面的左边距和上边距
e.pageX
e.pageY
2.获取鼠标点击位置距浏览器的左边距和上边距
e.clientX
e.clientY
3.获取鼠标点击位置距点击对象的左边距和上边距
e.offsetX
e.offsetY
4.获取div的宽度和高度
div.offsetWidth
div.offsetHeight
5.获取浏览器的宽度和高度
document.documentElement.clientWidth
document.documentElement.clientHeight
6.获取页面的宽度和高度
document.documentElement.scrollWidth
document.documentElement.scrollHeight
7.获取div的内容滚动的距离
div.scrollTop
div.scrollLeft
8.设置div的内容滚动的距离
div.scrollTop=100
div.scrollLeft=100
9.获取页面的滚动距离
document.documentElement.scrollTop||document.body.scrollTop
10.设置页面的滚动距离
document.documentElement.scrollTop=100
document.body.scrollTop=100
注意*有关函数的括号问题
function demo(){}
需要调用函数的时候 demo();
如果直接写demo 那只是一个函数名,不会调用demo函数的
setTimeout(demo,1000); //1s之后执行demo函数 ,此时函数后不加括号
setTimeout(demo(),1000); //立即执行demo函数,定时器不起作用,小括号有立即执行的作用
如果函数需要小括号,因为有参数,需要把函数用引号引起来
setInterval('demo(obj,event)',1000);
4.获取样式
js中只能获取到行内样式
兼容IE8
/*
* 获取样式
* @param Object obj获取样式的对象
* @param Object attr:获取的css样式名称
* return 获取样式的值
* */
function getStyle(obj, attr) {
return document.defaultView ? document.defaultView.getComputedStyle(obj, null)[attr] : obj.currentStyle[attr];
}
// 调用,需要给attr加引号
console.log(getStyle(box, 'backgroundColor'));
主流浏览器获取的颜色都转换成rgb值,IE8获取的是style样式里面写的属性值,写什么就是什么
BOM - window
window属性
全局变量 window. 可以省略
var str = '坚持下来,你会收获不一样的人生'; console.log(str); console.log(window.str); function demo(){ console.log('都已成年'); } demo(); window.demo();
screen:屏幕
screen.width:屏幕宽度 也就是分辨率的宽度
screen.height:屏幕的高度 也就是分辨率的高度
screen.availWidth:屏幕可用宽度 不包括底部菜单栏或侧面菜单栏
screen.availHeight:屏幕可用高度 不包括底部菜单栏或侧面菜单栏navigator: 获取浏览器相关信息
navigator.userAgent:获取代理信息Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
history:浏览器的历史对象
history.go(1|-1|0):前进(下一个页面)/后退(上一个页面)/刷新
history.length:历史记录location: 浏览器地址栏的信息
location
Location {href: "http://localhost:63342/work/JS/%E9%B9%BF%E7%91%B60…/7-1location.html?_ijt=o66094ti4bhjivqbd4qebug7op", ancestorOrigins: DOMStringList, origin: "http://localhost:63342", replace: ƒ, assign: ƒ, …}
location.href:获取当前页面的URL地址
http://localhost:63342/work/JS/%E9%B9%BF%E7%91%B601-17/7-1location.html?_ijt=o66094ti4bhjivqbd4qebug7op
location.hash:获取锚点
#锚点名
location.origin:获取主机名+端口号
http://localhost:63342
location.reload():刷新
location='url地址'; 页面跳转到指定页面
window方法
open(窗口地址,'','width=400,height=400,top=500,left=500')
window.open(URL,name,features,replace)
参数 描述 URL 一个可选的字符串,声明了要在新窗口中显示的文档的 URL。如果省略了这个参数,或者它的值是空字符串,那么新窗口就不会显示任何文档。 name 一个可选的字符串,该字符串是一个由逗号分隔的特征列表,其中包括数字、字母和下划线,该字符声明了新窗口的名称。这个名称可以用作标记 和 的属性 target 的值。如果该参数指定了一个已经存在的窗口,那么 open() 方法就不再创建一个新窗口,而只是返回对指定窗口的引用。在这种情况下,features 将被忽略。 features 一个可选的字符串,声明了新窗口要显示的标准浏览器的特征。如果省略该参数,新窗口将具有所有标准特征。在窗口特征这个表格中,我们对该字符串的格式进行了详细的说明。 replace 一个可选的布尔值。规定了装载到窗口的 URL 是在窗口的浏览历史中创建一个新条目,还是替换浏览历史中的当前条目。支持下面的值:true - URL 替换浏览历史中的当前条目。false - URL 在浏览历史中创建新的条目。 close() 关闭 window.close() 关闭当前窗口 newName.close() 关闭newName窗口
moveTo(x,y):移动到指定位置
moveBy(x,y):每次指定多少距离
resizeBy(x,y):每次改变指定大小
resizeTo(width,height):每次改变到指定的宽高
alert()/confirm()/prompt() 弹出框/确认框/问答框
- window.alert() / window.confirm()/window.prompt()
parseInt()/parseFloat()/Number()
setInterval()/setTimeout()/clearInterval()/clearTimeout()
JSON
格式:var json = {"username":"zhangsan","age":"20","sex":"男"}; * JSON对象:只是保存数据的 * 跟js对象的区别: * 1. json对象 属性名必须加双引号 * 1. json对象只负责保存数据,没有方法
JSON转string
JSON.stringify(对象)
- string 转 JSON
JSON.parse(字符串)
jsonp
正常的ajax需要遵循同源策略,也就是调用后台数据的时候,需要写相对路径,如果写绝对路径,则访问不好使,例如
xhr.open('GET','http://localhost/work/Ajax/luyao02-02/1.php',true);
如果这么写,那么只能用localhost访问,不能用127.0.0.1访问,如果需要解决跨域问题,需要jsonp
<!--script请求不需要遵循同源策略-->
<script src="http://localhost/work/Ajax/luyao02-02/2.js"></script>
- 创建一个
var scriptObj = document.createElement('script');
scriptObj.src = 'http://localhost/work/Ajax/luyao02-02/2.js';
document.documentElement.appendChild(scriptObj);
- ajax 跨域请求
$.ajax({
type:'GET',//这里无论写不写,都是执行GET,即使写post执行是也是get,因为post不能执行跨域请求
async: true, //jsonp跨域请求只能是异步请求 可不写
dataType:'jsonp',
jsonp:'callback',//回调函数的名称
url:'http://127.0.0.1/work/Ajax/luyao02-02/6.php',
success:function (data) {
$('.box').html(data.name);
alert(data.name);
}
});
- url地址解析字符串问题
function request(cb) {
var script_obj = document.createElement('script');
script_obj.src = 'http://127.0.0.1/work/Ajax/luyao02-02/5.php?callback='+cb;
document.documentElement.appendChild(script_obj);
}
function showTxt(str){
box.innerHTML = str;
}
btn[0].onclick = function(){
// 'http://127.0.0.1/work/Ajax/luyao02-02/5.php?callback='+'需要拼接的字符串'
// 类似于callback = +'字符串';
request('showTxt'); // 所以这里这个函数必须用‘’
}
<?php
echo $_GET['callback'].'("调整好自己")';
跨域经典的错误标志 No 'Access-Control-Allow-Origin'
闭包
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
<button>6</button>
<script>
var btn = document.querySelectorAll('button');
// js中的事件是先绑定,后触发,此处的结构,相当于立即执行函数的返回值赋值给onclick
for (var i = 0; i < btn.length; i++) {
btn[i].onclick = (function (i) {
return function () {
console.log(i);
}
})(i);
}
</script>