JS
JS
JS是动态,弱类型语言
判断语言
强弱类型:是否存在强制类型转换
动静态语言:是否需要编译
JS语句如果写在一行,两个语句之间一定要加;
写在不同行;
加不加无所谓
默认以分号作为结束符
注释
单行注释
//单行注释
多行注释
/*
多行注释1
多行注释2
*/
js引入方式
-
script标签内直接写,可在head或者body最后写
<script> alert(123) </script>
-
通过script标签src添加 引入外部js文件
<script src="js.js"></script>
常量和变量
标识符
标识符必须是字母,下划线,美元符号$和数字组成,数字不能开头.
标识符区分大小写.
推荐使用驼峰体
声明
var 声明一个变量
let 声明一个块作用域中的局部变量,
const 声明一个常量,常量声明的时候一定要初始化.无法被修改
JS中的变量声明和初始化是可以分开的.
var y // 只是声明,y值默认为undefined
var x= 5 //规范的声明并初始化,声明全局或局部变量
x = 6 //不规范的初始化,不建议,严格模式下会产生异常,再赋值之前不能引用,因为没有声明,一旦纸样赋值就是全局作用域.
function hello()
{
var a // 只是声明,a为undefined.作用域再函数中
a=100
}
console.log(a) //为声明变量a,异常
//a= 200 //不能提升作用域
//var a = 200;hello(); // var 提升作用域
变量提升
var
命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined
。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。
为了纠正这种现象,let
命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
console.log(a);
var a = 10;
VM124:1 undefined
--------------------------------------------
console.log(b);
let b = 30;
VM189:1 Uncaught ReferenceError: Cannot access 'b' before initialization
at <anonymous>:1:13
暂时性死区
ES6 明确规定,如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let
命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
不允许重复声明
let
不允许在相同作用域内,重复声明同一个变量。因此,不能在函数内部重新声明参数。
变量和常量的选择
如果明确知道一个标识符定义后不再修改,应该尽量声明称const常量,减少被修改的风险,减少bug
提升作用域
console.log(a)
var a = 100
>>>100
相当于把a= 100 放在了整段代码的最前面
数据类型
名称 | 说明 |
---|---|
number | 数值型,包后整型和浮点型,NaN |
boolean | 布尔型,true和false |
string | 字符串 |
null | null |
undefined | 变量声明为赋值的,对象未定义的属性 |
symbol | ES6新引入的类型,类似枚举,独一无二的值 |
object | 是以上基本类型的复合类型,是容器,数组[],自定义对象{} |
// 类型转换
// 弱类型
console.log('=====string=====')
console.log(a = 3 + 'magedu', typeof(a))
console.log(a = null + 'magedu', typeof(a))
console.log(a = undefined + 'magedu', typeof(a))
console.log(a = true + 'magedu', typeof(a))
// 数字
console.log('=====number=====')
console.log(a = null + 8, typeof(a))
console.log(a = undefined + 8, typeof(a)) //undefined没法转换成一个对应的数字
console.log(a = true + 8, typeof(a)) // 1
console.log(a = false + 8, typeof(a))
// boolean
console.log('=====bool=====')
console.log(a = null + true, typeof(a))
console.log(a = null + false, typeof(a))
console.log(a = undefined + true, typeof(a)) //undefined没法转换成一个对应的数字
console.log(a = undefined + false, typeof(a)) // 1
console.log(a = null & true, typeof(a))
console.log(a = undefined & true, typeof(a))
// 短路
console.log(a = null && true, typeof(a)) // 逻辑运算符,null 直接就是false短路
console.log(a = false && null, typeof(a)) // 逻辑运算符,false短路返回false
console.log(a = false && 'magedu', typeof(a)) // boolean
console.log(a = true && 'magedu', typeof(a)) // 字符串
console.log(a = true && '', typeof(a)) // 字符串
// null
console.log('=====null=====')
console.log(a = null + undefined, typeof(a))
总结:
NaN,not a number 转换数字失败,表示不是数字
遇到字符串,加号就是拼接字符串,所有非字符串隐式转换为字符串.
如果没有字符串,加号把其他所有类型都当数字处理,为数字类型隐式转换为一个数字.
undefined特殊,以为他没有定义值,所以是一个特殊数字NaN.
null,false当作0,true当作1
如果运算符是逻辑运算符,短路符,返回就是短路时的类型,没有隐式转换.
JS算数运算符趋向转换为数字类型
除非是非明确,否则不要依赖隐式转换,写代码的时候,往往为了程序的健壮,请显示转换.
typeof 用来查看js数据类型
x1 = '123.23.23.23'
parseInt(x1)
parseFloat(x1)
>>>123
>>>123.23
字符串
将一个值使用''
单引号或者""
双引号引用起来就是字符串
模板字符串
ES6提供了反引号定义的字符串,可以支持多行,还支持插值(插值就是占位符替换)
转义字符
用时再百度
字符串的用法
类似Python
拼接
建议使用 +
数组
类似python 中的列表
方法 | 说明 |
---|---|
.length | 数组的大小 |
.push(ele) | 尾部追加元素 |
.pop() | 获取尾部的元素 |
.unshift(ele) | 头部插入元素 |
.shift() | 头部移除元素 |
.slice(start, end) | 切片 |
.reverse() | 反转 |
.join(seq) | 将数组元素连接成字符串 |
.concat(val, ...) | 连接数组 |
.sort() | 排序 |
.forEach() | 将数组的每个元素传递给回调函数 |
.splice() | 删除元素,并向数组添加新元素。 |
.map() | 返回一个数组元素调用函数处理后的值的新数组 |
运算符
算数运算符
+ - * / % ++ --
var x=10;
var res1=x++;
var res2=++x;
res1;
10
res2;
12
其中x++表示先将x赋值给res1,再自增1
++x 表示x先自增1,再赋值给res2
比较运算符
> >= < <= != == === !==
由于js是弱类型语言,所以存在强制类型转换
1 == “1” // true 弱等于
1 === "1" // false 强等于
//上面这张情况出现的原因在于JS是一门弱类型语言(会自动转换数据类型),所以当你用两个等号进行比较时,JS内部会自动先将
//数值类型的1转换成字符串类型的1再进行比较,所以我们以后写JS涉及到比较时尽量用三等号来强制限制类型,防止判断错误
逻辑运算符
Python | Javascript |
---|---|
and | && |
or | || |
not | ! |
流程控制
if-else if-else
()中写条件,{}中写函数体
var a = 10;
if (a > 5){
console.log("a > 5");
}else if (a < 5) {
console.log("a < 5");
}else {
console.log("a = 5");
}
switch
case后只能加整型和字符串类型
冒号,分号和break不能省略,
代码运行会找到匹配的case值,然后向下执行,所以一定要有break
var day = 2;
switch (day) {
case 0:
console.log("Sunday");
break;
case 1:
console.log("Monday");
break;
default:
console.log("...")
}
for
()中写条件,{}中写函数体
for (var i=0;i<10;i++) {
console.log(i);
}
while
()中写条件,{}中写函数体
var i = 0;
while (i < 10) {
console.log(i);
i++;
}
三目运算
条件 ? 条件成立 : 条件不成立
var a = 1;
var b = 2;
var c = a > b ? a : b
//这里的三元运算顺序是先写判断条件a>b再写条件成立返回的值为a,条件不成立返回的值为b;三元运算可以嵌套使用;
var a=10,b=20;
var x=a>b ?a:(b=="20")?a:b;
x
10
函数
使用function关键字定义
// 普通函数定义
function f1() {
console.log("Hello world!");
}
// 带参数的函数
function f2(a, b) {
console.log(arguments); // 内置的arguments对象
console.log(arguments.length);
console.log(a, b);
}
// 带返回值的函数
function sum(a, b){
return a + b;
}
sum(1, 2); // 调用函数
// 匿名函数方式
var sum = function(a, b){
return a + b;
}
sum(1, 2);
// 立即执行函数 书写立即执行的函数,首先先写两个括号()()这样防止书写混乱
(function(a, b){
return a + b;
})(1, 2);
// ES6中允许使用`=>` 定义函数,
//var 函数名 = 函数参数 => 返回值;
var f = v => v;
// 等同于
var f = function(v){
return v;
}
var 函数名 = (多个函数参数) => 返回值;
如只有一个函数参数,则课不用括号
函数中的arguments参数
function add(a,b){
console.log(a+b);
console.log(arguments.length); console.log(arguments[0]);
//arguments相当于将出传入的参数全部包含,这里取得就是第一个元素1
}
add(1,2)
>>>3
>>>2
>>>1
arguments可以接收所有传入的参数
函数的全局变量和局部变量
局部变量:
在JavaScript函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它(该变量的作用域是函数内部)。只要函数运行完毕,本地变量就会被删除。
全局变量:
在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。
变量生存周期:
JavaScript变量的生命期从它们被声明的时间开始。
局部变量会在函数运行以后被删除。
全局变量会在页面关闭后被删除。
作用域
首先在函数内部查找变量,找不到则到外层函数查找,逐步找到最外层。与python作用域关系查找一模一样!
对象object
创建对象使用关键字new
JavaScript的对象(Object)本质上是键值对的集合(Hash结构),但是只能用字符串作为键。
遍历对象以key为准.
可以使用.
方法直接获取key对应的值.
ES6中提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当做键。
也就是说,Object结构提供了“字符串--值”的对应,Map结构提供了“值--值”的对应,是一种更完善的Hash结构实现。
Date对象
注意,月份是0到11对应1到12
RegExp对象
js中使用test()来执行正则函数的匹配
定义
推荐使用方法2
注意:正则表达式中不能有空格
// 定义正则表达式两种方式
var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9]{5,11}");
var reg2 = /^[a-zA-Z][a-zA-Z0-9]{5,9}$/;
//^x 以x开头
//y& 以y结尾
校验
// 正则校验数据
reg1.test('jason666')
匹配
var s1 = 'asdfadfjasdlgj';
var reg2 = /^[a-zA-Z][a-zA-Z0-9]{5,9}$/g
当使用/g的时候即为全局匹配,光标会停留在上次匹配到的字符之后
不是用/g,每次光标刷新至文本开头
可使用`reg2.lastIndex来查看光标位置
不写匹配内容,默认匹配undefault