ECMAScript语法
ECMAScript编程语言是松散类型语言(弱类型语言,回顾:Java是强制类型语言,变量声明必须指明数据类型),所谓松散类型就是变量可以存储任何数据类型的数据,变量的类型是根据数据的类型的变化而变化(强制类型语言:自动类型转换和强制类型转换)。
一、变量
1.1 变量的声明
(1)显性声明
<script>
/* var只是用来声明变量,不能决定数据类型,数据类型是使用数据类决定 */
var str = "叶凡";//表示字符串
var str = 100;//表示数字类型
/*function:函数声明优于变量声明*/
function show(){
alert("摇光");
}//变量的名称show
let num = 100;//声明变量
const NAME= "流苏";//用来声明常量
</script>
变量声明特点:`
var和function特点`
- 允许重复声明,如果使用
function 方法名称(){}
如果在一个<script>
块中,加载的优先级最高,后置会覆盖前置,先调用后声明
<script>
var a = 2;
console.log(a);
var a= 3;
console.log(a);
foo();//先调用后声明
function foo(){
console.log("摇光");
}
foo();//函数执行的结果,特点重要
function foo(){
console.log("天枢");
}
foo();//函数调用
</script>
- 声明的变量是存在声明提升,会自动提升到所在作用域的最顶端,但是变量赋值不会提升
console.log(b,"变量没有赋值,返回的数据undefined");
/*优先加载var b;变量的声明,但是不会去加载变量的赋值*/
var b = 10;
相当于:
console.log("=================================");
var b;
console.log(b,"变量没有赋值,返回的数据undefined");
/*优先加载var b;变量的声明,但是不会去加载变量的赋值*/
b= 10;
- 没有块级作用域
console.log("=================================");
function test01(){
//var num;
if(true){//代码块,块级别
var num = 10;//使用var来声明,函数级别
//num= 10;
}
console.log(num);
}
test01();
var
和function
声明的全局变量与顶层对象属性是等价,JavaScript当中,如果没有指定调用的对象,就是JavaScript中最大的对象window
var c="蓝白";
console.log(window);//JavaScript当中最大的对象
/*调用window属性*/
console.log(c,window.c,window["c"],window['c']);
window.test01();
window["test01"]();
注意:this关键字:谁调用就代表谁
<script>
function foo(){
console.log(this,this==window);
}
foo();
document.onclick = foo;
</script>
let声明特点(开发中尽量用let声明)
- let声明的全局变量不属于顶层对象的属性
let bookName = "仙逆";
console.log(bookName,window.bookName);//仙逆 undefined
- let声明变量支持块级别作用域
function test01(){
if(true){
let num = 10;//作用域只能在if代码中有效
}
console.log(num);//num is not defined
}
test01();
- let声明变量名称和var声明变量名称不得相同
- 不支持优先加载,支持顺序加载
(2)隐性声明(不推荐使用)
console.log(window.a);//undefined,顶层声明该变量
function test01(){
a = 5;//没有使用声明的关键字,就属性全局的变量
}
console.log(window.a);
//执行方法的时候才会给该全局变量赋值
test01();
console.log(a);
- .显示声明和隐式声明的变量都是挂载在window上,必须执行隐式声明这代码 全局上才会有这个属性
- 隐式声明没有变量提升
- 如果都在全局,他们都是全局变量
如果在函数中,显示声明变量为局部变量,隐式声明为全局变量
1.2 数据的类型
JavaScript中提供了全局内置函数typeof(数据):结果为数据类型的字符串
(1) 基本数据类型(值类型)
-
简单数据类型:Number、Boolean、String 特殊数据类型:Undefined、Null
百度后发现object也是一种类型
-
存放位置:内存的栈区域
-
值具有不可变性,我们称这样的数据类型的值为原始值
-
基本数据类型的值是使用值访问,基本数据类型的值是不可变的
-
基本数据类型的比较:比较的是值是否相等
==
特殊说明:函数调用都有返回值,如果没有设置return,函数的返回值:undefined
//声明的变量尽量一个变量对应一个数据类型
var num = 123;
console.log("数字类型Number:",typeof(num));
num = 123.456;
console.log("数字类型Number:",typeof(num));
num = "悟空";
console.log("字符串类型String:",typeof(num));
num = '八戒';
console.log("字符串类型String:",typeof(num));
num = true;
console.log("布尔类型Boolean:",typeof(num));
num = null;
console.log("特殊数据类型Null:",typeof(num));//返回的是object字符串,空对象指针
var b;
console.log("特殊数据类型Undefined:",typeof(b));//没有设置值的变量,JavaScript特有的
/*特殊说明:函数调用都有返回值,如果没有设置return,函数的返回值:undefined*/
console.log("=============================");
function test01(){
return 100;
}
console.log(test01());
function test02(){
}
console.log(test02());//undefined
/*当null和undefined进行比较的时候有两种情况*/
console.log(null==undefined);//数据是相同,true
console.log("JavaScript中全等符号,数据相同,数据类型相同",null===undefined);
特殊数据类型Undefined:没有设置值的变量,JavaScript特有
JavaScript中全等符号,数据相同,数据类型相同:null=undefined
数据相同:null=undefined
(2)引用数据类型(对象类型)
-
Object、Array、Function、RegExp、Date
-
存放位置:内存中栈内存指向堆内存的指针,内容在堆内存中
-
值的可变性:引用数据类型的值是按照引用访问,引用类型的值是动态改变的
-
比较:引用类型的比较是引用地址比较,判断是否指向同一个对象
1.3 变量作用域
一定会涉及到一个问题,当函数中形参名称和全局变量名称相同的时候赋值问题。
var name = "流苏"
function user(name){//name形参
console.log("局部变量形参和全局变量相同,如何处理");//范
console.log(name,"没有指定,优先使用局部变量");//范
console.log(this.name,window.name);//流苏
this.name = name;/赋值
}
console.log("全局变量",name);//
user("范");//window.user("范")
console.log("全局变量",name);
- 全局变量:声明的变量是使用var声明,就是全局变量,全局变量可以在整个页面的任何位置使用
- 除了函数以外,其他的任何位置定义变量都是全局变量
- 全局变量,如果页面不关闭,那么就会释放,占用空间,消耗内存(合理声明全局变量)
- 局部变量:在函数内部定义的变量就是局部变量(不要拿隐式声明特例)
- 全局作用域:全局变量的使用范围
- 局部作用域:局部变量的使用范围
- 块级作用域:一对大括号就可以看作一个块,在这个区域定义的变量,只能在区域中使用(推荐使用let),如果使用var声明就不存在块级别作用域,块级别作用域:函数中存在。
-
1.4 类型的转换
(1)强制类型转换
A. 转换数字
let s1 = "123";
let s2 = "113.556";
let s3 = "abc";
let s4 = "100px";
let s5 = "abc456";
let b1 = true;
let b2 = false;
console.log("使用Number类型完成转换");
var num = new Number(s1);//类似于包装类
console.log(num,num.valueOf(),typeof num.valueOf());
console.log(Number(s2),typeof Number(s2));
console.log(Number(s3),typeof Number(s3));
console.log(Number(s4),typeof Number(s4));
console.log(Number(s5),typeof Number(s5));
console.log(Number(b1),typeof Number(b1));
console.log(Number(b2),typeof Number(b2));
console.log("NaN:Not A Number 不是一个数字");
console.log("===使用Number提供的内置方法parseInt和parseFloat");
console.log(Number.parseInt(s1),parseInt(s2));//只留整数部分,没有四舍五入
console.log(Number.parseFloat(s1),parseFloat(s2));
//有能转换成功规则
console.log(s3,parseInt(s3));
console.log(s4,parseInt(s4));
console.log(s5,parseInt(s5));
console.log("布尔类型==>")
console.log(b1,parseInt(b1));
console.log(b2,parseInt(b2));
B. 转换字符串
let num = 123;
console.log(String(num),typeof String(num));
let str = new String(num);
console.log(str,"对象",str.toString());
let s = num+"";//推荐这种:隐式转换
console.log(s,typeof s);
C.转换Boolean(重点:看看哪些值是false)
let s = null;
console.log(Boolean(s),typeof Boolean(s));
s = undefined;
console.log(Boolean(s),typeof Boolean(s));
s = "";
console.log(Boolean(s),typeof Boolean(s));
s = 0;
console.log(Boolean(s),typeof Boolean(s));
s = NaN;
console.log(Boolean(s),typeof Boolean(s));
//false
(2)隐私类型转换
A.加法运算规则:
- 如果一方是字符串,另一方一方也会被转换为字符串类型
- null转换为0
- undefined转换为NaN
console.log(100+undefined);//任何数字和NaN计算都是NaN
console.log(100+null);//100+0
console.log(100+"1");//1001
console.log(100-"1");//字符串会转换10进制运算 99
console.log(100*"2");//200
console.log(100*"2abc");//100*NaN
二、运算符
- 赋值运算符(
=
,扩展赋值运算符(Java中具有强制类型转换功能
)) - 比较运算符
- 算术运算符
- 逻辑运算符
- 条件运算符(三元运算符)
涉及运算
操作数1 运算符 操作数2
,操作数:字面量、变量、函数
(1)比较运算符
/*字符的比较*/
var s1 = "123";
var s2 = 123;
var s3 = 0123;
var s4 = "0123";
/* ==:判断数据是否相等 */
console.log(s1==s2,"字符串纯数字组成,在比较的时候按照10进制转换");
console.log(s4==s3,"0123字符串10转换123,数字类型0123代表8进制");
console.log("=================");
/* ===:全等,翻译typeof A == typeof B && A==B 类型相等数值也必须相等 */
console.log(s1===s2,"值是相等,但是类型不等String Number");
var s5 = "456";
var s6 = 123;
console.log(s5!=s6,"字符串纯数字组成,在比较的时候按照10进制转换");
/* !==:不全等,翻译typeof A != typeof B || A!=B */
console.log(s5!==s6);
(2)逻辑运算符
逻辑运算符运算结果(在Java中只有true和false),但是在javacript不属于false那些值都是真,
我们已经知道false/0/""/null/undefined/NaN
,
这个里面了有一个特殊的比较null==undefined 返回true
/*&& 全真为真 ||全假为假 !取反*/
var str = "adsfa";
if(str){
console.log("真",str)
}else{
console.log("假",str);
}
/*重点知道||的使用的运算结果*/
var name ;
name = name || "流苏";//undefined
console.log(name,"返回值不是boolean,是流苏");
(3)条件运算符
表达式?true执行:false执行
三、语句
- 顺序结构
- 分支结构
- 循环结构
语句块(Java里面称为:代码块:初始化代码块、静态代码块、普通代码块,执行顺序必须要知道)
var x = 10;
{//语句块
var x = 100;//在顶级
}
console.log("x=",x,window.x);
var y = 20;
{//语句块
let y = 200;//作用域在块级别
}
console.log("y=",y);
(1)顺序结构
(2)分支结构
- if语句
- switch语句
- try…catch
function test01(index){
var array = new Array("瑶","流苏","贝贝");
if(array[index]){
return array[index];
}else{
throw "没有数据";//手动抛出异常
}
}
//异常控制流程
try {
var name = test01(-1);
console.log(name);
}catch (e) {
console.log(e);
}
经典面试题:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
function test01(){
try{
console.log(0);
throw "你错误了";
}catch (e) {
console.log(1);
return true;
console.log(2)
}finally {
console.log(3);
return false;
console.log(4)
}
console.log(5);
}
console.log(test01(),"控制台输出的情况");
</script>
</body>
</html>
(3)循环结构
document.getElementById
获取元素对象。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>ECMASCRIPT语法和DOM结合</h3>
<input type="checkbox" name="hobby" value="basketball">篮球
<input type="checkbox" name="hobby" value="football">足球
<input type="checkbox" name="hobby" value="pingpang">乒乓
<input type="checkbox" name="hobby" value="book">看书
<input type="checkbox" name="hobby" value="music">音乐
<input type="checkbox" name="hobby" value="film">电影
<!-- 上述标签中没有ID,如何获取复选框的数据 -->
<hr/>
<button type="button" id="myBtn">选中了几个爱好</button>
<script>
window.onload=function () {//在整个页面资源加载完毕之后,立即执行
var objBtn = document.getElementById("myBtn");
console.log("按钮元素对象,通过.或者[]操作属性",objBtn);
var hobbyArray = document.getElementsByName("hobby");
console.log("按照Name获取元素数组对象",hobbyArray,hobbyArray.length);
//绑定单击事件,匿名函数
objBtn.onclick=function(){
console.log(this,"代表当前的元素对象");
let count = 0;
//数组的遍历
for(let i=0;i<hobbyArray.length;i++){
//获取每一个复选框的元素
var o = hobbyArray[i];
//通过判断checked是否选中
if(o.checked){
count++;
}
}
console.log(i);
alert("你一共选中了["+count+"]个爱好");
};
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>ECMASCRIPT语法和DOM结合</h3>
<select id="hobby" style="width: 150px;height: 200px;" multiple>
<option value="football">足球</option>
<option value="basketball">篮球</option>
<option value="music">音乐</option>
<option value="java">编程</option>
<option value="book">看小说</option>
</select>
<hr/>
<button type="button" id="myBtn">选中了几个爱好</button>
<!-- 分隔线 上述的代码是美工,没有已经设计好页面,尽量不要破坏原来代码的结构,尽量做到代码分离 -->
<script>
window.onload=function () {//在整个页面资源加载完毕之后,立即执行
var hobbyArray = document.getElementById("hobby");//获取select对象,需要找到对象option元素对象
document.getElementById("myBtn")["onclick"]=function(){
let count = 0;
var optionArray = hobbyArray.options;//获取所有option标签
var str = "";
for(let i=0;i<optionArray.length;i++){
var o = optionArray[i];//获取每个option对象
if(o.selected){
count++;
str += o.value+":"+o.text+"|";
}
}
console.log("选择了:"+count);
console.log(str);
}
}
</script>
</body>
</html>
关于while
和do...while
跟java的是一样的
控制循环:break/continue/return
获取索引
- 1.使用普通for循环获取索引,数字的索引
var arr = new Array("星河","摇光",123,true);//Array对象,就可以通过.和[]添加对象属性
arr[9]=100;
arr["name"]="天枢";
arr.author = "银河";
console.log(arr);
for(let index = 0;index<arr.length;index++){
console.log(index,arr[index]);
}
只能遍历数字索引,"name"不能遍历
- 2.for…in的语句获取索引
for(let key in arr){
console.log(key,arr[key]);//只能使用中括号,因为key是变量
}
只能使用中括号,因为key是变量
- 3.for…of的语句对集合中值(Array/Map/Set)
for(let val of arr){
console.log(val);//索引是纯数字
}
四、函数
当函数属于某个对象的时候,称为方法,如果函数数据顶级对象,称为函数
函数的目的就是封装一些功能,重复利用。
4.1 定义函数
一个函数定义(函数声明):由一系列的function
关键字组成,顺序如下:
- 函数的名称
- 函数形参列表,包围在括号中由逗号分隔
- 定义函数体的JavaScript语句,使用大括号包裹
- 返回值:如果没有return,返回值为undefined
定义方式:
- function+函数名:有名函数,称为定义方式
function square/*函数名称*/(number/*形参列表*/){
return number*number;/*函数体和返回值*/
}
function myFunc(a,b,c){
return a+b+c;
}
- function后没有函数名称:匿名函数,必须赋值给某个变量,称为变量方式
var test01 = function(a,b,c){
return a*b*c;
};
var test02 = function(){
console.log("没有return,返回值undefined");
};
4.2 函数调用
我们已经知道,有名函数和匿名函数,我们需要知道他们之间区别。
- 有名函数:先调用后声明,
在一个<script>
标签内,有名函数加载优先级最高,优先加载,当方法名称相同,后置覆盖前置。个人建议:尽量少使用有名函数
- 匿名函数:先声明后调用,按照变量声明的顺序执行。
注意:匿名函数,立即执行
//Uncaught SyntaxError: Function statements require a function name
/*
function(number){
return number*number;
}
*/
var result = (function(number){//匿名函数的立即执行
console.log(number)
return number*number;
})(4);
console.log("result不是函数,是函数执行完毕时候的返回值:",result,typeof result)
4.3 函数作用域
在函数内定义的变量是不能被函数之外的任何地方访问(局部变量),因为变量只能在函数内部进行定义。相对应的,一个函数可以访问定义在其他范围内的任何变量和函数。
定义在全局区域中的函数可以访问所有定义在全局区域中的遍历。在另一个函数中定义的函数也可以访问在其父函数中定义的所有变量和父函数有权访问的任何的其他变量。
//定义全局变量
var num1 = 20;
var num2 = 3;
var name = "吴承恩";
//定义在全局作用域的函数
function multiply(){
return num1*num2;//可以使用全局变量
}
console.log(multiply());
//嵌套函数,在函数的内部定义函数
function getScore(){//父函数
//局部变量
var num1 = 2;
var num2 = 3;
function add(){//可以直接使用父函数中定义的变量或者使用全局变量
return name+"的分数:"+(num1+num2);
}
return add();//方法调用执行,吴承恩的分数:5 的字符串
}
console.log(getScore(),typeof getScore());
4.4 函数参数
- (1) 参数设置默认值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>函数参数</h3>
<script>
function multiply01(a,b){
return a*b;
}
let result = multiply01(20,5);
console.log(result);
function multiply02(a,b){
b = (typeof b !== "undefined")?b:1;
return a*b;
}
result = multiply02(25);
console.log(result);
function multiply03(a=2,b=3){//设置默认值
return a*b;
}
result =multiply03();
console.log(result);
</script>
</body>
</html>
- (2) arguments对象
在调用函数的时候 ,无论传递多少个形参都会被封装到arguments对象中
<script>
function sum(a,b){//形参个数无所谓,自动封装至arguments数组中
console.log(arguments);
return a+b;
}
let result = sum(2,3,4,56,78,9);
console.log("形参个数无所谓,自动封装至arguments数组中");
console.log(result);
function sum01(){
let sum = 0;
for (let i = 0; i < arguments.length; i++) {
sum+=arguments[i];
}
return sum;
}
console.log(sum01(10,20,30));
console.log(sum01(10));
console.log(sum01(10,20,30,5,6,9));
</script>
4.5 函数嵌套(闭包)
可以是一个函数里面嵌套另外一个或多个函数.嵌套内部函数对其容器外部函数是私有的,自身形成了一个闭包.
一个闭包是一个可以自己拥有独立的环境和变量的表达式(通常指函数).
嵌套函数就是一个闭包,它可以继承容器外部函数的参数和变量.内部函数包含外部函数的作用域
- 内部函数只可以在外部函数中访问
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
function addSquares(a,b){//外部函数
//嵌套函数:闭包
function square(x){//内部函数,只能在外部函数中进行调用
return x*x;
}
return square(a)+square(b);//可以使用外部函数中的参数
}
let a = addSquares(2,3);//4+9
console.log(a)
b = addSquares(3,4);//9+16
console.log(b)
</script>
</body>
</html>
- 内部函数形成了一个闭包,它可以访问外部函数参数和变量,但是外部函数不能使用内部函数的参数和变量
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
function outside(x){
function inside(y){//闭包:可以使用外部函数参数或者变量,进行保存操作
return x+y;
}
//关键返回函数的变量;
return inside;
}
var t01 = outside(3);//x=3
console.log("函数的是函数对应的值,不是执行结果");
console.log(t01);
var result01 = t01(5);//y=5,执行函数
console.log(result01);
var result02 = t01(10);//y=10,执行函数
console.log(result02);
t01 = outside(2);
result01 = t01(5);//y=5,执行函数
console.log(result01);
</script>
</body>
</html>
上述代码说明:当inside函数被返回的时候,x变量是怎么被保存下来,
一个闭包(内部函数)必须保存它可见作用域(外部函数)中所有的参数和变量,因为每一次调用传入的参数可能都不相同,每一次对外部函数的调用实际上都会重写创建一遍这个闭包,只有当返回的inside没有被引用的时候,内存才会被释放。
4.6 箭头函数(相当于lambda表达式)
<script>
var arr = new Array("揽星河","携明月","云海之间","凤求凰");
var result01 = arr.map(function(s){ return s.length});
console.log(result01);
var result02 = arr.map(s=>s.length);//自动进行识别推断
console.log(result02);
</script>
五、内置对象
1.数字对象(Number)
在JavaScript中不区分整数和浮点数,统一都是数字类型,通过代码进行说明:
注意:
NaN和任何计算都是NaN
var NUMBER_MAX_VALUE = Number.MAX_VALUE;
console.log(NUMBER_MAX_VALUE);
var NUMBER_MIN_VALUE = Number.MIN_VALUE;
console.log(NUMBER_MIN_VALUE);
var NotANumber = Number.NaN;//NaN和任何计算都是NaN
console.log(NotANumber);
console.log("Number对象中提供的常用方法如下:");
var s = "123.456";
//类型转换方式
var num1 = Number.parseFloat(s);
var num2 = Number(s);
console.log(num1,typeof num1,num2,typeof num2);
console.log("判断是否是为整数:",Number.isInteger(num1));
console.log(num1);
s = "780px";
num1 = Number.parseInt(s);
console.log(num1);
s = "px780";
num1= Number.parseInt(s);//NaN
console.log(num1);
console.log("判断是 不是一个数字:",Number.isNaN(num1));//如果 num1 是特殊的非数字值 NaN(或者能被转换为这样的值),返回的值就是 true
2.数学对象(Math)
console.log("圆周率"+Math.PI);
console.log("绝对值:",-3,Math.abs(-3));
//三角函数,15为弧度,而不是角度(计算机无法计算角度)
console.log(Math.sin(15));
console.log(Math.cos(15));
console.log(Math.tan(15));
console.log("指数",Math.pow(4,3));
console.log("天花板数(最近的整数)",Math.ceil(-11.2));
console.log("地板数(最近的整数)",Math.floor(-11.2));
console.log("获取几个数值中的最大值",Math.max(1,2,3,4,5,6,7,8));
console.log("获取几个数值中的最小值",Math.min(1,2,3,4,5,6,7,8));
console.log("四舍五入,整数部分",Math.round(123.556));
//toFixed方法可以将数字转换为字符串,并指定小数点后保留几位。如果小数实际位数不够指定的位数,使用的是银行家舍入规则:四舍六入五取偶(又称四舍六入五留双)。
console.log("设置函数保留小数点后几位",(123.456).toFixed(2));
//设置函数保留小数点后几位
function roundFun(value, n) {
return Math.round(value*Math.pow(10,n))/Math.pow(10,n);
}
console.log(roundFun(123.456,2));//调用函数
console.log("整数部分,没有四舍五入",Math.trunc(123.556));//截取
3.日期对象(Date)
console.log("如何创建一个日期对象的两种方式:当前时间");
var mydate01 = new Date();//Java中看到new在堆内存中创建空间
console.log(mydate01);
var mydate02 = Date();//调用构造函数才会分配内存
console.log(mydate02);
var mydate03 = new Date(1999,9,18);
console.log(mydate03);
console.log("set开头的方法:用于设置Date对象的日期或者时间");
mydate01.setDate(21);
console.log(mydate01);
console.log("get开头的方法:用于获取Date对象的日期或者时间");
function getNow(){
var d = new Date();
var year = d.getFullYear();
var month = d.getMonth()+1;
var date = d.getDate();
date = date<10?"0"+date:date;
var hour = d.getHours();
hour = hour<10?"0"+hour:hour;
var min = d.getMinutes();
min = min<10?"0"+min:min;
var second = d.getSeconds();
second = second<10?"0"+second:second;
return year+"-"+month+"-"+date+" "+hour+":"+min+":"+second;
}
console.log(getNow());
console.log("获取时间戳",mydate01.getTime())
4.字符串对象(String)
- 1.字符串对象的创建方式:字面量和字符串对象
console.log("1.字符串对象的创建方式:字面量和字符串对象");
var s1 = "天枢";
var s2 = '摇光';
console.log(s2);
var s3 = new String("星河");
console.log(s3);
/**尽量少使用字符的对象创建的方式,有可能产生错误*/
- 2.eval(0方法
var s1 = "2+2";
var s2 = new String("2+2");
console.log(eval(s1));
console.log(eval(s2));
- 3.字符串基本操作
var str = "abcdabcd.docx";
console.log("获取指定索引位置的字符串:",str.charAt(1));
console.log("查找第一次出现时的索引位置,没找到返回-1",str.indexOf("da"),str.indexOf("xyz"));
console.log("查找最后出现时的索引位置,没找到返回-1",str.lastIndexOf("c"),str.indexOf("xyz"));
console.log("是否包含指定的字符串:"+str.includes("da"),str.includes("da",4));//从索引为4的位置开始查找
console.log("开头匹配:"+str.startsWith("abc"));
console.log("末尾匹配:"+str.startsWith(".docx"));
var s = str.concat(".exe").concat(".jpg");//拼接字符串
console.log(s);
console.log("分割字符串,获取数组:",s.split("."));
console.log("截取索引2到末尾----截取2-4(不包含4):",str.substring(2),s.substring(2,4));
console.log("从索引1开始截取长度为4:",str.substr(1,4));
console.log("替换或者查找或者匹配:正则表达式");
console.log("d替换*****"+s.replace("d","*****"));
console.log("变大写"+s.toUpperCase());
console.log("变小写"+s.toLowerCase());
console.log(s.trim(),s.trimEnd(),s.trimStart(),s.trimLeft(),s.trimRight());
4.1多行模版字符串(重要)
注意符号:
``
var a = 5,b=20;
var s1 = "我的计算结果是:"+(a+b)+",翻倍计算:"+(2*(a+b))+"!";//字符串拼接
console.log(s1);
//字符串模版
var template = `我的计算结果是:${a+b},翻倍计算:${2*(a+b)}!`;
console.log(template);
六.数组
1.数组对象:如何创建数组
var str = new Array("天枢","摇光","星河");
var str1 = Array("贪狼","破军","紫薇");
console.log(str,str1,str1.length);
var str2 = ["今日","何日"];//推进写法
console.log(str2,str2.length);
console.log("注意:如果只有一个整数,那么创建对象的结果是不一样");
var str3 = new Array(123);
console.log(str3,str3.length);
var str4 = [123];
console.log(str4,str4.length);
如果只有一个整数,那么创建对象的结果是不一样.new array长度为该数字,用[]创建则是1
2.数组充填数据
因为JavaScripte是弱类型语言,那么我们数据中可以充填任何的数据,但是个人建议保持数据类型一致性
var arr01 = ["摇光",123,true,null,undefined,function(){
console.log(Math.random());
}];
console.log(arr01.length);//5
arr01[10]="天枢";
console.log(arr01,arr01.length);//11
console.log("数组的索引,不是数字,不会统计");
arr01["name"]="星河";
arr01.author="404";
console.log(arr01.length);//11
console.log(arr01);
3.数组遍历
var arr01 = ["天枢","星河","开罗","橙光"];
console.log("A.普通for循环");
for(let i=0;i<arr01.length;i++){
let data = arr01[i];
console.log(data);
}
console.log("B.for...in获取索引,再通过索引获取数据");
for(let index in arr01){
console.log(index,arr01[index]);
}
console.log("C.for...of获取数据");
for(let value of arr01){
console.log(value);
}
console.log("D.foreache方法");
arr01.forEach(function(element,index){
console.log(element,index)
});
console.log("E.箭头函数");
arr01.forEach((element,index)=>{
console.log(element);
console.log(index);
});
console.log("F.修改数组数据");
var arr02 = arr01.map(function(value,index){
return value+"="+index;
});
console.log(arr02);
4.数组方法
(1) 连接
concat
: 连接两个数组并且返回一个新的数组joinjoin
: 将数组的所有元素连接成一个字符串push
: 常用方法,在数组的末尾追加一个或者多个元素,并且返回数组操作后的长度。
var arr01 = ["天枢","开阳","摇光"];
var arr02 = ["玉衡","天机","天璇"];
//数组连接:concat
var arr03 = arr01.concat(arr02).concat("破军","贪狼");
console.log(arr03,arr03.toString());
//数组的转字符串连接:join
var str = arr03.join("-");
console.log(str);
//末尾追加:push
var length = arr03.push("紫薇","太白");
console.log(length,arr03.length);
console.log(arr03.join(","))
(2)移除操作
pop
; 从数组中移除最后一个元素,并返回该元素推荐使用
: 直接令数组长度等于0shift
: 从数组中移除第一个元素,并返回该元素
//清空数组
// 1.pop()
while (arr01.length!=0){
let name = arr01.pop();
console.log(name);
}
console.log(arr01,arr01.length)
// 2.令其长度等于0
arr02.length = 0;
console.log(arr02);
// 3.shift()
var arr01 = ["天枢","开阳","摇光"];
while(arr01.length !== 0){
let name = arr01.shift();
console.log(name)
}
(3)添加操作
push
(常用) : 在数组的末尾追加一个或者多个元素,并且返回数组操作后的长度。unshift
: 在数组的末尾追加一个或者多个元素,
(4)splice()方法
splice(index(索引位置),remove_count(移除元素个数),替换的n个元素)
: 从数组中移除一些元素,替换元素是可选的
var arr01 = ["天枢","开阳","摇光","玉衡","天机","天璇"];
console.log("初始数组:"+arr01);
arr01.splice(0,1);//相当于shift操作
console.log(arr01.join("-")+"==>相当于shift操作");
arr01.splice(arr01.length-1,1);//相当于pop操作
console.log(arr01.join("-")+"==>相当于pop操作");
arr01.splice(0,0,"贪狼");//相当于unshift操作
console.log(arr01.join("-")+"==>相当于unshift操作");
arr01.splice(arr01.length,0,"破军");//相当于push操作
console.log(arr01.join("-")+"==>相当于push操作");
//删除并替换指定位置元素
arr01.splice(3,1,"北极","太白");
console.log(arr01);
(5)排序操作和数组翻转
reverse()
: 数组翻转
var arr01 = ["天枢","开阳","摇光","玉衡","天机","天璇"];
console.log("初始数组:"+arr01);
//数组翻转
console.log(arr01.reverse().join("-"));
- 数组排序
//数组排序
var arr02 = [];
for (let i = 0; i < 10; i++) {
arr02.push(Math.round(Math.random()*100));//随即输出0-100之间的整数
}
console.log(arr02.join());
console.log("排序:"+arr02.sort());
注意:
gai方法仅仅是对第一位数字进行比较然后排序,所以4才会排18之后,所以我们要自定义排序方法
//数组排序
var arr02 = [];
for (let i = 0; i < 10; i++) {
arr02.push(Math.round(Math.random()*100));//随即输出0-100之间的整数
}
//升序
arr02.sort(function (a,b){
if (a>b){
return 1;
}
if (a<b){
return -1;
}
if (a=b){
return 0;
}
});
console.log(arr02.join());
//降序(简写)
arr02.sort(function (a,b){
return b-a;
})
console.log(arr02.join());
//胖箭头表示升序
arr02.sort((a,b)=>a-b);
console.log(arr02.join());
(6)查找操作,是否包含
indexOf
: 从前操作匹配第一个元素的索引位置,找不到返回-1,lastIndexOf
:从后操作匹配第一个元素的索引位置,找不到返回-1includes
查找是否包含某一元素
var arr01 = ["天枢","时代","开阳","摇光","时代","玉衡","天机","天 var arr01 = ["天枢","时代","开阳","摇光","时代","玉衡","天机","天璇"];
//从前查找
console.log("indexOf:从前操作匹配第一个元素的索引位置,找不到返回-1=>"+arr01.indexOf("时代"),arr01.indexOf("闪耀"));
//指定索引位置
console.log("从指定索引位置查找=>"+arr01.indexOf("时代",2));
//从后查找
console.log("lastIndexOf:从后操作匹配第一个元素的索引位置,找不到返回-1=>"+arr01.lastIndexOf("时代"),arr01.lastIndexOf("闪耀"));
//是否包含
console.log("是否包含某个元素:"+arr01.includes("时代"));
//指定位置查找
console.log("从指定位置查找是否包含某个元素:"+arr01.includes("时代",(arr01.length-2)));
- 遍历操作:
foreach
(前文已演示) map
:操作数组元素,返回新数组
(7)筛选操作
filter
:提供过滤规则,返回新数组
var arr01 = ["天枢","时代",12,456,function (){console.log("摇光")},"破军"];
console.log("筛选操作");
var arr02 = arr01.filter(function (element){
return typeof(element)=="number"
})
console.log("筛选数字类型的元素:"+arr02.join());
var arr02 = arr01.filter(value => typeof (value)=="number" && value>100);
console.log("类型为数字且大于100的元素:"+arr02);
every
:当数据中每个元素符合设置的标准的返回true,否则返回falsesome
:当数据中某个元素符合设置的标准的返回true,否则返回false
console.log("every:当数据中每个元素符合设置的标准的返回true,否则返回false");
var arr03 = [1,"2",3];
function isNumber(value) {
return typeof value == "number";
}
console.log(arr03.every(isNumber));//lisNumber变量,函数体
var arr04 =[1,2,3];
console.log(arr04.every(isNumber));
console.log("some:当数据中某个元素符合设置的标准的返回true,否则返回false");
var arr05=["北斗",23,"摇光"];
console.log(arr05.some( isNumber));
七.集合
1.Map类型
console.log("1.Map对象,一服都会使用new标识符");
//存储数据
var tempMap = new Map();//键值对
tempMap.set( "bookName","摇光");
tempMap.set("bookName","流星");
tempMap.set( "author","嘤嘤嘤");
tempMap.set( "price",88.5);
console.log(tempMap)
console.log("获取数据",tempMap.get("bookName"));
//遍历数据
for(let [key,value] of tempMap){
console.log(key," : ",value);
}
console.log(tempMap.has( "author"),tempMap.has( "author123"));
//删除数据
tempMap.delete( "author");
console.log(tempMap.has("author"));//判断是否存在
//清空数据
tempMap.clear();
console.log(tempMap);
2.Set类型
console.log("2.Set对象,一组值得集合,但是不允许重复");
//存储数据
var tempSet = new Set();
tempSet.add("流星");
tempSet.add("摇光");
tempSet.add("流星");//不许重复
tempSet.add("天枢");
console.log(tempSet.size,tempSet);
console.log("判断是否包含某个数据");
console.log(tempSet.has("嘤嘤嘤"),tempSet.has("流星"));
console.log("删除");
console.log(tempSet.delete("天枢"));
for (let value of tempSet) {
console.log(value);
}
3.Set和Array转换
console . log( "1.Set对象转换为数组");
var tempSet = new Set();
tempSet. add( "摇光");
tempSet. add("流星");
tempSet.add("天枢");
console. log(tempSet) ;
var arr01 = Array.from( tempSet);
console. log(arr01) ;
console . log("2 .数组对象转换为Set对象");
var arr02 =["流光",1,2,3,1,2];
var tempSet = new Set(arr02);//去重功能
console. log(tempSet) ;
八.对象
1.创建对象及属性设置
console.log( "1.创建对象和属性设置");
var obj1 = new Object();/**这种方式不推荐*/
//对象增加属性
obj1.bookName ="摇光";
obj1["6"]="天枢";
obj1[666]="星河";
console.log(obj1,obj1.bookName,obj1[6],obj1[666]);
console.log("一元运算符delete,删除某个属性");
delete obj1[6];
console.log(obj1,obj1.bookName,obj1[6],obj1[666]);
console.log ("======================");
//推荐方式
var book = {
bookName:"幸福的咸鱼",
"author":"咸鱼",
1: "嘤嘤嘤",
show:function (){
console.log(this);
return this.bookName+":"+this.price;
}
};//创建对象的同时进行属性的初始化和行为操作
book[666]="摇光";
book.price="$666"
//对象方法调用
console.log(book.show());
console.log("对象遍历");
for (let key in book) {
console.log(key,book[key]);
}
2.创建对象方式
(1)创建对象工厂模式
console.log( "1.创建多个对象时重复代码较多,需要进行封装操作");
function CreatePersonFactory(name){
var obj = {};
obj.name = name;
obj.showName = function (){
return this.name+"-"+Math.random();
}
return obj;
}
var p1 = CreatePersonFactory("嘤嘤嘤");
console.log(p1.showName());
console.log("上述方法缺点:无法识别创建队形的类型,因为全部返回object,没有区分");
上述方法缺点:无法识别创建队形的类型,因为全部返回object,没有区分
(2)构造函数模式
改进:
console.log("2.构造函数模式:this谁调用代表谁");
function Person(name,age){
console.log(this);
this.name = name;
this.age = age;
this.showInfo=function (){
return this.name+"-"+this.age
}
}
var p1 = new Person("摇光",19);
console.log(p1 instanceof Person);//true
console.log(p1);
console.error("不能直接调用,相当于window.person");
Person("嘤嘤嘤",22);
缺点:
var p1 = new Person("摇光",19);
console.log(p1.showInfo());
console.log(p1 instanceof Person);
var p2 = new Person("星河",20);
console.log(p1.showInfo==p2.showInfo);
结果为false
构造方式缺点:创建两个对象公用一个方法,每new一次,系统都会创建一块内存保存方法,但是他们具有相同功能
构造方式缺点:发现方法并没有做到公用,所以采用原型+构造函数模式;
(3)原型+构造函数模式
console.log("4.原型+构造方法模式");
function Student(name,age){
this.name = name;
this.age = age;
}
//原型方法
Student.prototype.showInfo = function (){
return this.name+","+this.age;
}
var s1 = new Student("摇光",12);
console.log(s1.showInfo());
var s2 = new Student("银河",13);
console.log(s2.showInfo());
console.log(s1.showInfo==s2.showInfo);
3.创建对象的属性和方法
function Dog ( name , age) {
//设置私有属性private
var type = "犬";只能在对象构造函教内部使用
//设置公有属性,在对象实例化后调用
this.name = name;
this.age = age;
//对象方法
this.say = function () {//闭包
console.log(type, this.name)
}
}
//类方法(实际就是静态方法,直接周用)
Dog. Run=function( ) {
console.log("跑");
//console. log( "跑" , type) ; //type is not definde
}
//原型方法
Dog.prototype.showInfo = function () {
return this.name + " : " + this.age;
}
//公共的静态属性
Dog.prototype.sex = "公";
console.log("方法调用");
Dog.Run();
console.log(Dog.prototype.showInfo());
console.log(Dog.prototype.sex);
var dog = new Dog("大白", 19);
dog.say();
console.log(dog.showInfo());
console.log(dog.sex);