JavaScript
- JavaScript兼容于ECMA标准,因此也称为ECMAScript。
调试命令
alert('hello world');
console.log('文字信息');
console.warn('警告信息');
console.error('错误信息');
document.write('hello world');
* js中严格区分大小写
变量的命名规则
1.变量中可以含有a-Z 0-9 _ $ , 但是不能以数字开头
2.不能使用JS中的关键字和保留字
3.尽量遵从驼峰命名规则
JavaScript的数据类型 (六种
基本数据类型
String
Number
Boolean
Null
Undefined
复杂数据类型
/ Date
Object - Array
\ function ...
NaN:表示不是数字值的特殊值,可以理解为Number的一种特殊类型,只有当在js运算中发生数据类型转换时提示,isNaN()方法是特有的对数据进行判断的 ,如果是数字返回false,不是数字返回true。
null空对象类型, 表示'没有对象',即该处不应该有值
undefined表示缺少值,就是此处应该有一个值,但是没有定义,例如 var =a;
数据类型转换
将其他的数据类型转换为string
方法1:
调用被转换数据类型的toString()方法 也就是 .toString()
该方法不会影响原变量,它会将转换的结果返回f
注意:null和undefined没有toString()方法
方法2:
调用String()函数,并将被转换的数据作为参数传递给函数
将其他的数据类型转换为number
方法1:
调用Number()函数
被转换的内容可以转换成数字,那么就直接返回这个内容对应的数字
如果被转换内容中有非数字, 那么返回NaN
如果内容为空或者null或者false,则转换成0
undefined转换成NaN
方法2:
parseInt( )将内容转成Number
如果被转换内容中出现小数,那么转换的时候会转换去掉小数
如果第一个字符是数字,则继续解析,直至字符串解析完毕或者遇到一个非数字字符为止
方法3:
parseFloat( )将内容转成Number
与parseInt一样,唯一的区别就是可以保留小数
注意:如果对非string使用parseInt( )和parseFloat( ),会先将其转换为string再操作
将其他的数据类型转换为boolean
方法1:
调用Boolean()函数
除了0、NaN其他都是true
除了空串其他都是true
null和undefined都是false
运算符
+(加号)
对非Number类型的值进行运算时,会将这些值转换为Number然后再运算
任何值和NaN运算都得NaN
任何值和字符串做加法运算,都会先转换为字符串,然后再和字符串做拼串(任何数据类型 + 字符串都得字符)
数字和undefined运算得NaN
隐式转换
任意的数据类型加上空串( 任意数据类型 + ''),即可将其转换为String类型
a.如果加号两边都是字符串,那么加号的作用是连接
b.如果加号两边都是数值,那么加号的作用是相加
c.如果加号一边是字符串,那么加号的作用是连接
-(减号) *(乘) /(除)
任何值做减/乘/除运算时,都会自动转换为Number
可以通过为一个值-0 *1 /1 来将其转换为Number
例:
var str = '123';
var num = str - 0;
// var num = str * 1;
// var num = str / 1;
console.log(num ,typeof num);
%(取余&取模)
两数相除取余数
()括号
改变运算顺序的先后顺序
一元运算符
+ 正号
不会对数字产生影响
隐式类型转换:可以对其他数据类型使用正号(+),来将其转换为Number
- 负号
可以对数字进行符号的取反
自增和自减
自增
- 通过自增可以让变量在自身的基础上增加1
- 对变量自增以后,原变量的值会立即自增1
a++ 的值等于原变量的值(自增前的值)
++a 的值等于新值(自增后的值)
自减
- 通过自减可以让变量在自身的基础上减1
- 无论是a--还是--a,都会立即使原变量的值自减1
a-- 的值等于原变量的值(自减前的值)
--a 的值等于新值(自减后的值)
逻辑运算符 &&(与) ||(或) !(非)
&&(与)
有假则为假,全真才为真
||(或)
有真则为真,全假才为假
!(非)
可以用来对一个值进行非运算(true变false,false变true)
如果对非布尔值进行运算,先将非布尔值变成布尔值,再运算
可以为一个任意数据类型取反两次,将其转换为布尔值
* undefined , null , NaN , " " , 0 , false 以上几个值转换为布尔值都是false
&& || 非布尔值的情况下
对于非布尔值进行与或运算时,会先将其转换为布尔值,然后再运算,并且返回原值
&&(与)运算:
如果两个值都为true,则返回后边的
如果两个值中有false,则返回靠前的false
如果第一个值为true,则必然返回第二个值
如果第一个值为false,则直接返回第一个值
||(或)运算:
如果第一个值为true,则必然返回第一个值
如果第一个值为false,则直接返回第二个值
赋值运算符
=
可以将符号右边的值赋给左边的变量
+=
a += 5 就是 a = a + 5; (a等于a加上5再赋给自身)
关系运算符 >(大于) <(小于)
通过关系运算符可以比较两个值之间的大小关系,如果关系成立则返回true,不成立则返回false
非数值的情况
对于非数值进比较,先将其转换为数值再进行比较
任何值和NaN做任何比较都是false
如果符号两侧的值都是字符串,不会将其转换成数字,而会分别比较字符串的Unicode编码
输出Unicode编码 console.log('\u1c00')
相等运算符
== 用两个等于号来做相等运算
== (两个等于号比对值)两边值类型不同的时候,要先进行类型转换,再比较。
* 由于undefined衍生自null,所以undefined == null 的时候会返回true
* NaN不和任何值相等,包括他本身
* 通过isNaN()函数来判断一个值是否是NaN
*
===(全等) 判断两个值是否全等,不会做类型转换,如果两个值类型不能,直接返回false
三元运算符
条件表达式?语句1:语句2;
执行流程:
条件运算符在执行时,首先对条件表达式进行求值,
如果该值为true,则执行语句1,并返回执行结果
如果该值为false,则执行语句2,并返回执行结果
例:
var a = 10;
var b = 20;
a > b ? console.log('a大'):console.log('b大')
for循环
for(var i = 0;i < 10; i++){
console.log(i)
}
for(①初始化表达式;②条件表达式;④更新表达式){
③执行语句...
}
流程:
①执行初始化表达式,初始化变量(只会执行一次)
②执行条件表达式,判断是否执行循环
如果为true,则执行循环③
如果为false,终止循环
④执行更新表达式,更新表达式执行完毕继续重复②
练习:打印1至100的和
var sum = 0;
for(var i =0;i <= 100;i++){
// console.log(i);
sum = sum+i;
}
console.log(sum);
练习:打印1至100以内奇数的和
var sum = 0;
for(var i =0;i <= 100;i++){
if(i % 2 != 0){
sum = sum + i;
}
}
console.log(sum);
需求,在页面中输出如下的图形
外循环控制高度
for (var i =0; i <5; i++) {
/* 内循环控制宽度 */
正三角
for(var j = 0;j < i+1; j++){
document.write('* ')
}
倒三角
for(var j =0;j <5-i; j++){
document.write('* ')
}
document.write('<br>')
}
打印99乘法表
for (var i =1; i <=9; i++) {
for(var j =1;j <= i; j++){
document.write("<span>"+j +'*' +i +'=' + i*j +"</span>")
}
document.write('<br>')
}
switch case 语句
var n = window.prompt('input');
switch (n) {
case '春天':
console.log('春意盎然');
break;
case '夏天':
console.log('夏日炎炎');
break;
case '秋天':
console.log('收获的季节');
break;
case '冬天':
console.log('冻死你个龟孙');
break;
}
break和continue
*不能在if语句中使用break和continue
break关键字可以用来退出switch或循环语句
break关键字会立即终止离他最近的循环语句
continue关键字可以用来跳出当次循环(终止本次循环,进行下次循环)
continue关键字会立即终止离他最近的循环语句
*使用return会结束整个函数
对象
- 只要不是string、number、boolean、null、undefined,其他都是对象
基本数据类型都是单一的值"hello" 123 true, 值和值之间没有任何的联系
对象的分类
1.内建对象
-由ES标准中定义的对象,在任何的ES的实现中都可以使用
比如:Math String Number Boolean Function Object ...
2.宿主对象
-由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
比如:BOM DOM
3.自定义对象
-由开发人员自己创建的对象
创建对象
var obj = {};
* 在对象中保存的值称为属性
* 向对象添加属性
* 语法:
* 对象 . 属性名 = 属性值;*/
向obj中添加一个name gender age
obj.name ='八戒';
obj.gender ='男';
obj.age =18;
* 读取对象中的属性
* 语法:
* 对象 . 属性名
*
* 如果读取对象中没有的属性,不会报错,而是会返回undefined
console.log(obj.name);
console.log(obj.gender);
console.log(obj.age);
* 修改对象的属性
* 语法:
* 对象 . 属性名 = 新值*/
obj.name ='tom';
console.log(obj.name);
* 删除对象的属性
* 语法:
* delete 对象 . 属性名*/
delete obj.age;
console.log(obj , obj.age);
属性名和属性值
* 属性名:
* - 对象的属性名不强制要求遵守标识符的规范,但尽量按照标识符的规范
*
* 属性值
* - JS对象的属性值,可以是任意的数据类型
如果需要使用特殊的属性名,不能采用 . 的方式来操作
需要使用另一种方式
语法:
对象['属性名] = 属性值;
obj['123'] = 789;
console.log(obj['123']);
读取的时候也要使用这种方式
in运算符
* - 通过in运算符可以检查一个对象中是否含有指定的属性
* 如果有就返回true 没有就返回false
* 语法:
* "属性名" in 对象*/
console.log('name' in obj);
基本数据类型和引用数据类型
基本数据类型
JS中的变量都是保存到栈内存中的
基本数据类型的值,直接在栈内存中存储
值与值之间是独立存在的,修改一个变量不会影响其他的变量
例: var a = 10;
var b = a;
a++;
console.log(b);
* 因为a的值和b的值是独立存在的,所以a++之后并不会影响b的值
引用数据类型
对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是 对象的内存地址(即对象的引用),如果两个变量保存的是同一个对象的引用,当其中一个变量修改属性时,另一个也会收到影响(因为不是独立的)
例: var obj = new Object();
obj.name = '孙悟空';
var obj2 = obj;
console.log(obj2.name); //孙悟空
obj.name = '猪八戒';
console.log(obj2.name); //猪八戒
* 当我们比较两个基本数据类型时,就是比较值
* 当比较两个引用数据类型时,比较的是对象的内存地址
* 如果两个对象是一模一样的,但是地址不同,就会返回false
* 栈区(速度快 性能高 存储量比较小)
* 堆区(空间大 访问速度慢 性能比较低)
函数
- 函数中可以封装一些功能(代码),在需要的时候可以执行这些功能(代码)
- 函数中可以保存一些代码,在需要的时候调用
函数声明
格式:
function 函数名 ([形参1,形参2...形参N]){
语句...
}
function test(num1,num2) {
console.log(num1 + num2);
}
test(1,3);
* 当实参个数多与形参时,多出来的实参不被使用
* 当实参的数量少于形参时,则没有对应实参的形参,形参将是undefined
** 函数的执行结果可以通过return返回出来,但是需要有个变量来接收
注意:在函数中,return后的语句都不会执行
如果return语句后面不跟任何值,就相当于返回一个undefined
函数表达式
var fun3 =function () {
console.log(3);
};
fun3();
fun3();
- 调用函数
- 相当于使用的是函数的返回值
fun3
- 函数对象
- 相当于直接使用函数对象
立即执行函数
函数定义完立即被调用,这种函数就是立即执行函数
立即执行函数只会执行一次
(function () {
console.log(1);
})();
枚举对象中的属性
语法: for(var 变量 in 对象){
}
for...in语句 对象中有几个属性,循环体就会执行几次
每次执行时,会将对象中的一个属性的名字赋值给变量
var obj = {
name:'wlf',
age:18,
add:'pek',
gender:'男'
};
for(var n in obj){
console.log(obj[n]);
}
作用域
- 指一个变量的作用范围
js中有两种作用域
1.全局作用域
- 直接写在script标签中的都是全局作用域
- 全局作用域在页面打开时创建,在页面关闭时销毁
- 在全局作用域中,有一个全局对象window,可以直接使用
- 在全局作用域中:
创建的变量都会作为window对象的属性保存
创建的函数都会作为window对象的方法保存
- 全局作用域中的变量都是全局变量,在页面的任意的部分都可以访问的到
*变量的声明提前
- 使用var关键字声明的变量,会在所有的代码执行之前被声明(但不会赋值)
*函数的声明提前
- 使用函数声明形式创建的函数function函数,它会在所有的代码执行之前就被创建
- 使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用
2.函数作用域
- 调用函数时创建函数作用域,函数执行完函数作用域销毁
- 每调用一函数就会创建一个新的函数作用域,他们之间是相互独立的
- 函数作用域中可以访问到全局作用域的变量,而全局作用域中无法访问函数作用域的变量
*在函数中不适用var声明的变量都会成为全局变量
* 定义形参就相当于在函数作用域中声明了变量
数组对象方法
push() 向数组末位添加新元素,该方法会将数组新的长度作为返回值返回
unshift() 向数组首位添加新元素,该方法会将数组新的长度作为返回值返回
pop() 该方法可以删除数组的最后一个元素,并将被删除的元素作为返回值返回
shift() 该方法可以删除数组的第一个元素,并将被删除的元素作为返回值返回
reverse() 颠倒(翻转)数组中元素的顺序
join() 把所有元素放入字符串,并用指定分隔符进行分隔,如果不指定,默认是逗号(,)
并且会把object的类型转换成string
concat() 连接两个或更多的数组,并返回结果
slice() 选取数组的的一部分,并返回一个新数组
参数:1从哪个角标开始截取,2到哪个角标结束(不包含这个角标的元素)
返回值:开始截取的元素和结束截取的元素的前一个元素
注意点:第二个参数可选,如果不写,默认截取到元素最后
splice() 从数组中删除元素,并返回被删除的结果
参数:1开始删除元素的角标,2要删除几个元素,3把元素删除之后要替换的元素
sort() 对数组的元素进行排序
forEach()
- 需要一个函数作为参数
- 用forEach遍历时,数组中有几个元素,函数就会执行几次。每次执行时,浏览器会将遍历到的元素以实参的形式传递进来,我们可以来定义形参来读取这些内容
函数的形参1:当前遍历的元素
函数的形参2:当前遍历元素的索引(可选)
函数的形参3:当前遍历的数组(可选)
数组去重
var arr = [1,2,2,2,45,45,7,6,99,99,99,2]
for(var i = 0;i<arr.length;i++){
for(var j = i+1;j<arr.length;j++){
if(arr[i] == arr[j]){
arr.splice(j,1) j--;
}
}
}
console.log(arr);
可以去掉字符串 , 数组
// var arr = ['你好','hello','你好','我','他','的','的','的的'];
// var arr = ['1','2','1','3','4','1','2','4'];
var arr = [1,1,2,2,3,3,4,123,345,567,7,4,23,5,657,567];
//定义一个新的数组
var s = [];
//遍历数组
for(var i = 0;i<arr.length;i++){
//判断在s数组中是否存在,不存在则push到s数组中
if(s.indexOf(arr[i])== -1){
s.push(arr[i]);
}
}
console.log(s);
创建日期对象
var date=new Date();
date.getFullYear();用data调用获取时间的方法
1.getFullYear() 从Date 对象以四位数返回年份
2.getMonth() 从Date 对象对象返回月份,取值范围(0~11)
3.getDate() 从Date 对象返回一个月中的某一天,取值范围(1~31)
4.getDay() 从Date 对象返回一周中的某一天,取值范围(0~6)
// 星期几 0.周末 1.周一 2.周二
5.getHours() 返回Date 对象的小时,取值范围是(0~23)
6.getMinutes() 返回Date 对象的分钟,取值范围是(0~59)
7.getSeconds() 返回Date 对象的秒数,取值范围是(0~59)
8.getTime() 返回从1970年1月1日至今的毫秒数 称为:时间戳
9.valueOf() 返回Date 对象的原始值 时间戳
string对象方法
在底层,字符串是以字符串数组的形式保存的
length 获取字符串的长度
charAt() 返回对应的索引的元素
charCodeAt() 返回指定字符串的Unicode编码
concat() 用来链接两个或多个字符串
indexOf() 找到指定内容的索引(默认从前往后查找。如果没有找到指定内容,则返回-1)
slice() 选取数组的的一部分,并返回一个新数组
参数:1从哪个角标开始截取,2到哪个角标结束(不包含这个角标的元素)
返回值:开始截取的元素和结束截取的元素的前一个元素
注意点:第二个参数可选,如果不写,默认截取到元素最后
substring() 同slice()
不同的是参数不可以传递负值
split() 把字符串分割成字符串数组
参数是字符串里面的任意一个元素,传入参数之后,把元素之前的部分和之后的部分分成两个字符串,形成一个字符串数组
如果参数传一个空串,会将每个字符都拆分为数组中的一个元素
toLocaleUpperCase() 将字符串转化为大写并返回
正则表达式
语法:
var 变量 = new RegExp('正则表达式','匹配模式');
常用字面量来创建
var 变量 = /正则表达式/匹配模式;
参数2:
i : 忽略大小写
g : 全局匹配模式
手机号:<input type="text" id="pho" onblur="isPhone(this.value);"/>
邮箱: <input type="text" onblur="isEmail(this.value);"/>
//验证手机号是否合法
function isPhone(phone){
var pho = document.getElementById('pho');
var reg =/^[1][3,5,8][0-9]{9}$/;
var falg = phone.search(reg);
if(phone ==''){
console.log('手机号不能空');
pho.style.border='1px solid red'
}else {
// console.log('不是空的,进入');
if (falg == -1){
console.log("手机号不正确");
pho.style.border='1px solid yellow'
this.focus();
}else {
console.log('登录手机号成功');
pho.style.border='1px solid green'
}
}
}
//验证邮箱是否合法
/* ==================================================================
任意字母下划线 .任意字母下划线 @ 任意字母数字 .任意字母(2-5位) .任意字母(2-5位)
\w{3,} (\.\w+)* @ [A-z0-9]+ (\.[A-z]{2,5}){1,2}
===================================================================*/
function isEmail(email){
var reg =/^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
var falg = email.search(reg);
if(email ==''){
console.log('邮箱不能为空')
}else {
if (falg == -1){
console.log("邮箱不正确");
this.focus();
}else {
console.log('登录邮箱成功');
}
}
}
//去掉首尾空格
var str =' xx xxx x ';
var str = str.replace(/^\s*|\s*$/g,'');
console.log('|'+str+'|');
DOM
- document object model 文档对象模型
- document(文档)
文档表示的就是整个html网页文档
- object(对象)
对象表示将网页中的每一个部分都转换为一个对象
- model(模型)
使用模型来表示对象之间的关系,这样方便我们获取对象
[dom操作方法]
getElementById()
通过id属性获取一个元素节点对象
getElementsByClassName()
通过类名获取一组元素节点对象
getElementsByTagName()
参数:是标签的名称
通过标签名获取一组元素节点对象
childNodes
表示当前节点的所有子节点
注意:根据DOM标准,标签间的换行也会当成文本节点
而在ie8以下 则不会
children
获取当前元素的所有子元素(标签)
firstChild
表示当前节点的第一个子节点(包括空白文本节点)
lastChild
表示当前节点的最后一个子节点
parentNode
获取当前节点的父节点
querySelector() / querySelectorAll()
可以根据css选择器查询元素节点
获取兄弟标签
nextElementSibling =>ie9以下不兼容
nextSibling =>ie9以下兼容
兼容写法nextElementSibling || nextSibling;
appendChild()
向一个父节点中添加一个新的子节点。永远添加到后面
语法:父元素.appendChild(子节点)
createElement()
创建元素节点(创建标签)
参数:要创建的标签名称
createTextNode()
创建文本节点
removeChild()
删除指定标签
replaceChild()
替换子节点
参数:1新的节点,2被替换的节点
cloneNode()
克隆/复制节点
参数:为true的时候会克隆该元素和里面的子元素,为false的时候只会克隆该元素
setAttribute()
可以给标签设置属性
参数1:属性的名称,参数2:属性的值
JS获取元素的样式
1.currentStyle
只有IE支持,所以不推荐使用
2.getComputedStyle()
这个方法是window的方法,可以直接使用
需要两个参数
1.要获取样式的元素
2.可以传递一个为元素,一般都传null
返回值:一个对象
该方法不支持IE8及以下
写一个兼容的方法
//obj 要获取样式的元素
//name 要获取的样式名
function getStyle(obj,name){
if(window.getComputedStyle){
return getComputedStyle(obj,null)[name];
}else {
return obj.currentStyle[name];
}
}
注意点:通过currentStyle和getComputedStyle()获取到的样式只能读取,不能修改。
getBoundingClientRect()
-获取元素几乎所有信息
clientWidth
clientHeight
-可以获取元素的宽度和高度
-获取的值包括 content + padding
offsetWidth
offsetHeight
-获取元素的宽度和高度
-获取的值包括 content + padding + border
offsetLeft
offsetTop
-距离第一个有定位的祖先元素左边和上边的距离
注意:祖先元素必须要有定位,如果没有,则最终以body为准.
offsetParent
-找到最近的带有定位的祖先元素,如果祖先元素没有定位,默认是body
scrollWidth
scrollHeight
-可以获取元素整个滚动区域的宽度和高度
scrollTop
scrollLeft
-获取的是滚动条已经滚动过的距离
scrollHeight - scrollTop == clientHeight ,说明滚动条已经到底。[下图实例]
event事件对象
事件句柄:
onmousemove
- 鼠标在元素中移动时被触发
onmousedown
- 鼠标按下事件
onmousemove
- 鼠标拖拽移动事件
onmouseup
- 鼠标抬起事件
onmousewheel
- 鼠标滚轮滚动事件,会在滚轮滚动时触发(火狐不支持该属性)
用event.wheelDelta来获取滚动方向
DOMMouseScroll
- 鼠标滚轮滚动事件(只支持火狐)
用event.detail获取滚动方向
鼠标 / 键盘属性
event = event || window.event; (兼容写法:前面是标准浏览器,后面是ie6,7,8)
clientX
clientY
- 获取鼠标指针在可见窗口的水平和垂直坐标
pageX
pageY
- 代表鼠标在当前文档区域(整个网页,包括滚动条下面)的坐标
注意:在ie8中不支持
事件冒泡(Bubble)
- 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。
- 比如
阻止冒泡
- 阻止事件(主要是事件冒泡,因为IE不支持时间捕获)
* w3c的方法是event.stopPropagation(),IE则是使用event.cancelBubble = true
jquery用stopPropagation(),而js中直接用cancelBubble
事件委托(事件代理)
- 事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件
比如:ul下有1000个li,要给每一个li添加点击事件,我们不需要去遍历li,只需要给ul添加点击事件就可以。
默认行为
- 就是指本身就有一些特性,比如点击a标签默认就会跳转
取消默认事件
function preventDefault(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
}
给对象绑定事件
1:onclick
btn.onclick = function(){};
- 不能绑定多个,后面的会覆盖掉前面的。
2.addEventListener()
btn.addEventListener('click',function(){},false)
- 参数
1)事件的字符串,不用写on
2)回调函数,当事件触发时,该函数被调用
3)是否在捕获阶段触发事件,需要一个布尔值,一般传false,如果在事件捕获阶段就触发事件,可以把第三个参数写成true。
* 如果说事件冒泡是从a到li到ul到div,那么事件捕获就是div到ul到li到a;
- 可以同时为一个元素的相同事件绑定多个响应函数。
- 这个方法中的this是绑定事件的对象
3.attachEvent()
btn.attachEvent('onclick',function(){})
* IE8支持
- 参数
1)事件的字符串,需写on
2)回调函数,当事件触发时,该函数被调用
- 可以同时为一个元素的相同事件绑定多个响应函数,但是执行顺序是后绑定先执行。
- 这个方法中的this是window