Noname's Blog
信息安全专业的小萌新,立志走上更大的舞台
JavaScipt

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>