十、函数补充以及初识对象
1.arguments
arguments对象里面保存这方法的所有参数。arguments对象里面有个一个callee方法,该方法指向当前方法本身。
定义稳定的递归函数:
function calc(num){
if(num===1){
return num
}
// 因为arguments.callee 就时 指向当前方法本身。
// 这样的做的好处是,防止外部方法名修改后,导致递归调用失效。
let sum = num + arguments.callee(num-1)
return sum
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>arguments</title>
</head>
<body>
<script>
function fn1(a,b,c){
//方法在调用时,如果没有传递实参,形参的值是undefined
console.log(a,b,c);
// arguments是函数内部的一个内置对象
// arguments对象里面保存这方法的所有参数
// arguments对象里面有个一个callee方法,该方法指向当前方法本身
console.log(arguments);
let sum = 0
for(let i=0;i<arguments.length;i++){
sum += arguments[i]
}
return sum
}
let sum = fn1(100,200,300,400,500,600)
console.log(sum);
console.log('----------------------------');
// 计算1-20之间所有数的求和
function calc(num){
if(num===1){
return num
}
// arguments.callee指向当前方法本身
// 所以,在写递归算法时会经常使用。
return num + arguments.callee(num-1)
}
console.log(calc(20));
</script>
</body>
</html>
2.分页方法
//定义一个分页方法,方法的三个参数分别是:原始数组,页码,每页数量
function pageData(arr,pageIndex,pageSize){
//思路:就是对原始数组中的数据,做截取
//定义截取数据的起始位置
let start = (pageIndex-1)*pageSize
//定义截取数据的结束位置
let end = start+pageSize
return arr.slice(start,end)
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>分页方法</title>
</head>
<body>
<script>
// 定义一个数组
let arr = [11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999]
// 每页3条数据,返回第3页数据
let r1 = arr.slice(6,9)
console.log(r1);
// 每页4条数据,返回第4页数据
let r2 = arr.slice(12,16)
console.log(r2);
// 没有5条数据,返回第3页数据
let r3 = arr.slice(10,15)
console.log(r3);
console.log('------------------------');
// 定义一个分页方法,参数是:数组,页码,每页数量
function pageData(arr,pageIndex,pageSize){
let start = (pageIndex-1)*pageSize //算出起始下标
let end = start+pageSize //算出结束下标
//根据起始下标和结束下标,从原始数组中截取对应的数据并返回
return arr.slice(start,end)
}
console.log(pageData(arr,3,3));
console.log(pageData(arr,4,4));
console.log(pageData(arr,3,5));
</script>
</body>
</html>
3.初识对象
如果 a.b ,那么a就是对象,b是a的属性。如果 a.c(),那么a就是对象,c是a的方法。对象就是拥有一组属性和方法的集合。
定义对象有两种方式:1.采用字面量赋值方式直接定义。2.采用构造函数的方式new一个对象
1.采用字面量赋值方式定义对象
let obj = {
//定义属性
//定义方法
}
通过对象名.属性,调用对象的属性,可以获取属性的值,也可以修改属性的值,也可以添加新的属性。通过对象名.方法(),调用对象的方法,执行方法里面的代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>对象</title>
</head>
<body>
<script>
// 对象就是拥有一组属性和方法的集合
// 如果 a.b ,那么a就是对象,b是a的属性
// 如果 a.c(),那么a就是对象,c是a的方法
// 定义对象的第一种方式:采用字面量赋值方式直接定义
let stu1 = {
//属性名:属性值的方式,定义属性
no:1001,
name:'张三',
age:20,
sex:'男',
//定义学生的方法
study:function(){
console.log('每天学习8小时');
},
play:function(){
console.log('每天玩8小时');
}
}
console.log(stu1);
//调用对象身上的属性
console.log(stu1.name);
console.log(stu1.age);
//调用对象身上的方法
stu1.study()
stu1.play()
</script>
</body>
</html>
案例:定义计算器对象,实现加减乘除。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>使用对象制作计算器</title>
</head>
<body>
<script>
//定义一个计算器对象
let calc = {
//定义计算器的属性
num1:0,
num2:0,
//定义计算器的方法
jia:function(){
//在对象的方法中,获取对象的其它成员,要通过this
console.log(`${this.num1}+${this.num2}=${this.num1+this.num2}`);
},
//在SE6中,对象的方法,也可以采用下面的方式
jian(){
console.log(`${this.num1}-${this.num2}=${this.num1-this.num2}`);
},
cheng(){
console.log(`${this.num1}*${this.num2}=${this.num1*this.num2}`);
},
chu(){
console.log(`${this.num1}/${this.num2}=${this.num1/this.num2}`);
}
}
//给计算器对象的两个属性赋值
calc.num1 = 200
calc.num2 = 20
calc.jia()
calc.jian()
calc.cheng()
calc.chu()
</script>
</body>
</html>
2.采用构造函数的方式new一个对象
可以直接new一个Object对象
let obj = new Object()
也可以定义一个构造函数,再出new这个构造函数的对象。构造函数也称为:类,是自定义的一种类型。
//定义学生类
function Student(形参...){
//定义属性(必须使用this.)
//定义方法(必须使用this.)
}
//创建学生对象
let s1 = new Student(实参...)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>构造函数</title>
</head>
<body>
<script>
// 构造函数:首先是个函数,这个函数用来创建出对象
// 如果使用构造函数创建出对象:使用new关键字。
// 可以使用系统构造函数Object创建一个对象。效果等同于{}
let obj1 = new Object()
console.log(obj1);
let obj2 = {}
console.log(obj2);
console.log('--------------------------------');
// 多数情况下,都是先自定义一个构造函数,再通过自定义的构造函数创建出对应的对象
// 可以将构造函数理解成:类
function Student(no,name,age,sex){
//这里的this,用于给构造函数定义成员
this.no = no
this.name = name
this.age = age
this.sex = sex
this.sayHi = function(){
console.log(`大家好!我叫${this.name}`);
}
}
// 通过类(构造函数)可以创建出无数个对象
let s1 = new Student(1001,'张三',20,'男')
console.log(s1);
s1.sayHi()
let s2 = new Student(1002,'李四',22,'女')
console.log(s2);
s2.sayHi()
let s3 = new Student(1003,'王五',24,'男')
console.log(s3);
s3.sayHi()
</script>
</body>
</html>
练习题:
定义一个棋子类,里面有四个属性,分别是:名称,颜色,X轴位置,Y轴位置
比如:红色的马,当前位置是(X=15,Y=11) 里面有两个方法:分别是:
1.显示当前棋子在什么位置
2.移动方法,该方法,需要传两个参数,就是X轴和Y轴的新坐标,移动方法执行完后,在方法的最下面,调用一次显示当前位置的方法。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>构造函数练习</title>
</head>
<body>
<script>
// 定义一个棋子构造函数(类)
function Chess(name,color,x,y){
//定义属性
this.name=name
this.color=color
this.x=x
this.y=y
//定义方法
//显示当前位置的方法
this.show=function(){
console.log(`${this.color}${this.name},当前位置是X:${this.x} Y:${this.y}`);
}
//移动棋子的方法
this.move=function(x,y){
this.x = x
this.y = y
//位置更新后,重新调用显示当前位置的方法
this.show()
}
}
// 创建一个红马
let redHorse = new Chess('马','红',15,1)
redHorse.show()
redHorse.move(13,2)
//创建一个黑车
let blackCar = new Chess('车','黑',1,1)
blackCar.show()
blackCar.move(5,1)
</script>
</body>
</html>