Javascript
Javascript 引入的方式
- script 标签
defer:dom 加完后,再执行 js 代码
charset: 字符编码(utf-8) - a 标签中调用 js
1. a href="javascript:js_method();"
<a href="javascript:var a=10,b=20;alert('结果为:'+(a+b))">测试</>
这是我们平台上常用的方法,但是这种方法在传递this等参数的时候很容易出问题,而且javascript:协议作为a的href属性的时候不仅会导致不必要的触发window.onbeforeunload事件,在IE里面更会使gif动画图片停止播放。W3C标准不推荐在href里面执行javascript语句
2. a href="javascript:void(0);" οnclick="js_method()"
这种方法是很多网站最常用的方法,也是最周全的方法,onclick方法负责执行js函数,而void是一个操作符,void(0)返回undefined,地址不发生跳转。而且这种方法不会像第一种方法一样直接将js方法暴露在浏览器的状态栏。
3.a href="javascript:;" οnclick="js_method()"
这种方法跟跟2种类似,区别只是执行了一条空的js代码。
4.a href="#" οnclick="js_method()"
这种方法也是网上很常见的代码,#是标签内置的一个方法,代表top的作用。所以用这种方法点击后网页后返回到页面的最顶端。
5.a href="#" οnclick="js_method();return false;"
这种方法点击执行了js函数后return false,页面不发生跳转,执行后还是在页面的当前位置。
们的区别是每个href里的javascript方法都用try、catch包围。
综合上述,在a中调用js函数最适当的方法推荐使用:
a href="javascript:void(0);" οnclick="js_method()"
a href="javascript:;" οnclick="js_method()"
a href="#" οnclick="js_method();return false;"
<a href="javascript:void(document.body.style.backgroundColor='green');">测试</a>
- 外部引入 js 文件
<s’cript src="demo.js" type="text/javascript"></script>
// async 可选 ,异步执行脚本
- 注意事项
alert('</script>')会错误,需要用+拆开
alert('</s' + 'cript>')
Javascript 标识符
- 第一个字符必须是字母、下划线(_)或($)
- 其他字符可以是字母、下划线、美元符号或数字
- 不能把关键字、保留字、true\false\null 作为标识符
关键字:
break else new var case finally return void catch for switch while continue function this with default if throw delete in try do instanceof typeof ...
保留字:
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
Javascript 注释
单行注释
// 注释内容 vscode快捷键ctrl+/
多行注释
/*
注释内容
注释内容 vscode快捷键alt+ shift + a
*/
Javascript 变量和常量
- 常量:在程序中直接给出具体的数据,常量不可以改变
- 变量:在内存中开辟一段空间用于存放某个某个数据
- 只定义变量
var x;
var a,b,c - 定义变量且赋值
var x1 = true;
var y1 - 100
说明: 因为是弱语言,① 定义变量时可以不指定变量类型;② 可以重复定义;③ 可以不定义变量直接赋值,默认是为 window 对象添加了属性;④ 定义的变量如果没有赋值,系统将自动赋值为 undefined;⑤ 一条语句可以已分号结束,也可以不加分号;如果是多条语句写在同一行上,必须用分号隔开。
Javascript 数据类型
数据类型:在内存存储的方式
-
基本数据类型:7 种原始类型
undefined:typeof instance === "undefined" Boolean:typeof instance === "boolean" Number:typeof instance === "number" String:typeof instance === "string BigInt:typeof instance === "bigint" Symbol :typeof instance === "symbol" null:typeof instance === "object"。number:数值型,区分整型和浮点型
// 二进制 Binary system // 以0b或0B开头 var FLT_SIGNBIT = 0b10000000000000000000000000000000; // 2147483648 var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040 var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607 // 二进制展示(方便展示,理解上却更难了) // 正数:就是正数的原码 // 负数:负号+正数的原码 // 不是数值的二进制补码 parseInt(-10).toString(2) // -1010 // 十进制 Decimal system // 以0开头,但是后面跟8以下会当作八进制处理 var d = 1234567890; var l = 0888; // 888 十进制 var o = 0777; // 511 八进制 // 八进制 Octal number system // 以0开头,ECMAScript 6支持0o 0123 八进制 var n = 0755; // 493 var m = 0644; // 420 var e = 0o755; // 493 ECMAScript 6规范 // 十六进制 Hexadecimal // 以0x或0X开头 0xFFFFFFFFFFFFFFFFF // 295147905179352830000 0x123456789ABCDEF // 81985529216486900 0XA // 10 isNaN() 用来判断是不是不是一个数,返回Boolean值 NaN: 非数值(not a number)的一个特殊值 注意 true '25' 这样能转成数值的 isNaN()为true。string:字符型
// 在字符数据中输出引号,需要加\转义符 var a = "a\"bc" var b = "a\'bc" console.log(a,b) // js里面怎么转二进制? 字符通过 charCodeAt 转成 Unicode 码十进制,然后通过 Number 对象 toString 方法转成不同进制。 console.log('0'.charCodeAt()) // "48" 十进制 console.log('0'.charCodeAt().toString(16)) // "30" 十六进制 console.log(0x0030.toString(10)) // "48" 十进制 console.log(String.fromCharCode(48)) // "0" console.log('万'.charCodeAt().toString(16)) // "4e07" 十六进制 console.log(String.fromCharCode(0x4e07)) // "万" console.log('万'.charCodeAt().toString(2)) // "100111000000111" 二进制 console.log(String.fromCharCode(0b100111000000111)) // "万" 利用 toString() 方法可以把数值转换为字符串。如果转换的内容为空会报错:可以用 + "" 进行强制转换。 使用 parseInt() 和 parseFloat() 方法可以把字符串转换为数值 要把任何值转换为布尔型数据,在值的前面增加两个 !! 感叹号即可,!!0 为 False,其余的均为 True。 在 JavaScript 中, null 用于对象, undefined 用于变量,属性和方法。 对象只有被定义才有可能为 null,否则为 undefined。boolean:布尔型
null:空,用于对象
undefined:未定义,用于变量,属性和方法。
Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值。 -
引用数据类型
object:用来声明或存储一个对象(对象、函数、正则、字符、数值等)
typeof instance === "object"。任何 constructed 对象实例的特殊非数据结构类型,也用做数据结构:new Object,new Array,new Map,new Set,new WeakMap,new WeakSet,new Date,和几乎所有通过 new keyword 创建的东西var a = new Number(10) // object var b = 10 // number console.log(typeof a, typeof b) // typeof获取数据类型 console.log(a == b) // true ;==只比较值,不比较数据类型 console.log( a === b ) // false
基本类型的变量是存放在栈内存(Stack)里的
引用类型的值是保存在堆内存(Heap)中的对象(Object)
Javascript 运算符
- 算术运算符
// 加减乘除取余 自增 自减
+ - / % ++ --
var y=5;
var x=y++; // x=5,y=6,相当于 x=y;y+1
var x=++y; // x=6 ,y=6 ; 相当于 y+1; x=y;
-13 % 5 // -3
-13 % -5 // -3
13 % -5 //3 除法取决于被除数的符号
console.log(123+'bbb') // 123bbb
console.log('aaa'+'bbb') // aaabbb
console.log(('aaa'+'bbb').length) // 6 获取最总字符串的长度
- 关系运算符
// 返回的一般是true或false
> < >= <= == === != !==
比较方法:
a. 数值比较,比较其大小 console.log(20>30) // false
b. 字符比较,比较ascii码值得大小,按位比较,位置上没有的视为0; console.log('a'<'AJ') // true
c. 汉字比较,比较其Unicode编码值的大小,可以通过charCodeAt() 获取汉字编码值
- 逻辑运算符
逻辑非(取反) 逻辑与 逻辑或
! && ||
! !true => false !false =>true
&& 只要有个操作数为false,结果为false
注意:如果两个中任意一个操作数非逻辑值,第一个操作数的结果为true,返回第二个操作数的值;第一个操作数的结果为false时,返回第一个操作数的值。
console.log('123' && 10+20) // 30
console.log(false && []) // false
console.log(0 && 'aaa') // aaa
|| 只要有一个操作数为true,结果为true
注意:如果两个中任意一个操作数非逻辑值,第一个操作数的结果为true,返回第一个操作数的值;第一个操作数的结果为false时,返回第二个操作数的值。与&&相反
短路运算:&& 运算时,如果第一个操作数为 false 时,不需要计算第二个操作数
短路运算:|| 运算时,如果第一个操作数为 true 时,不需要计算第二个操作数
var x=100
var y = true && ++x
console.log(x,y) // 101 101
var x=100
var y = false && ++x
console.log(x,y) //100 false
-
三目运算符
语法:表达式 1?表达式 2:表达式 3var a=3>2?'abc':'123' // abc -
位运算符
位运算符用来对二进制位进行操作
运算符 描述 示例
& 按位与:如果对应的二进制位都为 1,则该二进制位为 1 5 & 1 等同于 0101 & 0001 结果为 0001,十进制结果为 1
| 按位或:如果对应的二进制位有一个为 1,则该二进制位为 1 5 | 1 等同于 0101 | 0001 结果为 0101,十进制结果为 5
^ 按位异或:如果对应的二进制位只有一个为 1,则该二进制位为 1 5 ^ 1 等同于 0101 ^ 0001 结果为 0100,十进制结果为 4
~ 按位非:反转所有二进制位,即 1 转换为 0,0 转换为 1 ~5 等同于 ~0101 结果为 1010,十进制结果为 -6
<< 按位左移:将所有二进制位统一向左移动指定的位数,并在最右侧补 0 5 << 1 等同于 0101 << 1 结果为 1010,十进制结果为 10
>> 按位右移(有符号右移):将所有二进制位统一向右移动指定的位数,并拷贝最左侧的位来填充左侧 5 >> 1 等同于 0101 >> 1 结果为 0010,十进制结果为 2
>>> 按位右移零(无符号右移):将所有二进制位统一向右移动指定的位数,并在最左侧补 0 5 >>> 1 等同于 0101 >>> 1 结果为 0010,十进制结果为 2
JS 输出语句
使用 alert() 函数来弹出提示框;
使用 confirm() 函数来弹出一个对话框;
使用 prompt() 函数来弹出一个输入框框;
使用 document.write() 方法将内容写入到 HTML 文档中;
使用 innerHTML 将内容写入到 HTML 标签中;
使用 console.log() 在浏览器的控制台输出内容。
<script type="text/javascript">
var res = window.confirm("这里是要显示的内容");
if(res == true){
alert("你点击了“确定”按钮");
}else{
alert("你点击了“取消”按钮");
}
</script>
JS 流程控制
顺序结构
if 语句;
if else 语句;
if else if else 语句;
switc case 语句。
提示:if else if else 语句在执行过程中,当遇到成立的条件表达式时,会立即执行其后{ }中的代码,然后退出整个 if else if else 语句,若后续代码中还有成立的条件表达式,则不会执行。
if (条件表达式 1) {
// 条件表达式 1 为真时执行的代码
} else if (条件表达式 2) {
// 条件表达式 2 为真时执行的代码
}
...
else if (条件表达式N) {
// 条件表达式 N 为真时执行的代码
} else {
// 所有条件表达式都为假时要执行的代码
}
条件结构(分支、选择)
不同形式的条件判断语句:
if 语句;
if else 语句;
if else if else 语句;
switc case 语句。
<script type="text/javascript">
var now = new Date(); // 获取当前的完整日期
var dayOfWeek = now.getDay(); // 获取一个 0-6 之间的数字,用来表示当前是星期几,0 表示星期日、1 表示星期一、以此类推
if(dayOfWeek == 0) { // 判断当前是星期几
alert("星期日")
} else if(dayOfWeek == 1) {
alert("星期一")
} else if(dayOfWeek == 2) {
alert("星期二")
} else if(dayOfWeek == 3) {
alert("星期三")
} else if(dayOfWeek == 4) {
alert("星期四")
} else if(dayOfWeek == 5) {
alert("星期五")
} else {
alert("星期六")
}
</script>
switch 语句根据表达式的值,依次与 case 子句中的值进行比较:
switch case 语句的语法格式如下:
switch (表达式){
case value1:
statements1 // 当表达式的结果等于 value1 时,则执行该代码
break;
case value2:
statements2 // 当表达式的结果等于 value2 时,则执行该代码
break;
......
case valueN:
statementsN // 当表达式的结果等于 valueN 时,则执行该代码
break;
default :
statements // 如果没有与表达式相同的值,则执行该代码
}
- 如果两者相等,则执行其后的语句段,当遇到 break 关键字时则跳出整个 switch 语句。
如果不相等,则继续匹配下一个 case。 - switch 语句包含一个可选的 default 关键字,如果在前面的 case 中没有找到相等的条件,则执行 default 后面的语句段。
- 注意:switch 语句中,表达式是使用全等(===)来与各个 cese 子句中的值进行匹配的。由于使用的是全等运算符,因此不会自动转换每个值的类型。
var id = 1;
switch (id) {
case 1 :
console.log("普通会员");
break; //停止执行,跳出switch
case 2 :
console.log("VIP会员");
break; //停止执行,跳出switch
case 3 :
console.log("管理员");
break; //停止执行,跳出switch
default : //上述条件都不满足时,默认执行的代码
console.log("游客");
}
循环结构(while / for /for ... in / forEach / do... while)
for 循环适合在已知循环次数时使用,
- for 语法格式如下:
for(initialization; condition; increment) {
// 要执行的代码
}
for 循环中包含三个可选的表达式 initialization、condition 和 increment,其中:
initialization:为一个表达式或者变量声明,我们通常将该步骤称为“初始化计数器变量”,在循环过程中只会执行一次;
condition:为一个条件表达式,与 while 循环中的条件表达式功能相同,通常用来与计数器的值进行比较,以确定是否进行循环,通过该表达式可以设置循环的次数;
increment:为一个表达式,用来在每次循环结束后更新(递增或递减)计数器的值。
for 循环中括号中的三个表达式是可以省略的,但是用于分隔三个表达式的分号不能省略
示例代码如下:
for (var i = 1; i <= 10; i++) {
document.write(i + " ");
}
运行结果:
1 2 3 4 5 6 7 8 9 10
// 省略第一个表达式
var i = 0;
for (; i < 5; i++) {
// 要执行的代码
}
// 省略第二个表达式
for (var y = 0; ; y++) {
if(y > 5){
break;
}
// 要执行的代码
}
// 省略第一个和第三个表达式
var j = 0;
for (; j < 5;) {
// 要执行的代码
j++;
}
// 省略所有表达式
var z = 0;
for (;;) {
if(z > 5){
break;
}
// 要执行的代码
z++;
}
- JS for in 循环是一种特殊类型的循环,也是普通 for 循环的变体,主要用来遍历对象,使用它可以将对象中的属性依次循环出来,其语法格式如下:
for (variable in object) {
// 要执行的代码
}
其中,variable 为一个变量,每次循环时这个变量都会被赋予不同的值,我们可以在{ }中使用这个变量来进行一系列操作;object 为要遍历的对象,在每次循环中,会将 object 对象中的一个属性的键赋值给变量 variable,直到对象中的所有属性都遍历完。
JS for in 循环示例代码:
// 定义一个对象
var person = {"name": "Clark", "surname": "Kent", "age": "36"};
// 遍历对象中的所有属性
for(var prop in person) {
document.write("<p>" + prop + " = " + person[prop] + "</p>");
}
运行结果:
name = Clark
surname = Kent
age = 36
for in 循环是为遍历对象而创建的,虽然也可以遍历数组,但是并不推荐,若要遍历数组,可以使用 for 循环或者 for of 循环
- JS for of 循环是 ECMAScript6 中新添加的一个循环方式,与 for in 循环类似,也是普通 for 循环的一种变体。使用 for of 循环可以轻松的遍历数组或者其它可遍历的对象,例如字符串、对象等。
JS for of 循环的语法格式如下:
for (variable of iterable) {
// 要执行的代码
}
其中,variable 为一个变量,每次循环时这个变量都会被赋予不同的值,我们可以在后面的{ }中使用这个变量来进行一系列操作;iterable 为要遍历的内容,在每次循环中,会将 iterable 中的一个值赋值给变量 variable,直到 iterable 中的所有值都遍历完。
while
JS while 循环的语法格式如下:
while (条件表达式) {
// 要执行的代码
}
while 循环在每次循环之前,会先对条件表达式进行求值,如果条件表达式的结果为 true,则执行{ }中的代码,如果条件表达式的结果为 false,则退出 while 循环,执行 while 循环之后的代码。
示例代码如下:
var i = 1;
while( i <= 5) {
document.write(i+", ");
i++;
}
运行结果:
1, 2, 3, 4, 5,
do while
JS do while 循环的语法格式如下:
do {
// 需要执行的代码
} while (条件表达式);
提示:do while 循环与 while 循环还有一点不同,那就是 do while 循环的末尾需要使用分号;进行结尾,而 while 循环则不需要。
使用 do while 循环计算 1~100 之间所有整数的和:
var i=1;
var sum=0;
do {
sum += i;
i++;
} while (i <= 100);
document.write("1 + 2 + 3 + ... + 98 + 99 + 100 = " + sum)
运行结果:
1 + 2 + 3 + ... + 98 + 99 + 100 = 5050
跳出循环
break 语句用来跳出整个循环,执行循环后面的代码;continue 语句用来跳过当次循环,继续执行下次循环。
使用 continue 语句跳出 for 循环:
for (var i = 0; i < 10; i++) {
if(i % 2 == 0) {
continue;
}
document.write(i + " ");
}
运行结果:
1 3 5 7 9
数组和对象遍历
data: {
arr:[11,22,234],
obj:{aa:1,bb:2,cc:3,dd:4}
},
// 数组便利
arrFuc() {
//1、 for
for (let i = 0; i < this.arr.length; i++) {
console.log(this.arr[i]); //11、22、234
}
//2、 for优化,长度缓存数组较大时对优化效果较明显
for (let j = 0, len = this.arr.length; j < len; j++) {
console.log(this.arr[j]); //11、22、234
}
//3、 for in
for (let k in this.arr) {
console.log(this.arr[k]); //11、22、234
}
//4、 for of ES6引进的新方法,对象需要通过和Object.keys()搭配使用,
// 可以正确响应break、continue和return语句
for (let l of this.arr) {
console.log(l); //11、22、234
}
//5、 forEach便利,参数:value数组中的当前项, index当前项的索引, array原始数组;
this.arr.forEach(item => {
console.log(item); //11、22、234
});
//6、 map的回调函数中支持return返回值可以return出来
// return的是啥,相当于把数组中的这一项变为啥(并不影响原来的数组,只是相当于把原数组克隆一份,把克隆的这一份的数组中的对应项改变了);
var newArr = this.arr.map((item, ind, arr) => {
if (item == 22) {
return 33;
} else {
return item;
}
});
console.log("map", newArr); //map [11, 33, 234]
//7、 filter遍历,不会改变原始数组,返回新数组,关键在于正确实现一个“筛选”函数。
var newArr2 = this.arr.filter(item => {
return item != 22;
}); //返回数组项不等于22的
console.log(newArr2); //[11, 234]
//8、 every是对数组中的每一项运行给定函数,如果该函数对每一项返回true,则返回true,否则返回false[返回布尔值]
var everyResult = this.arr.every((item, index, array) => {
return item > 11;
});
console.log("every方法", everyResult); //every方法 false
//9、 some()是对数组中每一项运行指定函数,如果该函数对任一项返回true,则返回true【返回布尔值】
var someResult = this.arr.some((item, index, array) => {
return item == 11;
});
console.log("some方法", someResult); //some方法 true
//10、reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值。
// reduce接受一个函数,函数有四个参数,分别是:上一次的值,当前值,当前值的索引,数组
console.log("reduce方法", this.arr.reduce((a, b) => a + b)); //reduce方法 267
//10.1、reduceRight()方法的功能和reduce()功能是一样的,不同的是reduceRight()从数组的末尾向前将数组中的数组项做累加
//11、find()方法返回数组中符合测试函数条件的第一个元素。正确返回该数值,否则返回undefined
console.log(
"find方法",
this.arr.find(ele => {
return ele == 11;
})
); //find方法 11
console.log(
"find方法",
this.arr.find(ele => {
return ele == 111;
})
); //find方法 undefined
// 11.1\findIndex()只返回符合要求的第一个数索引
console.log(
"findIndex",
this.arr.findIndex((item, index, arr) => {
console.log(item);
return item > 20;
}),
this.arr
); //findIndex 1 (3) [11, 22, 234, __ob__: Observer]
//12、splice(start,length,item)删,增,替换数组元素,返回被删除数组,无删除则不返回【会改变原数组】
this.arr.splice(0, 1, 555);
console.log("splice方法", this.arr); //splice方法 (3) [555, 22, 234, __ob__: Observer]
// 13、ES6 提供三个新的方法 —— entries(),keys()和values() —— 用于遍历数组。它们都返回一个遍历器对象,可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历
for (let index of this.arr.keys()) {
console.log("keys()键名的遍历", index); //keys()键名的遍历 0 keys()键名的遍历 1 keys()键名的遍历 2
}
for (let elem of this.arr.values()) {
console.log("values()键值的遍", elem); //values()键值的遍 555 values()键值的遍 22 values()键值的遍 234
}
for (let [index, elem] of this.arr.entries()) {
console.log("entries()键值对的遍历", index, elem); //entries()键值对的遍历 0 555 entries()键值对的遍历 1 22 entries()键值对的遍历 2 234
}
//14、copyWithin,3个参数第一个参数表示替换到指定索引的位置,第二个参数表示开始复制的的位置,第三个参数是结束位置,23参数没有默认从头开始复制, 替换到结束
console.log("原数组", this.arr); //原数组 (3) [555, 22, 234, __ob__: Observer]
this.arr.copyWithin(1, 0);
console.log("copyWithin", this.arr); //copyWithin (3) [555, 555, 22, __ob__: Observer]
//15、fill
console.log("fill", this.arr.fill(11111, 0, 2)); //fill (3) [11111, 11111, 22, __ob__: Observer]
this.arr.push("undefined");
//16、indexOf、includes
console.log(
"indexOf",
this.arr.indexOf(22),
this.arr.indexOf("undefined")
); //indexOf 2 3
console.log(
"includes",
this.arr.includes(22),
this.arr.includes("undefined")
); //includes true true
},
// 对象便利
objFuc() {
// 1、let in
for (let item in this.obj) {
console.log("键名", item); // 键名name,键名age
console.log("键值", this.obj[item]); //键值yan,键值22
}
//2、Object.keys 键名的便利
console.log(Object.keys(this.obj)); // ["name", "age"]
//3、Object.values 键值的便利
console.log(Object.values(this.obj)); // ["yan", 22]
//4、Object.entries 键值的便利
console.log(Object.entries(this.obj)); // 0: (2) ["name", "yan"] 1: (2) ["age", 22]
console.log(Object.getOwnPropertyNames(this.obj)); //["name", "age", "__ob__"]
for (let item of Object.keys(this.obj)) {
console.log(item); //name,age
}
}