JavaScript
一 JavaScript简介
1 JavaScript起源
https://www.cnblogs.com/linhaifeng/articles/9346219.html
总结JavaScript用途:
JavaScript一般用来编写客户端脚本,来为HTML页面添加交互行为,是前台语言
总结JavaScript的特点:
1.解释执行(浏览器就是解释器):事先不编译、逐行执行、无需进行严格的变量声明
2.简单易用:可以使用任何文本编辑工具编写,只需要浏览器就可以执行程序
3.基于对象:内置大量现成对象,编写少量程序可以完成目标
2 JavaScript组成
1、ECMAScript:JavaScript的语法标准。包括变量、表达式、运算符、函数、if语句、for语句等。
2、文档对象模型(DOM) Document object model:操作网页上的元素的API。比如让盒子移动、变色、轮播图等。
3、浏览器对象模型(BOM) Broswer object model:操作浏览器部分功能的API。比如让浏览器自动滚动。
二 JavaScript引入方式
1 方式一
<script>
//在这里写代码
</script>
2 方式二
<script src='xxx.js'></script>
三 JavaScript语法规范
#1.JavaScript对换行、缩进、空格不敏感
每一条语句末尾要加上分号,虽然分号不是必须加的,但是为了程序今后要压缩,如果不加分号,压缩之后将不能运行。
#2.所有的符号,都是英文的。比如括号、引号、分号
#3.JavaScript的注释:
单行注释:
//我是注释
多行注释:
/*
多行注释1
多行注释2
*/
四 变量
1 声明变量的语法
//1.先声明后定义
var name; //声明变量时无需指定类型,变量name可以接受任意类型
name = "arther"
//2.声明立刻定义
var age = 18;
JavaScript语言类型
#1.弱类型、强类型
按照计算机语言的类型系统的设计方式,可以分为强类型和弱类型两种。两者之间的区别,就在于计算时是否可以不同类型之间对使用者透明地隐形转换。从使用者的角度来看,如果一个语言可以隐式转换它的所有类型,那么它的变量、表达式等在参与运算时,即使类型不正确,也能通过隐式转换来得到正确地类型,这对使用者而言,就好像所有类型都能进行所有运算一样,这样的语言被称作弱类型。
#2.动态语言、静态语言
动态语言:声明变量时无需指定类型(运行时才开始检查数据类型,即在变量赋值时才确定变量的数据类型)
静态语言:声明变量时必先指定类型
#3.JavaScript是一种弱类型、动态语言,弱类型具体表现如下
var a = 200;
var b ='1';
var c = a+b;
#在强类型中因为数据类型的不兼容会直接报错,而这里会执行,但并不是做运算,而是做了字符串的拼接
#以为的结果:201
#最终的结果:'2001'
#如果进行相减呢
var d = a-b;
alert(typeof d);// -->number
“-”可以是一元运算符(取负),也可以是二元(减法运算)
#进行了数学运算,结果为:199
2 变量名命名规范
#1.由字母、数字、下划线、$组成,但是不能数字开头,也不能纯数字
#2.严格区分大小写
#3.不能包含关键字和保留字
如:abstract、boolean、byte、char、class、const、debugger、double、enum、export、extends、final、float、goto、implements、import、int、interface、long、native、package、private、protected、public、short、static、super、synchronized、throws、transient、volatile
#4.推荐用驼峰体命名法:有多个有意义的单词组成名称的时候,第一个单词的首字母小写,其余的单词首字母写
3 ES6中的let
ES6之前js没有块级作用域,ES6新增了let命令,用于声明变量(声明的变量属于块级作用域),流程控制语句的{}就是块级作用域。其用法类似于var,但是所声明的变量只在let命令所在的代码块内有效。例如:for循环的计数器就很适合使用let命令。
for(let i=1;i<=5;i++){}
4 常量
ES6新增const用来声明常量。一旦声明,其值就不能改变。
const PI = 3.1415926;
PI=3 //TypeError: "PI" is read-only
五 数据类型与内置方法
js是动态语言:变量里面能够存储数字、字符串等。变量会自动的根据存储内容的类型不同,来决定自己的类型。
1 数值(number)
JavaScript不区分整型和浮点型,就只有一种数字类型,即number
var x=3;
var y=3.1;
var z=13e5;
var m=12e-5;
var n=NaN; //typeof n 结果‘number’
四舍五入
var num=1.3456
num.toFixed(2) //'1.35'
字符串类型转成数字
#字符串转Number
parseInt('123') //返回123
#NaN属性是代表非数字值的特殊值。该属性用于指示某个值不是数字
parseInt('ABC') //返回NaN
#带有自动净化的功能:只保留字符串最开头的数字,后面的中文自动消失。例如:
console.log(parseInt("18孙悟空")); //18
#只去末尾的中文,不会去开头的
console.log(parseInt("孙悟空18")); //NaN
#字符串中的数字转浮点
parseInt('123.456') //返回 123
parseFloat('123.456') //返回 123.456
#自动带有截断小数的功能:取整,不四舍五入
var a = parseInt("1.3") + parseInt("2.6"); //a=3
var a = parseFloat("1.3") + parseFloat("2.6"); //a=3.9
数字类型转成字符串
#数字转成字符串类型
var x=10;
var y='20';
var z=x+y; // z='1020'
typeof z; //String
#数字转成字符串类型
var m=123;
var n=String(m)
var a=123;
var b=a.toString()
2 字符串(String)
var a = "hello";
var b = "world";
var c = a+b;
console.log(c); //得到Hellword
方法 | 说明 |
---|---|
.length | 返回长度 |
.trim() | 移除空白 |
.trimLeft() | 移除左边的空白 |
.trimRight() | 移除右边的空白 |
.charAt(n) | 返回第n个字符 |
.concat(value, ...) | 拼接,拼接字符串通常使用“+”号 |
.indexOf(substring, start) | 子序列位置 |
.substring(from, to) | 根据索引获取子序列 |
.slice(start, end) | 切片 |
.toLowerCase() | 小写 |
.toUpperCase() | 大写 |
.split(delimiter, limit) | 分割 |
string.slice(start, stop)和string.substring(start, stop):
两者的相同点:
如果start等于end,返回空字符串
如果stop参数省略,则取到字符串末
如果某个参数超过string的长度,这个参数会被替换为string的长度
substirng()的特点:
如果 start > stop ,start和stop将被交换
如果参数是负数或者不是数字,将会被0替换
silce()的特点:
如果 start > stop 不会交换两者
如果start小于0,则切割从字符串末尾往前数的第abs(start)个的字符开始(包括该位置的字符)
如果stop小于0,则切割在从字符串末尾往前数的第abs(stop)个字符结束(不包含该位置字符)
补充:
ES6中引入了模板字符串。模板字符串(template string)是增强版的字符串,用反引号(`)标识,它的用途为
#1.完全可以当做普通字符串使用
var msg = 'my name is arther';
#2.也可以用来定义多行字符串
var info = '
name:arther
age:18
gender:male
';
#3.并且可以在字符串中嵌入变量
var name = 'arther';
var age = 18 ;
var msg = `my name is ${name},my age is ${age}`;
3 布尔值(Boolean)
区别于Python,true和false都是小写
var a = true;
var b = false;
typeof(b); //"boolean"
任何数据类型都可以转换成boolean类型:空字符串、0、null、underfined、NaN都是false
#布尔值为假的数据类型
Boolean('')
Boolean(0)
Boolean(null)
Boolean(undefined)
Boolean(NaN
# 其余数据类型的布尔值均为真,例如
Boolean([])
Boolean(123)
4 null和undefined
- null表示值是空,一般在需要指定或清空一个变量时才会使用,如 name=null;
- undefined表示当声明一个变量但未初始化时,该变量的默认值是undefined。还有就是函数无明确的返回值时,返回的也是undefined。
null表示变量的值是空,undefined则表示只声明了变量,但还没有赋值。
原因:JavaScript是动态类型,只要到运行的是否变量名与变量值才产生绑定关系,并确认数据类型。
5 常用内置对象
JavaScript中的所有事物都是对象:字符串、数值、数组、函数...
此外I,JavaScript还提供多个内建对象,比如 Array,Date,Math 等等
对象只是带有属性和方法的特殊数据类型
5.1 数组对象Array
数组对象的作用是:使用单独的变量名来存储一系列的值。类似于python中的列表
var x = ["egon","hello"];
console.log(x[1]); //输出"hello"
常用方法:
方法 | 说明 |
---|---|
.length | 数组的大小 |
.push(ele) | 尾部追加元素 |
.pop() | 获取尾部的元素 |
.unshift(ele) | 头部插入元素 |
.shift() | 头部移除元素 |
.slice(start, end) | 切片 |
.reverse() | 反转 |
.join(seq) | 将数组元素连接成字符串 |
.concat(val, ...) | 连接数组 |
.sort() | 排序 |
.forEach() | 将数组的每个元素传递给回调函数 |
.splice() | 删除元素,并向数组添加新元素。 |
.map() | 返回一个数组元素调用函数处理后的值的新数组 |
关于sort()需要注意
如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说的更精确点,是按照字符编码的顺序进行排序。
var arr=[123,9,1222,111]
arr.sort();
>>>[111,1222,123,9]
如果按照其他标准进行排序,就需要提供比较函数,该函数应该具有两个参数a和b,接收传入的a和b,执行函数体代码,然后返回一个值用于说明a和b的大小
- 返回值<0:代表a小于b
- 返回值=0:代表a等于b
- 返回值>0:代表a大于b
示例
function sortNumber(a,b){
return a - b
}
var arr=[123,9,1222,111]
arr.sort(sortNumber);
>>>[9, 111, 123, 1222]
关于遍历数组中的元素,可以使用下面的方式
var arr=[123,9,1222,111]
for (var i=0;i<arr.length;i++) {
console.log(arr[i]);
}
forEach()与map()
var arr=['aa','bb','cc','dd','ee']
arr.forEach(function(item){
console.log(item + "_sb");
}
)
>>>打印出数组内每个元素与之拼接出来的新元素但是不能重新为其赋值
var res=arr.forEach(function(item){
return item + "_sb";
}
)
undefined
>>>没有给变量res进行初始化,说明forEach不能返回值
var arr=['aa','bb','cc','dd','ee']
var res=arr.map(function(item){
return (item + "_sb");
}
)
>>>["aa_sb", "bb_sb", "cc_sb", "dd_sb", "ee_sb"]
>>>map()对比forEach有返回值,形成一个新的数组
5.2 Date日期对象
创建日期对象只有构造函数一种方式,使用new关键字
//方法1:不指定参数
var d1 = new Date();
console.log(d1.toLocaleString());
//方法2:参数为日期字符串
var d2 = new Date("2018/01/27 11:12:13");
console.log(d2.toLocaleString());
var d3 = new Date("01/27/18 11:12:13"); // 月/日/年 时分秒
console.log(d3.toLocaleString());
//方法3:参数为毫秒数
var d4 = new Date(7000);
console.log(d4.toLocaleString());
console.log(d4.toUTCString());
//方法4:参数为:年,月,日,时,分,秒,毫秒
var d5 = new Date(2018,1,27,11,12,13,700);
console.log(d5.toLocaleString()); //毫秒并不直接显示
方法 | 含义 |
---|---|
getDate() | 根据本地时间返回指定日期对象的月份中的第几天(1-31)。 |
getMonth() | 根据本地时间返回指定日期对象的月份(0-11) |
getFullYear() | 根据本地时间返回指定日期对象的年份(四位数年份时返回四位数字) |
getDay() | 根据本地时间返回指定日期对象的星期中的第几天(0-6) |
getHours() | 根据本地时间返回指定日期对象的小时(0-23) |
getMinutes() | 根据本地时间返回指定日期对象的分钟(0-59) |
getSeconds() | 根据本地时间返回指定日期对象的秒数(0-59) |
getMilliseconds() | 根据本地时间返回指定日期对象的获取毫秒 |
getTime() | 返回累计毫秒数(从1970/1/1午夜) |
5.3 Math对象
方法 | 含义 |
---|---|
Math.floor() | 向下取整,如5.1取整为5 |
Math.ceil() | 向上取整,如5.1取整为6 |
Math.max(a,b) | 求a和b中的最大值 |
Math.min(a,b) | 求a和b中的最小值 |
Math.random() | 随机数,默认0-1之间的随机数,若想求min~max之间的数,公式为:min+Math.random()*(max-min) |
5.4 Json对象
//json格式的字符串转成对象
var str1='{"name":"egon","gender":"male"}';
var obj1=JSON.parse(str1);
console.log(obj1.name);
console.log(obj1["name"]);
//对象转成JSON格式
var str2=JSON.stringify(obj1);
5.5 RegExp对象
#1.创建正则对象的方式1
//参数1 正则表达式
//参数2 匹配模式:常用g(全局匹配;找到所有匹配,而不是在第一个匹配后停止)和i(忽略大小写)
//注意:正则放到引号内,{}内的逗号后面不要加空格
var reg1=new RegExp("^[a-zA-Z0-9]{5,11}$");
reg1.test("arther")//true
#2.创建正则对象的方式2
var reg2=/^[a-zA-Z0-9]{5,11}$/;
reg1.test("arther")//true
#3.String对象与正则结合的4个方法
var s1 = "hello world"
s1.match(/l/g) //符合正则的内容["l","l","l"]
s1.search(/h/g)//符合正则的内容的索引为 0
s1.split(/ /) // ["hello","world"]
s1.replace(/l/g,'L') // "heLLo worLd"
#4. 匹配模式g与i
var s2="name:Egon age:18"
s2.replace(/e/,"赢") // "nam赢:Egon age:18" 只取第一个e区分大小写
s2.replace(/e/g,"赢") // "nam赢:Egon ag赢:18" 取所有的e区分大小写
s2.replace(/e/gi,"赢") //"nam赢:赢gon ag赢:18" 去所有的e不区分大小写
六 运算符
算数运算符
+ - * / % ++ --
比较运算符
> >=
< <=
!=
==
===
!==
注意
1 == “1” // true
1 === "1" // false
逻辑运算符
&&
||
!
赋值运算符
=
+=
-=
*=
/=
七 流程控制
if else
var age=18;
if(age>18){
console.log("too old");
}
else if(age=18){
console.log("花姑娘 呦西");
}
else {
console.log("too young");
}
switch
Switch中的case子句通常都会加break语句,否则程序会继续执行后续case中的语句
var day = new Date().getDay();
switch (day) {
case 0:
console.log("星期天,出去浪");
break;
case 6:
console.log("星期六,也出去浪");
break;
default:
console.log("工作日,正常上班")
}
for
for (let i=1;i<=3;i++){
console.log(i);
}
//let也是声明变量,不过在此处是将变量i限制在了for语句的局内,所以在全局中找不到该变量
//如果是var则是跟着for成为了全局变量,这里这样的一个变化是为了防止与全局的变量产生冲突
while
let i=0
where(i<=3){
console.log(i);
i++;
}
三元运算
var x=1;
var y=2;
var x>y? x:y
//比较x、y大小,x大则显示x,反之显示y
八 函数
1 函数的定义与调用
// 无参函数
function f1() {
console.log("Hello world!");
};
f1();
// 有参数函数
function f2(a, b) {
console.log(arguments); // 内置的arguments对象
console.log(arguments.length);
console.log(arguments[0],arguments[1]);
console.log(a, b);
};
f2(10,20);
// 带返回值的函数
function sum(a, b){
return a + b;
}
res = sum(1, 2); // 调用函数
// 匿名函数
var sum = function(a, b){
return a + b;
}
sum(1, 2);
// 立即执行函数
(function(a, b){
return a + b;
})(1, 2);
2 函数中的arguments参数
function add(a,b){
console.log(a+b);
console.log(arguments.length)
}
add(1,2)
>>>3
>>>2
注意:
函数只能返回一个值,如果要返回多个值,只能将其放在数组或对象中返回
3 函数的全局变量和局部变量
#局部变量:
在JavaScript函数内声明的变量(使用 var)是局部变量,所以只能在函数内部访问它,该变量的作用域是在函数内部。只要函数运行完毕,局部变量就会被删除。
#全局变量:
在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它
#变量生存周期:
JavaScript变量的生命周期从她们被声明的时间开始
局部变量会在函数运行以后被删除
全局变量会在网页关闭后被删除
4 作用域
首先在函数内部查找变量,找不到则到外层函数查找,逐步找到最外层。另外函数的作用域关系是在定义阶段就固定死的,与调用位置无关
例1
var city = "BeiJing";
function f() {
var city = "ShangHai";
function inner(){
var city = "ShenZhen";
console.log(city);
}
inner();
}
f(); //ShenZhen
例2
var city = "BeiJing";
function Bar() {
console.log(city);
}
function f() {
var city = "ShangHai";
return Bar;
}
var ret = f();
ret(); //BeiJing
例3
var city = "BeiJing";
function f(){
var city = "ShangHai";
function inner(){
console.log(city);
}
return inner;
}
var res = f();
res(); //ShangHai
注意:
for (var i=1;i<=3;i++){
console.log(i);
}
console.log(i)
>>>4
//此处i跟着for为全局变量
//可以将声明改为let从而将变量设为局部
for (let i=1;i<=3;i++){
console.log(i);
}
console.log(i)
>>>Uncaught SyntaxError: Invalid or unexpected token
//报错
function f(){
name="arther";
var age=18;
}
console.log(name);
>>>arther
//在函数内该变量没有声明,那么将会默认为全局声明的变量
console.log(age);
>>>VM2006:1 Uncaught ReferenceError: age is not defined
//报错
5 变量提升和函数提升
(1) 在js中只有两种作用域
#1.全局作用域
#2.函数作用域
在ES6之前,js是没有块级作用域的
首先来解释一下什么是没有块级作用域
(2) 什么是变量提升
在我们js中,代码的执行时分两步走的,1.解析 2.一步一步执行
那么变量提升就是变量声明会被提升到作用域的最顶上去,也就是该变量不管是在作用域的那个地方声明的,都会提升到作用域的最顶上去。
上面写法其实等价于下面的写法
看个例子:
(3) 什么是函数提升
注意函数声明式,会将函数的声明和定义一起提升到作用域的最顶上去。
如果是这种写法:函数表达式声明的函数
相当于var fn;顶到了最上(类似变量提升了),然后打印时发现该变量并没有被定义。直到被函数定义。
最后一个例子
最后总结
1.所有的声明都会提升到作用域的最顶上去。
2.同一个变量只会声明一次,其他的会被忽略掉。
3.函数声明的优先级高于变量声明的优先级,并且函数声明和函数定义的部分一起被提升。