js的学习之旅
js
几个关键词
动态类型语言 弱类型语言 脚本语言(本身不具备开发操作系统的能力,只能控制其他程序)
嵌入式语言
宿主环境(浏览器 服务器)
混合编程
基本用法
script标签
<script type="text/javascript"></script>
当脚本被禁用
<noscript>您的浏览器不支持js</noscript>
引用外部js文件
<script src="test.js" type="text/javascript" charset="utf-8">
基本语法
输出函数
window.alert('');//以一个弹窗,在点击确定按钮之前代码会停止在这一行
document.write('123');//document指整个页面文档,会破坏原来页面的内容
document.body.innerHTML = '123';//一行一行加载,但是这一行还没加载到body的话则会出错,所以可以写在body里的script标签
console.log(123);//控制台输出
console.error(456);
console.warn(789);
值类型
String 字符串
Number 数字
Boolean
Null
undefined
Symbol
引用类型
Object 对象
Array 数组
Function 函数/方法
输出
定义变量
var str = "abc";
var str = 'abc';
var str = `abc`;//模板字符串
弱类型
数字类型
所有数字都是64位双精度浮点数
var a = 1;
a = 1.5;
正无穷大 Infinity
负无穷大 -Infinity
Boolean
true/false
任何对象都可以作为boolean来使用
false
0
null
""
undefined 变量只有声明没有初始值
NaN
特点:
数据类型却是数字类型
js中唯一一个不等于自己的值
代表运算失败或者运算无法返回正确的数值时返回
与任何数(包括自己)进行运算,结果仍是NaN
console.log(NaN == NaN);
console.log(typeof NaN);
var x = 6;
var c = 5 - 'x';//NaN
var n = true;
var n = 0;
变量提升
变量声明提升
x = "abc";
x = 6.4;
x = NaN;
JS对象
带有属性的方法的特殊数据类型
所有事物都是对象
自定义对象
//自定义对象
var dog = new Object();
dog.name = 'xxy';
dog.color = '黑色';
var cat = {name:'加菲', color:'棕色', age:6};
cat.name;
cat["given name"] = 'cafe';
//使用函数定义对象
//模板 class
function dog(name, color, age){
this.name = name;
this.color = color;
this.age = age;
this.eat = function(food){//方法
}
}
var dog = new dog('旺财', '黑色', 6);
转义字符
var x = 5;
x = '"abc"';
x = "abv\"";
数组
定义数组
//方法1
int[] arr = new int[4];
var items = new Array();
items[0] = 1;
items[1] = 2;
items[15] = 16;//length = 16;
console.log(items);
console.log(items[11])//undefined;
//方法2
var items2 = new Arr(1,2,3,4,5);
console.log(items2);//没毛病
//方法3
var items3 = [1,2,3,4,5];
items["位置1"] = '666';
console.log(items3);//15
注意:如果数组使用字符串做索引来赋值,js会把数组重新定义成为标准对象,数组的方法和属性将不能再使用
二维数组
var items4 = [[1,2], [3,4], [5,6], [7,8]];
运算符
1.四则运算 % ++ --
任性体现
var x = "5" - 3;//2 字面量是数字类型的字符串可以直接运算
var x = "xx" - 3;//NaN 运算失败
var x = "5" + 3;//53
显然,除了加号,字面量是数值的字符串可以直接做运算
var x = -"5";//得到一个-5
var x = - -"5";//得到一个5
2.= += -= *= /= %=
3.== !=
console.log("5" == 5);
如果要严格比较
=== 值和类型必须都一样(绝对等于)
!== 值和类型至少有一个不相等 (不绝对等于)
条件语句
switch类型里的是严格比较
x = "5";
switch(x){
case 5:
console.log(1);
break;
default:
console.log(2);
break;
}
函数
1.参数 不带数据类型
2.返回值
3.传递的参数个数少于函数声明时,参数的默认值为undefined,可以手动设置默认值
4.传递的参数个数多于函数声明时,也不会报错
5.函数也是对象,函数本身也可以作为参数传递
function add(a,b=0){
//内置变量 打印出参数列表
console.log(arguments);
return a + b;
}
console.log(add(1));
console.log(add(1,2,3,4));
function method(func, a, b){
func(a,b);
}
method(add, 1, 2);
调用方式
1.直接调用
2.提供给事件调用
<body>
<button onclick="alert(123)">Test</button>
</body>
3.作为参数来传递
回调函数
function test(){
alert('test');
}
//延时执行
setTimeout(test, 2000);//调用的函数本身,多少毫秒以后
setInterval(test, 2000);//上面的只执行一次,这个会按一个间隔不断执行
注意:test()为函数的返回值,test为函数本身
4.创建对象
function dog(name, color)
{
this.name = name;
this.color = color;
}
var dog1 = new dog('', '');
5.匿名函数 不可以重复调用
<script type="text/javascript">
document.querySelector('button').onclick = function(){
alert(123);
}
</script>
6.静态函数
只能直接通过函数名.静态函数名()来调用,不能通过实例来调用
dog.wangx3 = function(){
console.log('汪汪汪');
}
dog.wangx3();
//var dog1 = new dog('', '');
//dog1.wangx3;//用实例调用是不可的
sumup
可以用来创建对象,对象可以有公共方法,私有方法,静态函数
function dot(name, color){
this.name = name;
this.color = color;
//公共方法
this.eat = function(food){
console.log(food);
sleep();
}
//私有方法,内部方法,直接定义在函数内部,类的外面无法调用
function sleep(){
console.log('sleep');
}
}
dog1.eat('肉');//用实例调用
自调用函数
//第一种方式(官方不推荐)
(function(){
console.log("自调用函数1");
})();
//有传参时候的写法
(function(msg){
console.log(msg);
})("自调用函数1");
//第二种方式
(function(msg){
console.log(msg)
}("自调用函数2"));
//第三种方式
!function(msg){//或者用void(后含空格) 和+
console.log(msg);
}("自调用函数3");
箭头函数
var add = (a, b) => a+b;
add(1, 2);
变量的作用域
函数内声明的变量 局部变量
函数外声明的变量 全局变量
全局变量是全局对象window里面的一个属性
console.log(window)//顶级对象;
window.alert();
var 陷阱
for(var i = 0;i < 3; i++){
console.log(i);
}
console.log(i);//3, 没有报错嗷
在js里使用var定义的变量只有 全局变量和局部变量
for写在了最外面,所以相当于定义了一个全局变量i
let 定义的变量只在代码块里可以访问
const 定义常量
for(let i = 0;i < 3; i++){
console.log(i);
}
console.log(i);//报错了嗷
闭包
如何从外面访问内部的函数
闭包函数
沟通函数的内部和外部的桥梁
1.读取或设置内部的变量
2.始终保存在内存中(一直有占用)//整个外部函数销毁后,变量都不会被销毁
functioin out(){
console.log(a);
var b = 'goodbye';
function inner(){
console.log(b);
var c = 2;
}
inner();
//两个闭包函数
function getB(){
return b;
}
function setB(value){
b.value;
}
//console.log(c);
//return getB;
return {
getInnerB : getB,
setInnerB : setB,
}
};
var func = out();
//func();
func.getInnerB();
事件
发生在HTML元素上的事情
常用事件
onclick 单击
ondbclick 双击
onchange
onfocus
onkeydown
绑定事件
1.行内绑定
this指向的是全局window对象
<button onclick="alert(123)" >Test</button>
2.动态绑定
this指向的是元素本身
<button id="btn2" >Test</button>
//body的最后面,以防出现空指针报错
<script type="text/javascript">
document.getElementById('btn2').onclick = test();
</script>
还有一个灵异事件
function test(){
var name = this.innerText;
alert(name + ' is clicked!');
}
<body>
/*行内绑定时候指向了window对象,没有innerText这个东西*/
<button onclick="test()">Test1</button>//这个没有传过来
<button id="btn2">Test2</button>
</body>
那么怎么获得Test1元素呢?
event是一个自带的参数,要这么操作时候要声明在函数的参数列表里
//事件对象
function test(event){
console.log(event);//有很多很多东西
var name = this.innerText;//相当于event.吗
alert();
}
<body>
/*行内绑定时候指向了window对象,没有innerText这个东西*/
<button onclick="test(this)">Test1</button>//相当于传了元素本身
</body>
3.事件监听
DOM2绑定
this指向元素本身
可以对同一个事件绑定多个函数
可以删除绑定
<button id="btn3">Test3</button>
<script type="text/javascript">
//事件监听
document.getElementById('btn3').addEventListener("click", function(){
console.log(this); //有输出说明事件被触发了,btn3
}, false);
document.getElementById('btn3').addEventListener("click", function(){
console.log(12345); //有输出说明事件被触发了,btn3
}, false)
//删除绑定 一定要用有名字的函数
function to(){
console.log(this);
}
document.getElementById('btn3').removeEventListener("click",
function(){//和上面的不是同一个匿名函数,所以解除不了
console.log(this);
}
);
</script>
事件流
页面中接受事件的顺序
IE 事件冒泡流 由里向外
网景 事件捕获流 由外向里
usecapture 是否使用捕获流
<div id="out">
<div id="inner">
123
</div>
</div>
<script type="text/javascript">
//事件监听
document.getElementById('out').addEventListener("click", function(){
console.log(this); //有输出说明事件被触发了,btn3
}, false);//true为捕获流 out->inner
document.getElementById('inner').addEventListener("click", function(){
console.log(12345); //有输出说明事件被触发了,btn3
}, false)
</script>
核心API
Array对象
var arr1=[1,2,3,4,5];
//arr1[5] = 6;//传统的在末尾加元素的方法
arr1.push(7);//向数组的末尾添加元素
arr1.pop();//删除一个元素,返回被删除的值
arr1.unshift(99);//
//排序
arr1,shift();//从数组前面
//反序
arr1.reverse();
arr1.indexOf(9);
//搞出一个新数组
var arr2 = arr1.map( function(element,index){
return element * element;
})
arr1.forEach(function(element, index){
console.log(element);
})
Date对象
如何得到一个日期
var d = new Date();
d = new Date('2019-10-12');
//从1970/01/01经过的毫秒数
d = new Date(99999);
//月份是从0开始算的 2020/4/8
d = new Date(2020,3,8);
d.getFullYear()
d.getMonth()
d.getDate()
d.getDay()
Math对象
提供一系列静态方法进行运算
//返回0-1之间的随机数(包括0但是不包括1)
Math.random();
Math.abs(x);
Math.round(x);
Math.ceil(x);//向下舍入
Math.floor(x);//向上舍入
Math.max();
Math.pow(x,y);
字符串和数字之间的转换
//数字转字符串
var i = 3.1415
var s = i.toString();
s = i + "";
s = i.toString(2);//转成2进制的字符
s = i.toString(8);
s = i.toFixed(2);//指定小数位数
//字符串转数字
s = "3.14159";
i = s - 0;
i = +s;
i = Number(s);//只能用于十进制转换,如果s里包含非数字会变成NaN
//浮点数
i = parseFloat("3,14");//解析整数,如果有非数字不会报错,返回3.14
ParseInt("3.14");
字符串
使用方法
定义一个字符串
var str1="abc";
var str2='abc';
//还可以嵌套
var str3='"abc"';
转义字符
\'
\"
\\
\n
\t
\b
字符串的拼接
1.+
2.concat
3.join
4.
var str5 = "ab" + "c";
str5.concat("vvv");
//如何换行呢
//方式1
var str6 = "aaaaaaaa"+
"aaaaaaaaaaa";
//方式2
var str7 = "aaaaaaaaaaaa\
aaaaaaaaaaaaa";
//方式3
var str8 = `sssss
ssssss`;//反引号//注意是反斜线不是引号
4.模板字符串
var person = {name : 'cmy', age: 16};
var city = '南京';
console.log(`我是${person.name}, 我是${city}人`);
console.log(`2+2=${2+2}`);
console.log(`2的10次方是${Math.pow(2,10)}`);
常用方法
字符串截取
substring(start, end)
截取start到end-1之间的子字符串,end可以省略
start/end为负值时,会从0开始处理
当end < start时,会自动调整为小的当start,大的当end
var str = "www.baidu.com";
console.log(str.substring(4,9));//不会被截取到末尾
console.log(str.substring(4));
console.log(str.substring(-4,9));//从0开始处理
console.log(str.substring(3,-3));//先(3,0)->(0,3)
2.slice(start, end)
end为负数时,反向截取,-1指的是最后一个字符
end < start时,返回空白字符串
console.log(str.slice(4,9));
console.log(str.slice(4,-4));//反向截取
console.log(str.substring(4,1));//没有输出
3.substr(start, length)
console.log(str.substr(-4,5));//反向截取依旧是顺着数的.com
字符串分割
split(separator, limit)
console.log(str.split('.'));
console.log(str.split());//无参时变成了一个一维数组
console.log(str.split(' '));//传空字符串,拆分了所有单个字符
console.log(str.split('.', 2));//www baidu
字符串查找
1.indexOf
console.log(str.indexOf('baidu'));
console.log(str.indexOf('sin'));//没找到返回-1
console.log(str.indexOf('baidu', 3));//4,指定从位置3开始查找,若从6开始,则返回-1
if(str.indexOf('sin') >= 0)//判断是否存在
console.log(str.includes('baidu'));//直接返回一个布尔值
console.log(str.match('baidu'));//类似正则表达式可以得到一些字符串的匹配信息
console.log(str.search());
其他
console.log(str.replace('baidu', '163'));
var str2 = "aabbaa";
console.log(str2.replace('aa', 'cc'));//ccbbaabb
console.log(str2.replace('aa', 'cc'));
toLowerCase() / toUpperCase()
trim() / trimLeft() / trimRight()
localeCompare
startWith/endWith
repeat重复多少次
console.log("java".repeat(10));
padStart/padEnd 字符串长度补全
console.log("1".padStart(8.'0'))//在前面补0,补全到8位
//转变成html形式
console.log("Java".bold());//-><b>Java</b>
console.log("百度".link("http://www.baidu.com"));
案例
反转www.baidu.com
正则表达式
RegExp
1.模式字符串
2.修饰符
1.i 不区分大小写
2.g 执行全局匹配
3.m 执行多行匹配
perl风格
//定义了一个正则表达式的对象
var reg = new RegExp("apple", 'i');
console.log(reg);
reg = /apple/i;//正则表达式的对象
RegExp:
1.test 检测指定的字符串是否包含某个字串,返回true、false
2.exec 包含第一个匹配的数组或者null
3.compile 改变匹配模式
vat str = "appleappleapple"
console.log(reg.test(str));
console.log(/appie/ig.exec(str));//返回一个类似数组的列表,如果没有匹配到则返回一个null
String:
1.match 返回包含所有匹配字串的数组
2.replace 替换
3.search indexOf
4.split
console.log(str.match(/apple/g));//参数是一个正则表达式,g表示全局,会一直往后匹配;非全局表示匹配到了一个字符串之后不再匹配,会附加一些属性
console.log(str.match(/apple/g));
console.log(str.replace(/apple/g, 'orange'));
console.log(str2.replace(/.+))
应用
表单验证
function testData(event){
var name = document.myform.username.value;
if(! /[0-9a-zA-Z]{3,10}/.test(name)){
alert('用户名输入错误!');
event.preventDefault();//如果是button则不会触发提交
}
}
</script>
</head>
<body>
<form action="reg.html" method="get" name="myform">
<table>
<tr>
<td>