六、对象

可以解决更复杂的问题

(一)基本概念

  • 定义:对象是一种数据类型,以键值对形式保存数据的一种数据类型且数据没有顺序;
  • 辅助理解:在程序中对象也是个容器,对象的容器中保存的就是各种数据(比数组的功能更强大)
  • 键值对:一个键就是一个值,例如:CSS代码就是一个键值对,即:属性:键 ———— color:red;

(二)使用方法

1、定义对象

  • 写法一(字面量写法)(推荐):let 自定义对象名 = {}
  • 写法二(构造函数写法)(了解):let 自定义对象名 = new Object()

2、对象保存数据的专业术语:属性+方法

对象中除了属性就是方法

  • 属性:在对象容器中用于描述对象基本特征的都叫属性(姓名,年龄,性别,肤色,身高,体重等),属性都是一个名词
  • 方法:在对象容器中用于描述对象具有的功能或者对象能干什么事情叫方法(会跳舞,会算卦等),方法都是函数

3、保存数据:

  • 通过定义属性保存属性值自定义属性名:值
  • 通过定义方法保存方法(函数)自定义方法名:function(形参){}

4、对象的使用:

  • 增:增加对象中的属性或方法
    • 增加属性:对象名['新增属性名']=值; 或者 对象名.新增属性名=值;
    • 增加方法:对象名['新增方法名'] = function(){} 或者 对象名.新增方法名 = function(){}
  • 删:(了解即可)
    • 删除属性:delete 对象名['属性名']=值; 或者 delete对象名.属性名=值;
    • 删除方法:delete 对象名['方法名'] 或者 delete 对象名.方法名
  • 改:修改数学中的值——本质上就是给对象中的属性或者方法重新赋值
    • 修改属性:对象名['属性名']=值; 或者 对象名.属性名=值;
    • 修改方法:对象名['方法名'] = function(){} 或者 对象名.方法名 = function(){}
  • 查:查询对象中的值(获取对象的属性+获取对象中的方法)
    • 查询属性:对象名['属性名'] 或者 对象名.属性名
    • 查询方法:对象名.方法名();
  • 总结:修改与新增的语法时一样的;若对象中有对应的属性或方法则表示修改,若对象中没有对应的属性或方法则表示新增

举例:操作对象的方法:增、删、改、查

// 代码:定义一个对象,其中有三个属性(username、age、height)和两个方法(study、read)
let Ricardo = {
  username: '李嘉图',
  age: 21,
  height: 175,
  study: function () {
    console.log('Ricardo is studying!');
  },
  read: function () {
    console.log('Ricardo is reading!');
  }
}

// 查:获取对象的属性、方法
// 查询对象中的属性
console.log(Ricardo.username);  // 李嘉图
// 查询对象中的方法
Ricardo.study();  // Ricardo is studying!
// 查询对象中不存在的属性或者方法
// 查询对象中不存在的属性
console.log(Ricardo.weight);   // undefined
// 查询对象中不存在的者方法
Ricardo.eat();   // 报错提示:Ricardo.eat is not a function
// 使用console.log()输出方法时返回undefined
console.log(Ricardo.study());   // undefined  Ricardo.study()是个函数,但是没有返回值,默认值为undefined

// 改:修改对象的属性值
// 将年龄age修改为22
console.log(Ricardo.age);  // 21
Ricardo.age = 22;
console.log(Ricardo.age);  // 22

// 增:增加对象中的数据
// 增加属性:sex = '男';
console.log(Ricardo.sex);  // undefined
Ricardo.sex = '男';
console.log(Ricardo.sex);  // 男
// 增加方法:console.log('Ricardo is sleeping!')
Ricardo.sleep;  // 报错提示:Ricardo.sex is not a function
Ricardo.sleep = function(){
    console.log('Ricardo is sleeping!');
}
Ricardo.sleep;  // Ricardo is studying!

// 删:删除属性/方法:delete 属性/方法
// 删除属性sex和方法sleep
delete Ricardo.sex;
delete Ricardo.sleep;

// 查询对象中的属性和方法 
console.log(Ricardo);

5、遍历对象

