第一章 javascript语法
一, js代码的引入
方式一:在html页写js代码
<script>
alert('hello,world')
</script>
方式二: 引入js文件
<script src="first.js"></script>
二, 变量和赋值
变量:
var a = 100; //变量的定义和赋值
变量名有命名规范:只能由英语字母、数字、下划线、美元符号$构成,且不能以数字开头,并且不能是JavaScript保留字,变量区分大小写也就是说A和a是两个变量。
赋值:
将等号右边的值,赋给左边的变量;等号右边的变量,值不变。
var a = "3";
var b = 2;
a = b
console.log(a) // 2
console.log(b) // '3'
三, 注释
// 我是单行注释
/*
多行注释1
多行注释2
*/
四, 输入输出信息
弹出警告框:alert语句
<script type="text/javascript">
alert("警告框");
</script>
控制台输出console.log("") 和输入框prompt()
<script type="text/javascript">
var a = prompt('我帅不帅?敢说不打屎你!');
console.log(a);
</script>
五, 基础数据类型
数值类型:number
在JavaScript中,只要是数,就是数值型(number)的。无论整浮、浮点数(即小数)、无论大小、无论正负,都是number类型的。
var a = 100; //定义了一个变量a,并且赋值100
console.log(typeof a); //输出a变量的类型
console.log(typeof(a)); //输出a变量的类型
var num = 2.379
var newNum = num.toFixed(2) //设置小数保留的小数位数
console.log(newNum)
var a = Infinity; //表示无穷大
字符串类型:string
1.定义
var a = "abcde";
var b = '怀心抱素'; //不区分单双引号
console.log(typeof a);
console.log(typeof b);
2.常用方法
方法 | 说明 |
---|---|
.length #不加括号的是属性 | 返回长度 |
.trim() #得到一个新值 | 移除空白 |
.trimLeft() | 移除左边的空白 |
.trimRight() | 移除右边的空白 |
.concat(value, ...) #s1='hello';s.concat('xx');得到helloxx | 拼接 |
.charAt(n) #n类似索引,从0开始,超过最大值返回''空字符串 | 返回第n个字符 |
.indexOf(substring, start) #这个start是从索引几开始找,没有返回-1 | 子序列位置 |
.substring(from, to) #不支持负数,所以一般都不用它 | 根据索引获取子序列 |
.slice(start, end) #var s1='helloworld';s1.slice(0,-5) | 切片 |
.toLowerCase() #全部变小写 | 小写 |
.toUpperCase() #全部变大写 | 大写 |
.split(delimiter, limit)#分隔,s1.splite(' '),后面还可以加参数s1.split(' ',2),返回切割后的元素个数 | 分割 |
布尔值:boolean
var b1 = false;
console.log(typeof b1)
true : [] {}
false : undefined null NaN 0 ''
空元素:null
var c1 = null; //空对象. object
console.log(c1)
未定义:undefined
var d1;
//表示变量未定义
console.log(typeof d1)
六, 内置对象类型
一, 数组:Array
1.数组的创建
var colors = ['red','color','yellow']; //直接创建
var colors2 = new Array();//使用构造函数的方式创建 使用new关键词对构造函数进行创建对象
2.数组的赋值
var arr = [];
//通过下标进行一一查看/赋值
arr[0];
arr[0] = 123;
arr[1] = '哈哈哈';
arr[2] = '嘿嘿嘿'
3.数组的常用方法
方法 | 说明 |
---|---|
.length | 数组的大小 |
.push(ele) | 尾部追加元素 |
.pop() | 弹出并获取尾部的元素 |
.unshift(ele) | 头部插入元素 |
.shift() | 弹出并获取头部元素 |
.slice(start, end) | 切片 |
.reverse() #在原数组上改的 | 反转 |
.join(seq)#a1.join('+'),seq是连接符 | 将数组元素连接成字符串 |
.concat(val, ...) #连个数组合并,得到一个新数组,原数组不变 | 连接数组 |
.sort() | 排序 |
.forEach() | 将数组的每个元素传递给回调函数 |
.splice() #参数:1.从哪删(索引), 2.删几个 3.删除位置替换的新元素(可多个元素) | 删除元素,并向数组添加新元素。 |
.map() | 返回一个数组元素调用函数处理后的值的新数组 |
//判断是否是数组
Array.isArray(被检测的值); // 返true或false
//清空数组的方法
var array = [1,2,3,4,5,6];
array.splice(0); //方式1:删除数组中所有项目
array.length = 0; //方式1:length属性可以赋值
array = []; //方式3:最好
//sort排序数字示例
function sortNumber(a,b){
return a - b //升序 //b - a 降序
}
var arr1 = [11, 100, 22, 55, 33, 44]
arr1.sort(sortNumber)
二, JSON对象
var str1 = '{"name": "monkey", "age": 18}';
var obj1 = {"name": "monkey", "age": 18};
// JSON字符串转换成对象
var obj = JSON.parse(str1);
// 对象转换成JSON字符串
var str = JSON.stringify(obj1);
遍历对象中的内容:
var a = {"name": "Alex", "age": 18};
for (var i in a){
console.log(i, a[i]);
}
三, 日期:Date
定义:
创建日期对象只有构造函数一种方式,使用new关键字
var myDate = new Date(); //创建了一个date对象
常用方法:
语法 | 含义 |
---|---|
getDate() | 返回指定日期对象的月份中的第几天(1-31) |
Date() | 返回当前时间 |
getMonth() | 返回指定日期对象的月份(0-11) |
getFullYear() | 返回指定日期对象的年份 |
getDay() | 返回指定日期对象的星期中的第几天(0-6,从周日开始算) |
getHours() | 返回指定日期对象的小时(0-23) |
getMinutes() | 返回指定日期对象的分钟(0-59) |
getSeconds() | 返回指定日期对象的秒数(0-59) |
代码示例:
//创建日期对象
var myDate=new Date();
//获取一个月中的某一天
console.log(myDate.getDate());
//返回本地时间
console.log(myDate().toLocalString());//2018/5/27 下午10:36:23
四, RegExp对象
创建一个正则:
//正则规则内不要包含不想要的空格
var reg = RegExp('正则表达式') //注意,写在字符串中所有带的元字符都会被转义,应该写作\
var reg2 = /正则表达式/ //内部的元字符就不会转义了
reg.test('待检测的字符串') //如果字符串中含有符合表达式规则的内容就返回true,否则返回false
在字符串中应用正则
var exp = 'abcd1234'
exp.match(/d/) //只匹配从左到右的第一个
exp.match(/d/g) //匹配所有符合规则的 返回一个数组
var exp2 = 'a b a A B'
exp2.match(/a/) //只匹配小写a
exp2.match(/a/i) //i表示不区分大小写 A也会被匹配出来
exp2.match(/a/ig) //不区分大小写并匹配所有
exp.search(/正则表达式/i) //不区分大小写,从exp字符串中找出符合条件的子串的第一个索引位置
exp.split(/正则表达式/i,n) //不区分大小写,根据正则切割,返回前n个结果
exp.replace(/正则/gi,'新的值') //i表示不区分大小写,g表示替换所有,将符合正则条件的内容替换成新的值
小问题1
var reg2 = /d/g //正则表示要匹配多个值
reg2.test('a1b2c3') //多次test会的到true true true false 继续test会循环之前的结果
小问题2
var reg3 = /w{5,10}/
reg3.test() //如果什么都不写,那么默认test中传递undefined参数,刚好可以符合9位字符串的规则
五, 数学相关:Math
方法 | 含义 |
---|---|
Math.floor() | 向下取整 |
Math.ceil() | 向上取整 |
Math.max(a,b) | 求a和b中的最大值 |
Math.min(a,b) | 求a和b中的最小值 |
Math.random() | 0-1之间的随机数 |
Math.abs(x) | 返回x的绝对值 |
Math.round(x) | 返回四舍五入的整数 |
//100-200之间的随机整数
Math.round(100 + Math,random()*(200-100))
六, 数据类型之间的转换
parseInt() :字符串转数字
var a = '5'
var a = parseInt(a);
console.log(typeof(a))
//带有自动净化的功能;只保留字符串最开头的数字,后面的中文自动消失。
console.log(parseInt("2018你真帅!!"));
//自动带有截断小数的功能:取整,不四舍五入。
var a = parseInt(5.8) + parseInt(4.7);
console.log(a);
var a = parseInt(5.8 + 4.7);
console.log(a);
//非数字返回NaN, 但是NaN本身是数字类型
var a = parseInt('aaa'); // Not A Number
parseFloat() : 字符串转小数
var a = parseFloat('5.8')+ parseFloat('4.7');
console.log(a);
var a = parseFloat('5.8' + '4.7');
console.log(a);
String()和.toString:转字符串
var n1 = 123;
var str1 = String(n1); //推荐使用
console.log(typeof(str1));
var num = 234;
console.log(num.toString())
Boolean():任何数据类型都可以转成布尔值
var b1 = '123'; // true
var b3 = -123; // true
var b4 = Infinity; //表示正无穷大 true
var b2 = 0; // false
var b5 = NaN; //false
var b6; //表示undefined //false
var b7 = null; //false
七, 运算符
赋值运算符:
运算符 | 示例 | 含义 |
---|---|---|
= | ||
+= | x+=y | x=x+y |
-= | x-=y | x=x-y |
*= | x*=y | x=x*y |
/= | x/=y | x=x/y |
%= | x%=y | x=x%y |
比较运算符
运算符 | 描述 |
---|---|
== | 数值相等 |
!= | 数值不相等 |
=== | 数值与类型均相等 |
!== | 数值与类型不全相等 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
小于等于 |
算数运算符:
运算符 | 描述 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 取余 |
++ | 自增 |
-- | 自减 |
var a = 1;
var b = a++; // a=2 b=1,先赋值后++
var c = ++a; // a=3 c=3,先++后赋值
//字符串 + 数值 = 字符串
var a = 'hello' + 2
//字符串 - 数值 = 数值
var b = '3' - 1
逻辑运算符:
运算符 | 描述 |
---|---|
&& | 与 |
|| | 或 |
! | 非 |
第二章 流程控制与函数
一, 流程控制
//单if
var ji = 20;
if(ji >= 20){
console.log('恭喜你,吃鸡成功,大吉大利');
}
alert('下面的代码还会执行');
//if else
var ji = 20;
if(ji>=20){
console.log('恭喜你,吃鸡成功,大吉大利')
}else{
console.log('很遗憾 下次继续努力')
//if...else if...else
if (true) {
//执行操作
}else if(true){
//满足条件执行
}else if(true){
//满足条件执行
}else{
//满足条件执行
}
//case语句
var gameScore = 'better';
switch(gameScore){
//case表示一个条件 满足这个条件就会走进来 遇到break跳出。如果某个条件中不写 break,那么直到该程序遇到下一个break停止
case 'good':
console.log('玩的很好')
//break表示退出
break;
case 'better':
console.log('玩的非常好')
break;
case 'best':
console.log('恭喜你 吃鸡成功')
break;
default: //都不符合会执行
console.log('很遗憾')
}
//while循环
var i = 1; //初始化循环变量
while(i<=9){ //判断循环条件
console.log(i);
i = i+1; //更新循环条件
}
//do-while循环
//不管有没有满足while中的条件do里面的代码都会走一次
var i = 3; //初始化循环变量
do{
console.log(i)
i++; //更新循环条件
}while (i<10) //判断循环条件
//for循环
//遍历数组最好用这种方式
for(var i = 1;i<=10;i++){
console.log(i)
}
var arr = [1,2,3,4,5]
for (n in arr){
console.log(n)
}
//三元运算符
var a = 1
var b = 2
var c = a > b ? a:b //如果a>b成立返回a,否则返回b
console.log(c)
二, 函数
函数的定义:
function 函数名字(){
函数体
}
函数的调用:
函数名();
函数的参数和返回值:形参和实参
注意:实际参数和形式参数的个数,要相同
注意:函数只能返回一个值,如果要返回多个值,只能将其放在数组或对象中返回
console.log(sum(3, 4));
//函数:求和
function sum(a, b) {
return a + b;
}
伪数组:arguments
arguments代表的是实参。有个讲究的地方是:arguments只在函数中使用
-
返回函数实参的个数:arguments.length
fn(2,4); fn(2,4,6); fn(2,4,6,8); function fn(a,b,c) { console.log(arguments); console.log(fn.length); //获取形参的个数 console.log(arguments.length); //获取实参的个数 console.log("----------------"); }
-
之所以说arguments是伪数组,是因为:arguments可以修改元素,但不能改变数组的长短
fn(2,4); fn(2,4,6); fn(2,4,6,8); function fn(a,b) { arguments[0] = 99; //将实参的第一个数改为99 arguments.push(8); //此方法不通过,因为无法增加元素 }
匿名函数:
// 匿名函数方式,多和其他函数配合使用
var sum = function(a, b){
return a + b;
}
sum(1, 2);
自执行函数:
// 立即执行函数,页面加载到这里,这个函数就直接执行了,不需要被调用执行
(function(a, b){
return a + b;
})(1, 2);
//python中写可以这么写:ret=(lambda x,y:x+y)(10,20) 然后print(ret)
函数的全局变量和局部变量:
//全局变量
a = 1;
//局部变量
var b = 2;
//for循环内的变量
let c = 3;
第三章 面向对象
创建对象的几种常用方式:
- 使用Object或对象字面量创建对象
- 工厂模式创建对象
- 构造函数模式创建对象
- 原型模式创建对象
一, 使用Object或对象字面量创建对象
JS中最基本创建对象的方式:
var people = new Object();
student.name = "怀心抱素";
student.age = "20";
这样,一个student对象就创建完毕,拥有2个属性name
以及age
,分别赋值为"easy"
和20
。
对象字面量方式创建对象:
var people = {
name : "怀心抱素",
age : 20
};
二, 工厂模式创建对象
function createPeople(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
return obj;
}
var people1 = createPeople("怀心抱素1", 20);
var people2 = createPeople("怀心抱素2", 20);
...
var people3 = createPeople("怀心抱素n", 20);
//可以源源不断的创建,但是无法判断类型
三, 构造函数模式创建对象
在上面创建Object这样的原生对象的时候,使用了构造函数:
var obj = new Object();
var arr = new Array(10); //构造一个初始长度为10的数组对象
在进行自定义构造函数创建对象之前,首先了解一下构造函数
和普通函数
有什么区别。
- 实际上并不存在创建构造函数的特殊语法,其与普通函数唯一的区别在于调用方法。对于任意函数,使用new操作符调用,那么它就是构造函数;不使用new操作符调用,那么它就是普通函数
- 按照惯例,约定构造函数名以大写字母开头,普通函数以小写字母开头,这样有利于显性区分二者。例如上面的new Array(),new Object()
- 使用new操作符调用构造函数时,会经历
- 创建一个新对象
- 将构造函数作用域赋给新对象(使this指向该新对象)
- 执行构造函数代码
- 返回新对象
了解了构造函数
和普通函数
的区别之后,使用构造函数将工厂模式
的函数重写,并添加一个方法属性:
function People(name, age) {
this.name = name;
this.age = age;
this.alertName = function(){
alert(this.name)
};
}
function Fruit(name, color) {
this.name = name;
this.color = color;
this.alertName = function(){
alert(this.name)
};
}
再分别创建People和Fruit的对象:
var v1 = new People("怀心抱素", 20);
var v2 = new Fruit("apple", "green");
alert(v1 instanceof People); //true
alert(v2 instanceof People); //false
alert(v1 instanceof Fruit); //false
alert(v2 instanceof Fruit); //true
alert(v1 instanceof Object); //true 任何对象均继承自Object
alert(v2 instanceof Object); //true 任何对象均继承自Object
这样就解决了工厂模式
无法区分对象类型的尴尬。那么使用构造方法来创建对象是否已经完美了呢?使用构造器函数通常在js中创建对象。
发现People和Fruit对象中共有同样的方法,当进行调用的时候这无疑是内存的消耗。完全可以在执行该函数的时候再这样做,办法是将对象方法移到构造函数外部:
function People(name, age) {
this.name = name;
this.age = age;
this.alertName = alertName;
}
function alertName() {
alert(this.name);
}
var peo1 = new People("怀心抱素1", 20);
var peo2 = new People("怀心抱素2", 20);
在调用stu1.alertName()时,this对象才被绑定到stu1上。通过将alertName()函数定义为全局函数,这样对象中的alertName属性则被设置为指向该全局函数的指针。由此stu1和stu2共享了该全局函数,解决了内存浪费的问题。
但是,通过全局函数的方式解决对象内部共享的问题,终究不像一个好的解决方法。如果这样定义的全局函数多了,想要将自定义对象封装的初衷便几乎无法实现了。更好的方案是通过原型对象模式来解决。
四, 原型的模式创建对象
function People() {
this.name = '怀心抱素';
this.age = 20;
}
People.prototype.alertName = function(){
alert(this.name);
};
var peo1 = new People();
var peo2 = new People();
peo1.alertName(); //怀心抱素
peo2.alertName(); //怀心抱素
alert(stu1.alertName == stu2.alertName); //true 二者共享同一函数