函数
函数的定义:(三要素:功能、参数、返回值);
//1、字面量定义
function printLove(n){
//函数体
for(var i = 0; i < n; i++){
console.log('i love you~ zhao li ying~');
}
return 1000000;
}
//2、函数表达式定义;
var printLove = function(){
//函数体
for(var i = 0; i < 100; i++){
console.log('i love you~ zhao li ying~');
}
}
//函数调用:
printLove(10);
// alert();//以后只要碰到一个玩意后面加(),那么这个玩意就一定是函数,整体被叫函数调用。这个函数定义一定存在,不是我们自己写的就是系统给定义好的;
函数分类
1 无参无返回值 (一般打印特定的东西或者给项目分模块的时候用到)
2 有参无返回值(给某个事物设置一个属性值)
3无参有返回值;
4有参有返回值(通常我们见到的都是有参有返回值的;)
函数的封装练习:
<script type="text/javascript">
//编写求1到n的和函数
// function getSum(n){
// var sum = 0;
// for(var i = 1; i <= n; i++){
// sum += i;
// }
// return sum;
// }
//
// var result = getSum(100);
//
// console.log(result);
//编写函数实现求一个数的阶乘
function getFactorial(n) {
var product = 1;
for(var i = 1; i <= n; i++) {
product *= i;
}
return product;
}
// console.log(getFactorial(6))
//编写函数求数组的最大值,最小值
function getMaxAndMin(arr) {
var max = arr[0];
var min = arr[0];
for(var i = 0; i < arr.length; i++) {
if(max <= arr[i]) {
max = arr[i];
}
if(min >= arr[i]) {
min = arr[i];
}
}
return [max, min]; //return后面只能返回一个东西,不能返回两个东西 没有max,min这样的写法;封装为数组整体返回;
}
// var arr = [12,3,4,2,325];
// var result = getMaxAndMin(arr);
// console.log(result[0],result[1]);
//封装函数加工数组,每一项加10输出
function addTen(arr) {
for(var i = 0; i < arr.length; i++) {
console.log(arr[i] + 10);
}
}
// var arr = [1,2,3,4,5];
// addTen(arr);
//封装函数实现打印1到N的质数;
function printPrimeNumber(n) {
var flag = true;
for(var i = 1; i <= n; i++) {
for(var j = 2; j < i; j++) {
if(i % j == 0) {
flag = false;
break;
}
}
//
if(flag && i != 1) {
console.log(i);
}
flag = true; //重置标志位;
}
}
printPrimeNumber(5);
//封装函数实现冒泡排序
function bubbleSort(arr) {
for(var i = 0; i < arr.length - 1; i++) {
for(var j = 0; j < arr.length - 1 - i; j++) {
if(arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
// var arr = [12,23,2,45,6];
//
// console.log(bubbleSort(arr));
//封装函数实现对数组的翻转
function reverseArr(arr) {
for(var i = 0; i < arr.length / 2; i++) {
var temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
return arr;
}
// var arr = [12,23,2,45,6];
//
// console.log(reverseArr(arr));
function deleteRepeat(arr) {
var newArr = [];
var flag = true;
for(var i = 0; i < arr.length; i++) {
//外层循环是从arr当中拿数
//内层循环是用外层拿到的数去和newArr当中的数一个一个对比
for(var j = 0; j < newArr.length; j++) {
if(arr[i] == newArr[j]) {
flag = false;
break;
}
}
//
if(flag) {
newArr[newArr.length] = arr[i];
}
flag = true;
}
return newArr;
}
var arr = [1, 2, 3, 4, 1, 2, 3, 1, 1, 2, 3, 4, 7, 8, 2];
console.log(deleteRepeat(arr));
</script>
作用域
程序执行的时候 有两种环境 全局环境和局部环境(函数环境);
作用域链描述的是变量查找的过程;
IIFE匿名函数自调用:
<script type="text/javascript">
// function fn(){};//字面量
// var fn = function(){};//函数表达式定义
// fn();
// 此处省略100行代码
fn();
//函数表达式,没有名字,没办法进行调用,但是没有名字我们可以自己调用
// function(){
// console.log('i love you~');
// }
//匿名函数自调用表达式
特点:
定义的时候就执行了;
只能执行一次,以后想再执行,没门;
匿名函数自调用不会发生预解析;
//作用:
//1、通常用来对项目进行初始化用的;
//2、用来防止命名空间被污染;
//3、封装代码,隐藏代码的实现
//下面虽然我们写了两个一模一样的匿名函数,但是他们是不同的函数
//要想函数两次是调用的同一个,必须是有名函数;
// (function(){
// console.log('i love you~');
// })();
// (function(){
// console.log('i love you~');
// })();
//匿名函数防止命名空间被污染;
var a = 10;
var b = 20;
function add(a,b){
return a + b;
}
var a = 'zhaoliying';
add(a,b);
(function(){
var a = 10;
var b = 20;
function add(a,b){
return a + b;
}
add(a,b);
})();
</script>
arguments伪数组
js当中形参可有可无,可以省略不要 js的函数里面都会有一个arguments伪数组,这个伪数组存储的就是实参
虽然实参伪数组可以让我们拿到传的参数,但是还是推荐使用形参去获取实参;
函数递归
<script type="text/javascript">
//递归是一把双刃剑,用好了就很好,用不好程序就会带来不可挽回的结果;
//因此递归函数,不是随便在自己内部调自己的
//想要构成递归:必须符合2个条件:
//1、递归函数必须有一个明显的结束条件
//2、递归必须有一个趋近于结束条件的趋势;
// function fn(){
// console.log('i love you~ zhao li ying~');
// fn();
// }
//
// fn();
//使用递归函数求阶乘
function factorial(n){
//结束条件
if(n <= 1){
return 1;
}
return n * factorial(n - 1);
}
var result = factorial(5);
console.log(result);
// 5! 5*4!
// 4! 4*3!
</script>
回调函数
<script type="text/javascript">
//函数是可以当参数去传给另外一个函数的,
//只不过,函数当参数去传的时候,一般都是一个回调函数
//下面的写法是把函数当参数传递,但是函数不是回调函数,因为自己调用了;
function fn(n){
console.log('heihei');
n();
}
function fn1(){
console.log('haha');
}
fn(fn1);
</script>
对象
定义对象的方式
1、字面量定义
对象的所有的名或者键 我们都称作属性
对象的所有的值,我们都叫属性值;
对象的属性也分 属性和方法;属性一般都是名词,方法一般都是动词;
2、构造函数定义
var car = new Object({name:'幻影',brand:'劳斯莱斯',color:'black',price:20000000});
3、工厂模式定义对象
function createObject(){
var obj = new Object();
return obj;
}
var obj= createObject();
console.log(person);
注意: 上面我们定义的所有对象都称作:Object的实例对象
var obj1 = {};
var obj2 = new Object();
创建了没有属性的 Object的实例对象
以后我往这个对象当中填了人的属性,那么这个对象就是人
如果我填了狗的属性,那么这个对象就是狗
如果我填了车的属性,那么这个对象就是车
对象的操作和遍历
<script type="text/javascript">
// var arr = [1,2,3,4];
// arr[1] = 22;
var phone = {
name:'mate30',
brand:'华为',
color:'blcak',
price:3000,
size:5.5,
takePhotos:function(){
console.log('我可以拍照');
}
}
//对象的增删改查(全是两种方法)
//1、增和改:两种方法分别是.语法和[]语法
var a = true;
phone.timeLength = 1000; //有则更改,无则添加
phone.name = '荣耀6'
//
phone["memory"] = 128; //这样也是可以进行操作属性添加或者更改
phone["color"] = 'blue'
//假设我们想给对象加一个特殊的名字的属性和属性值;
//contnet-type 不能使用.语法去操作,要想操作只能用[]语法
//如果你想用一个变量的值,作为对象的属性名,也是只能用[]语法,并且不能添加引号;
//对象的属性最终都要是字符串,如果变量的值不是字符串,那么就会被隐式转为字符串
// phone.content-type = 'heihei'; 语法错误,只能用[]
phone["content-type"] = 'haha';
phone["[]"] = 'heihei';
phone[a] = '呵呵';//
console.log(phone);
//删除一个属性
delete phone.name;
console.log(phone);
//查找一个属性,查找这个属性的属性值
console.log(phone.color);
console.log(phone["color"]);
//查找一个对象当中不存在的属性,那么这个属性值是undefined 而不是报错;
console.log(phone.gaga);
//方法的调用
console.log(phone.takePhotos);
phone.takePhotos();
// var fn = function(){
//
// }
//
// console.log(fn);
//对象的遍历:
//遍历数组用for循环 遍历对象用for in循环
//for .. in循环遍历的是对象的所有属性(键)
for(var key in phone){
console.log(key,phone[key])
}
//拓展:
//数组是数组数组也是对象
//for循环只能拿到数组数字属性(下标)的属性和属性值;
//for in循环可以拿到数组所有的属性和属性值;
var arr = [1,2,3,4];
arr.a = 'heihei';
console.log(arr);
for(var i = 0; i < arr.length; i++){
console.log(i,arr[i]);
}
for(var key in arr){
console.log(key,arr[key]);
}
//函数是函数函数也是对象
function add(a,b,c){
return a + b;
}
add.a = 'haha';
console.dir(add);
for(var key in add){
console.log(key,add[key]);
}
</script>
构造函数
<script type="text/javascript">
//创建一个特定的类(理解,在这里类就是函数,只不过这个函数不会当作普通函数去用,本质上还是函数)
function Person(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
this.speak = function(){
console.log('说话');
}
}
var p1 = Person('zhaoliying',32,'famale');//函数当普通函数用,返回值看return,this指向window
var p2 = new Person('zhaoliying',32,'famale');//如果是当构造函数去用,返回值不看return,返回实例化的对象,this指向准备实例化出来的对象
console.log(p1,window);
</script>
原型对象和原型链
1原型最终就是为了 资源共享 节省内存
2 原型链就是为了让一个对象查找属性的时候,有依据;
3 原型链:一个对象在查找属性的时候,先从自身内部去找,如果没有找到,继续顺着隐式原型去找到原型对象,如果原型对象当中有,就是用,没有,那么继续顺着原型对象的隐式原型找到原型对象的原型对象,如果有就用没有继续往上找,直到找到Object构造函数的显式原型对象为止,如果有就用,没有,返回undefined;不会报错;作用域链找到顶端如果没有会报错;
JSON对象
<script type="text/javascript">
var a = 10;
var b = 'zhaoliying';
//第一步:把数据封装为对象
var obj = {
a:a,
b:b
}
//第二步:把对象转化为JSON串 ,然后通过我们的ajax就可以把这个json数据传给后端
var result = JSON.stringify(obj);
console.log(result);
//假设后端给我们传回来的数据,那也必须是json数据格式,如果我们想要解析数据,就是上面的逆运算
//先把后端传过来的json串转化为前端里面的对象或者对象的数组,然后进行操作
console.log(JSON.parse(result).b);
</script>
instanceof
<script type="text/javascript">
var a = 10;//number
a = 'zhaoliying';//string
a = true;//boolean
a = undefined;//undefined
a = function(){};//function
a = null;//object
a = [];//object
a = {};//object
console.log(typeof a);
//A instanceof B 用来判断A这个对象 是不是 B这个构造函数的实例
//转么用来区分数组和对象的,以后去看这个数据是不是数组Array的实例就好了,如果是那它就是数组;
console.log(a instanceof Array);
console.log(a instanceof Object);
//如果你想判断这个值是不是null 直接用===,因为null这个数据类型只有一个值null
//同理这个全等也可以判断undefined;
console.log(a === null);
console.log(a === undefined);
</script>
Math对象的用法
<script type="text/javascript">
var num = -1.5;
//小数转整数用的
console.log(Math.round(num));//把小数四舍五入转化为整数 **
console.log(Math.floor(num));//向下取整**
console.log(Math.ceil(num));//向上取整2**
//max min PI pow abs sin
console.log(Math.max(13,24,4,66,99));//99 取多个数的最大值
console.log(Math.min(13,24,4,66,99));//4 取多个数的最大值
console.log(Math.PI);//圆周率**
console.log(Math.pow(2,50))//幂运算
console.log(2**50);
console.log(Math.abs(num));
console.log(Math.sin(Math.PI * 23 / 180))//js当中三角函数传的参数都是弧度 不是角度
// 弧度: 圆的周长 / 半径 = 360° 对应的弧度
// 周长: 2*PI * r
// 360 === > 2PI 180 ===> PI
// 30 == ?
//23 == ?//
// 180 / PI = 23 / ?//
// 23 * PI / 180
***************************************************************************************
console.log(Math.random());//返回一个随机数 0——1之间 包含0但是不包含1
// //1 - 60 包含60
// console.log(Math.floor(Math.random() * 60 + 1 ));//1 - 60
//
// //5 - 60包含60
// console.log(Math.floor(Math.random()*56 + 5)) //0~ 55.99999999999999 + 5 5 60.99999999999
//
//
// //5 - 90包含90
// console.log(Math.floor(Math.random()*86 + 5))
//
// // 100 - 1000
//
// console.log(Math.floor(Math.random()*901 + 100));
console.log(getRandom(1, 60));
//随机验证码
//第一步:确定码源
var str = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890';
var code = '';
//第二步:拼接验证码
//字符串是有序的东西,只不过字符串是一个常量,无法更改,但是我们可以查找使用,而且也可以当数组使用。
//字符串也有下标和长度;
// str[0] = 'r';
// console.log(str[0]);
for(var i = 0; i < 6; i++) {
code += str[Math.floor(Math.random() * str.length)]
}
console.log(code);
</script>
Date日期时间
<script type="text/javascript">
//想要用到日期时间的一些方法比如getFullYear,先实例化对象,然后才能用实例化对象身上的方法;
//如果想要用到一些其它的方法比如now,这些方法是在Date对象身上的,就不需要实例化对象
// console.log(Date.now());//返回的是当前的时间,用毫秒计算 从1970年1月1日0时0分0秒开始到现在
// console.dir(Date);
// var date = new Date();
// console.log(date);//返回当地所在时区的一个标准时间,这个对象时js内置好的,打印的东西有点奇怪
// console.log(date.getFullYear());//年份全写
// console.log(date.getYear());//已经废弃
// console.log(date.getMonth());//0-11代表1-12月,拿到月份要+1;
// console.log(date.getDate());//拿到日
// console.log(date.getDay());//拿到星期
// console.log(date.getHours());//拿到时
// console.log(date.getMinutes());//分
// console.log(date.getSeconds());//秒
// console.log(date.getMilliseconds());
// console.log(date.toLocaleTimeString());
// console.log(date.toLocaleDateString());//2019/11/1
// console.log(date.getTime());//1970 年 1 月 1 日之间的毫秒数
//格式话当前日期时间字符串
//api 接口 方法 函数 统统本质都是函数;
console.log(getDateAndTimeString());
</script>
字符串方法
<script type="text/javascript">
var str = 'adasd1*234567890123AASDADS';
console.log(str.charAt(1)); //index ********** 三要素
//获取对应下标的字符 参数是下标; 返回值:获取到的字符
console.log(str.charCodeAt(0)); //index
//获取对应下标的字符的Unicode码 参数是下标; 返回值:获取到的字符的unicode码
console.log(str.concat('iii')); //拼接 str + 'iii';
//将原串和传递的字符串参数进行拼接 参数:可以有也可以没有 返回值:没有参数就是复制的原串,如果有返回拼接好的字符串
console.log(String.fromCharCode(49)); //unicode编码
//将字符的unicode码转化为字符 参数:unicode码 返回值:Unicode吗对应的字符
console.log(str.indexOf('2',3)); //********************
//返回字串在原串当中的索引位置,子串的首字符的位置; 参数:第一个是子串 第二个代表从哪开始查
//返回值:子串首字符索引位置;如果根本没有传递参数这个子串,返回 -1;
console.log(str.lastIndexOf('23')); //求子串位置,默认从末尾开始
// console.log(str.replace('1', '**')); //替换字串***********************
// //把传递的第一个子串在原串当中替换为传递的第二个串,只能替换一个;
// //参数:1、被替换的子串 2、用来替换的串
//返回值,替换后的字符串
// str = '123';
console.log(str.localeCompare('123')); //比较大小
//用来比较原串和传递的串之间大小
//参数:传递一个新的串
//返回值:1原串比新串大 -1原串比新串小 0代表相等
//我们这三个方法,要想用到所有的功能,必须和正则表达式配合,后面学了正则后再搞他们;
// console.log(str.match(/1/g)); //找到匹配项返回数组
// console.log(str.replace('1', '**')); /
// console.log(str.search())
console.log(str.slice(4,8)); //*************************
console.log(str.slice(-4,-1));
//用来从长串当中截取字串
// //参数:start和end两个参数 代表子串的起始位置和结束位置;start 开始(包括 start)到 end 结束(不包括 end)为止的所有字符。
// //参数可以使用负数
//返回值:返回截取的子串;
console.log(str.substring(0, 4));
//功能参数返回值和上面slice一模一样,但是唯一不同的是参数不允许是负数
console.log(str.substr(1, 4)); //后面的参数是长度
//功能返回值和上面slice一模一样
//参数前面第一个是开始位置,后面是一个长度
console.log(str.split('2'));//*************************************
// //功能:以指定子串 为间隔将字符串转化(切割)为数组,这个指定的子串将不复存在
//参数:指定的子串,如果指定的子串不存在,相当于没有传递参数;
//返回值:不传参,整个字符串作为数组的值,
// 传参:切割好的数组
// console.log(str.toLocaleLowerCase());
//与 toLowerCase() 不同的是,toLocaleLowerCase() 方法按照本地方式把字符串转换为小写。只有几种语言(如土耳其语)具有地方特有的大小写映射,所有该方法的返回值通常与 toLowerCase() 一样
console.log(str.toLocaleUpperCase());
console.log(str.toLowerCase());
console.log(str.toUpperCase());
//功能:把字符串转化为对应的大写字符串或者小写字符串
//参数:无
//返回值:返回转化后的字符串
console.log(str.valueOf()); //取字符串对应的值,本身就是值类型
console.log(str.toString());
//上面valueof和toString经常是用来把对象数据转化为基本数据使用的;
//ES6 字符串方法:
//
// var a = ajax()//json
// a = JSON.parse(a);
// var str = a.str;
//
// if(str.startsWith('a')){
//
// }else{
//
// }
// 1. includes(str) : 判断是否包含指定的字符串
console.log(str.includes('1**2'));
// 2. startsWith(str) : 判断是否以指定字符串开头
console.log(str.startsWith('a'));
// 3. endsWith(str) : 判断是否以指定字符串结尾
console.log(str.endsWith('a'));
// 4. repeat(count) : 重复指定次数
console.log(str.repeat(-1));// 参数0空串 负数报错 正数 代表重复几次
</script>
数组方法
<script type="text/javascript">
//字符串是常量,无论字符串用什么方法,返回的字符串都不是原串,而是一个新的字符串;
//原串是无法更改的;
// var str = '123';
// var a = str.concat('iii');
// console.log(str,a);
//数组的方法,一定注意是返回的新数组还是在原数组做的改变;
var arr = [1000,22222222,33,100,4000];
//在数组末尾干活
// var result = arr.push(6,7,8,9,[1,2,3,4]);
// //功能:在数组的末尾添加元素,
// //参数:可以是一个,也可以是多个,甚至可以是一个或者多个数组
// //返回值:添加完元素之后,数组的新长度。这个方法会影响原数组的
// console.log(arr,result);
// var result = arr.pop();
// //功能:从数组的末尾删除一个元素
// //参数:无
// //返回值:返回删除的那个元素
// //会影响原数组
// console.log(arr,result)
//在数组头部干活
// var result = arr.unshift(200,300)
// //功能:在数组的头部添加元素,
//参数:可以是一个,也可以是多个,甚至可以是一个或者多个数组
//返回值:添加完元素之后,数组的新长度。这个方法会影响原数组的
// console.log(arr,result);
// var result = arr.shift();
// //功能:从数组的头部删除一个元素
//参数:无
//返回值:返回删除的那个元素
//会影响原数组
// console.log(arr,result);
//在数组中间干活
//splice方法比较恶心: 但是我们大家把这个方法理解为从中间删
// var result = arr.splice(1,1);
// //功能:删除对应的元素
// //参数:至少2个 第一个代表从哪开始删除 第二个代表删除几个
// //返回值:返回删除的元素组成的新数组
// //会影响原数组
// console.log(arr,result);
// var result = arr.splice(1,1,200,300,400);
// //功能:splice用于修改 ,先把要修改的位置的值删除,删除之后再在这个位置进行添加,可以添加一个也可以添加多个
// //参数:至少三个,第一个代表从哪开始,第二个代表删除几个,第三个开始往后都是新添加的元素;
// //返回值:返回删除的元素组成的新数组
// //会影响原数组
// console.log(arr,result);
//
// var result = arr.splice(1,0,200,300,400);
// //功能:splice用于增加 ,从起始位置删除0个,删除之后再在这个位置进行添加,可以添加一个也可以添加多个
// //参数:至少三个,第一个代表从哪开始,第二个代表删除0个,第三个开始往后都是新添加的元素;
// //返回值:空数组
// //会影响原数组
// console.log(arr,result);
//翻转数组
// var result = arr.reverse();
// //功能:翻转数组
//参数:无
//返回值:返回翻转后的原数组
会影响原数组
// console.log(result,arr);
// console.log(arr == result);
//拼接或者复制
// var result = arr.concat(1000,2000,[3000,4000]);
// //功能:拼接数组,没有参数其实就是复制一个数组
// //参数:可有可无,如果没有参数就是复制一个数组,有参数,会把参数拆成基本数据拼接到数组后面
// //返回值:返回拼接好的数组,而且是一个新数组,和原数组不是同一个;
// 不会影响原数组
// console.log(result,arr);
// console.log(result == arr);
//把数组元素按照执指定的连接符给连接成一个字符串 和字符串方法slite是逆运算
// var result = arr.join('**');//如果不传参数,默认以,作为连接符
// //功能:把数组元素按照指定的连接符给连接成一个字符串
// //参数:可有可无;如果没有,默认指定是的逗号作为连接符; 如果指定空串,元素之间不会有任何字符连接;如果指定其它字符串;
// //那么将会以其它字符串作为连接符把元素连接成字符串;
//
// //返回值;返回连接好的字符串
// //不会影响原数组;
// console.log(result,arr);
// var result = arr.slice(1,-1);
// //功能:和字符串slice方法类似,从原数组当中截取子数组
//参数:参考字符串方法
//返回值;返回截取好的新数组
//不会影响原数组;
// console.log(result,arr);
// var result = arr.sort(function(a,b){
// return a - b;
// });
// function fn(a,b){
// return a - b
// }
//功能:对数组进行排序;
//参数:无参就是按照Unicode吗进行比较进行排序
// 想要按照我们指定的去升序或者降序,必须传递一个回调函数
//返回值;返回排好序的原数组
//会影响原数组;
// console.log(arr,result);
// console.log(arr == result);
// console.log(arr.toString());//
//功能 数组自己的toString方法;会把数组转化为字符串,所有数组转化字符串
// 都是去掉两边中括号,中间的内容直接变为字符串
//参数:无
//返回值:转化好的字符串
//不会影响原数组;
console.log(arr);
</script>