(1)基本使用

  • 语法:for(let 变量 in 要被遍历的对象){}
  • 语法解释:
    • for in 语法也是一个循环,循环次数会自动根据对象中的属性个数进行遍历,如三个属性的对象则循环三次,一个属性的对象则循环一次
    • for in 语法中的变量就是对象中的 属性名/方法名
    • 要被遍历的对象写在in后面
    • 获取对象中的值,必须通过 对象名[变量] 获取
    • 如果对象中同时出现属性与方法需要特殊处理
  • 总结:
    • 获取对象中的值必须通过 对象名[变量]  !!!
      • eg:Ricardo[变量名] == Ricardo[abc]
    • 不可以使用 对象名.变量 获取,否则获取值全为undefined 因为使用点的方式获取的是'对象'中属性为'变量'的值
      • eg:Ricardo.变量名 == Ricardo.abc
      • 对象中没有这个属性则得到的值为undefined

(2)举例

例1:将对象的每一个属性值都输入进控制台中
// 代码:定义一个对象,其中有三个属性(username、age、height)和一个方法(study)
let Ricardo = {
  username:'李嘉图',
  age:21,
  height:175,
  // 如果对象中同时出现属性与方法需要特殊处理
  study:function(){
    console.log('Ricardo is studying!');
  }
}
// 遍历对象
for (let abc in Ricardo) {
  // abc变量保存了对象中的所有属性名和方法名
  console.log(abc);  // username、age、height、study
  // 获取对象中的每一个属性对应的值
  console.log(Ricardo[abc]);  // 李嘉图、21、175
}
例2:要求将数组中值分别在控制台中输出
// 代码:学生数组中的每个元素都是对象
let students = [
  {name:'小明',age:18,gender:'男',hometown:'河北省'},
  {name:'小红',age:19,gender:'女',hometown:'河南省'},
  {name:'小刚',age:17,gender:'男',hometown:'山西省'},
  {name:'小丽',age:18,gender:'女',hometown:'山东省'}
];
for (let i = 0; i < students.length; i++) {
  // 输出学生数组中的每个对象
  console.log(students[i]);
  // 输出学生数组中的的姓名+年龄+性别
  console.log(`学生姓名:${students[i].name},学生年龄:${students[i].age},学生性别:${students[i].gender}`);
}
例3:要求根据所给定的数据在页面中渲染出一个学生信息的表格
// 代码:学生数组中的每个元素都是对象
let students = [
  {name:'小明',age:18,gender:'男',hometown:'河北省'},
  {name:'小红',age:19,gender:'女',hometown:'河南省'},
  {name:'小刚',age:17,gender:'男',hometown:'山西省'},
  {name:'小丽',age:18,gender:'女',hometown:'山东省'}
];
// 在页面中打印标签
document.write('<div class="students"><table>');
document.write('<th>序号</th><th>姓名</th><th>年龄</th><th>性别</th><th>家乡</th>');
for (let i = 0; i < students.length; i++) {
  // console.log(`姓名:${students[i].name},年龄:${students[i].age},性别:${students[i].gender},家乡:${students[i].gender}`);
  document.write('<tr>');
  document.write(`<td>${i+1}</td><td>${students[i].name}</td><td>${students[i].age}</td><td>${students[i].gender}</td><td>${students[i].hometown}</td>`);
  document.write('</tr>');
}
document.write('</table></div>');

(三)内置对象

对象是js中已经定义好了,只需要直接运行调用即可  eg:console.log();document.write();

1、Math

Math是JS中提供的"数学"对象,,即提供一系列做数学运算的方法,以下提供几种常用的Math方法:

  1. random:生成0~1之间的随机数(包括0,不包括1):Math.random();
    • 扩展使用:随机生成一个[N,M)之间的整数:Math.floor(Math.random() * (M - N + 1)) + N;
  2. ceil:向上取整,获取最近一个比当前值大的整数:Math.ceil(值);
  3. floor:向下取整,获取最近一个比当前值小的整数:Math.floor(值);
  4. max:找最大值:Math.max(值1,值2,值3,……);
  5. min:找最小值:Math.min(值1,值2,值3,……);
  6. pow:幂运算:Math.pow(底数,指数/幂);
  7. abs:绝对值:Math.abs(值);

举例

例1:把['赵云','黄忠','关羽','张飞','马超','刘备','曹操']随机一个名字显示在页面中
let arry = ['赵云','黄忠','关羽','张飞','马超','刘备','曹操'];
let random = Math.floor(Math.random() * arry.length);
document.write(arry[random]);
例2:随机点名器,把['张三','李四','王五','赵六','路人甲','炮灰乙','流氓丙','土匪丁']随机一个名字显示在页面中
let names = ['张三','李四','王五','赵六','路人甲','炮灰乙','流氓丙','土匪丁'];
// 代码待优化,因为会重复点到一个人
// let random = Math.floor(Math.random() * names.length);
// document.write(arry[random]);
// 改进方案:点完一个人就删一个人
// 代码缺陷:点完名之后会刷新页面,也就是前一次的删除操作没有保持到后一操作中,此处优化方法在WebAPI中
let random = Math.floor(Math.random() * names.length);
document.write(names[random]);
names.splice(random,1);
例3:程序随机生成 1~10 之间的一个数字,用户输入一个数字
let random = Math.floor(Math.random() * 9) + 1;
let num = +prompt("请输入一个1~10之间的整数:");
while(true){
  if (num % 1 !== 0 || num < 1 || num > 10) {
    alert("输入数字不符合规范!");
    num = +prompt("请输入一个1~10之间的整数:");
  }else{
    if (num > random) {
      alert("数字猜大了,继续猜。");
      num = +prompt("请输入一个1~10之间的整数:");
    }else if (num < random) {
      alert("数字猜小了,继续猜。");
      num = +prompt("请输入一个1~10之间的整数:");
    }else{
      alert("猜对了,程序结束。");
      break;
    }
  }
}
例4:程序随机生成颜色

I.预定义颜色red、green、blue等;
II.十六进制;
III.rgb(值,值,值)

// 输入标签,修改样式,渲染颜色

// 思路I.预定义颜色red、green、blue等(将颜色写死,不推荐)
let color1 = ['red','green','blue','yellow','pink'];
let randomColor1 = Math.floor(Math.random() * color1.length);
document.write(`<div class="test1" style="height:300px;width:300px;background-color:${color1[randomColor1]}"></div>`);
console.log(color1[randomColor1]);

// 思路II.十六进制;(将十六进制作为数组随机获取并组合成一个随机六位数从而达到#xxxxxx的效果)
let hexadecimal = [1,2,3,4,5,6,7,8,9,'a','b','c','d','e','f'];
// function getRandomNumber1(){
//   let randomColor2 = Math.floor(Math.random() * hexadecimal.length);
//   return hexadecimal[randomColor2];
// }
// let color2 = String(getRandomNumber1()) + String(getRandomNumber1()) + String(getRandomNumber1()) + String(getRandomNumber1()) + String(getRandomNumber1()) + String(getRandomNumber1());

// 代码优化:通过循环的方式获取六次随机数并拼接到一起组成十六进制的颜色表示
let color2 = "#";
for (let i = 0; i < 6; i++) {
  let randomColor2 = Math.floor(Math.random() * hexadecimal.length);
  color2 += hexadecimal[randomColor2];
}
document.write(`<div class="test1" style="height:300px;width:300px;background-color:${color2}"></div>`);
console.log(`${color2}`);

// 思路III.rgb(值,值,值)(随机获取三个0~255之间的数从而达到rgb(x,x,x)的效果)
// function getRandomNumber2(){
//   let randomColor3 = Math.floor(Math.random() * 255);
//   return randomColor3;
// }
// let color3 = String(getRandomNumber2()) + ',' + String(getRandomNumber2()) + ',' + String(getRandomNumber2());
// document.write(`<div class="test1" style="height:300px;width:300px;background-color:rgb(${color3})"></div>`);
// console.log(`rgb(${color3})`);  

// 代码优化:因为rgb只有三个数据,直接获取三个随机数并赋值给三个变量r、g、b
let r = Math.floor(Math.random() * 255);
let g = Math.floor(Math.random() * 255);
let b = Math.floor(Math.random() * 255);
document.write(`<div class="test1" style="height:300px;width:300px;background-color:rgb(${r},${g},${b})"></div>`);
console.log(`rgb(${r},${g},${b})`);

2、其他

详见JS高级笔记