js对象

277 阅读6分钟

1.对象是什么?

是一种以键值对方式存储复杂数据类型

2.对象的相同点和不同点:

相同点:都可以存储多个数据
不同点:存储方式不同
数组:有序存储. 下标从0开始递增
*应用:存储相同类型的数据
对象:无序存储.属性名和属性值是一一对应(键值对)
*应用:存储不同类型的数据
数组一般存储相同数据类型的数据
如果使用数组来存储不同数据类型的数据阅读性不高
对象一般存储数据类型不同的数据
  需求: 存储一个人的信息  (姓名,年龄,性别)

    //1.使用基本数据类型来存储
    //(1)弊端:冗余,维护不便
    //(2)好处: 阅读性高
    let name = '班长'
    let age = 38
    let sex = '男'

    //2.使用复杂数据类型:数组
    //(1)好处: 一个变量存储多个数据
    //(2)弊端: 阅读性不高
    let arr = ['班长',38,'男']
    console.log(arr)

    //3.使用对象 : 存多个 + 阅读性高
    let obj = { name:'班长',age:38,sex:'男' }
    console.log(obj)
    

3.对象语法

    1.声明对象  
        let 对象名 = {
            属性名:属性值,
            属性名:属性值,
        }

    2.取值语法
        对象名.属性名

    3.细节:  对象里面的属性是什么类型, 取出来的时候就可以使用它的语法
          
      3.1 如果对象里面属性是'数组',就可以使用数组语法:  对象名.属性名[下标]
      3.2 如果对象里面的属性是'函数',就可以使用函数语法:  对象名.方法名()
      3.3 如果对象里面的属性是'对象',就可以使用对象语法:  对象名.属性名.属性名

  如果对象中的属性值是函数对象,我们一般称呼为对象方法
    
    

4.案例

    需求: 自己声明一个对象,要求存储 :字符串类型、数字类型、数组类型、函数类型、对象类型,
           并且打印每一种类型的数据。如果是函数,则调用
    let obj = {
        name: '张三',
        age: 18,
        hoppy: ['学习', '上课', '敲代码'],
        eat: function () {
            console.log('123')
        },
        friend: {
            name: '李四',
            age: 18
        }
    }
    console.log(obj.name);//张三
    console.log(obj.age + 1)//19
    console.log(obj.hoppy[0])//学习
    obj.eat()//123
    console.log(obj.friend.name)//李四
    
    细节:  对象里面的属性是什么类型, 取出来的时候就可以使用它的语法
         console.log(obj.age + 1)//19
         console.log(obj.name + 1)//张三1
    

image.png

5.查对象属性

       1.查询对象特点
        1.1 如果属性名存在,则获取属性值
        1.2 如果属性名不存在,则获取undefined
    2.查询对象属性两种语法
        点语法       obj.属性名
        []语法       obj['属性名']    obj[ 变量名 ] 
    3.总结 : 
            如果[]内部有引号, 则解析为属性名
            如果[]内部没有写引号,则解析为变量名 
    
    let obj = {
        name: '张三',
        age: 18,
        sex: '男'
    }
    //1.点语法:  对象名:属性名
    如果属性名存在,则获取属性值
    console.log(obj.name); //'张三'
    如果属性名不存在,则获取undefined
    console.log(obj.firend); //undifed

    //2.字符串语法:   对象名['属性名']   对象名[变量名]
    //如果中括号有引号,则会解析当成属性名   
    console.log(obj['name']); //'张三'

    // 如果中括号没有引号,则会解析当成变量名  
    let age = 'sex'
    //这里 obj[age] 没有加引号,所以age解析为变量名. age变量中存储的是"sex"
    //1.取age变量值:'sex'   2.取对象值:obj['sex']
    console.log(obj[age]); //男
    //这里 obj['age']有引号,所以age解析为属性名。 相当于obj.age
    console.log( obj['age'] )//18

6.查询对象测试

 /* 
    1.点语法:  对象名.属性名
    2.[]语法: 对象名[ '属性名' ]   对象名[ 变量名 ]
    
    如果 [] 里面有字符串, 则解析成属性名
    如果 [] 里面没有字符串,则解析成变量名
    */
    let obj = {
        name:'班长',
        age:20,
        sex:'男',
    }
    
    let aaa = 'name'
    let bbb = 'aaa'
    let sex = 'age'

    console.log( obj.sex )//男
    console.log( obj['sex'] )//男
    console.log( obj[sex] )//20

    console.log( obj.aaa )//undefined
    console.log( obj['aaa'] )//undefined
    console.log( obj[aaa] )//班长

    console.log( obj.bbb )//undefined
    console.log( obj['bbb'] )//undefined
    console.log( obj[bbb] )//undefined

    console.log( obj.age )//20
    console.log( obj['age'] )//20
    //[] 里面没有字符串,所以age解析为变量名。  而没有声明age,所以报错变量未声明
    console.log( obj[age] )//报错 age is not defined
    

7.新增对象以及查询对象的方法:

    const goods = {
       uname: '小米8',
       num: '100123',
       weight: '0.55kg',
       address: '中国大陆'
      }
//查询对象
//方法一:
console.log(goods.num)//100123    
//方法二:
console.log(goods['num'])//100123
// 修改对象
goods.uname = '小米10'
console.log(goods.uname)//小米10
// 新增对象
goods.color = 'pink'
console.log(goods.color)
console.log(goods)
    

image.png

   let obj = {
        name:'张三',
        age:20,
        sex:'男'
    }

    //1.修改属性
    obj.name = '李四'
    
    console.log( obj )

    //2.新增属性
    /* 
    2.1 如果对象属性名存在,则是修改属性值
    2.2 如果对象属性名不存在,则是新增属性
    */
    obj.score = 90
    console.log( obj )

    //3.删除属性:  delete 对象名.属性名
    delete obj.age
    console.log( obj )
    

image.png

8.对象里面的方法传参

   const person = {
     name: 'andy',
     sayHi: function (jump) {
        document.write('你好' + jump)
     },
      sing: function () {

      },
    dance: function () {

   }
 }
console.log(person)
person.sayHi('我是程序员')

image.png

9.对象操作(新增与修改)

     1.修改属性
        对象名.属性名   = 值
        对象名['属性名'] = 值
     2.新增属性
        (1)如果已经存在的属性赋值,则是修改
        (2)如果不存在的属性赋值,则是新增
     3.删除对象属性
        delete 对象性.属性名
    */
    let obj = {
        name: '张三',
        age: 18,
        sex: '男'
    }
    //对象赋值(新增与修改):对象名.属性名=值    对象名['属性名']=值
    //如果属性存在,则修改操作
    obj.sex = '女'

    //如果属性名不存在,则新增属性
    obj.girlFriend = '小明'
    console.log(obj);

    //删除属性:delete 对象名.属性名
    delete obj.age
    console.log(obj); //{name: '张三'sex: '女', obj.girlFriend : '小明'}
    

10.遍历对象

         1.遍历数组: 固定for循环
         for(let i = 0;i< arr.length;i++){   arr[i] }
  
         2.遍历对象 : 特殊的for-in循环  (专用于遍历对象)
          for(let key in 对象名){ 对象名[key] }
  
      let obj = {
      name: '张三',
      age: 18,
      sex: '男',
      score: 99
     }
   由于对象没有长度,没有下标.所以不能使用for(let i = 0;i<长度;i+){}
   js作者为了解决对象遍历问题,单独设计了一种全新的循环.for-in循环
    for (let key in obj) {
     console.log(key); //属性名
     console.log(obj[key]); //属性值
    }
    

image.png

image.png

案例:

   const goods = {
                  uname: '小米8',
                  num: '100123',
                  weight: '0.55kg',
                  address: '中国大陆'
                } 
  for (const k in goods) {
           console.log(goods[k]);
    }
    

11. 根据数组对象生成表格

  <style>
     table {
        width: 800px;
        height: 60px;
        text-align: center;
        border-collapse: collapse;
        margin:200px auto;
     }
     table,
     tr,
     th,
     td {
        border: 1px solid skyblue;
     }
</style>
</head>
<body>
      <script>
 let arr = [    { name: "小明", age: 18, gender: "男", hometown: "河北省" },    { name: "小红", age: 19, gender: "女", hometown: "河南省" },    { name: "小刚", age: 17, gender: "男", hometown: "山西省" },    { name: "小丽", age: 18, gender: "女", hometown: "山东省" }  ]
    document.write('<table>')
    document.write('<tr><th>序号</th><th>姓名</th><th>年龄</th><th>性别</th><th>籍贯</th></tr>')
   for(let i = 0; i< arr.length; i++){
    document.write(`<tr>
        <td>${ i+1}</td>
        <td>${arr[i].name}</td>
        <td>${arr[i].age}</td>
        <td>${arr[i].gender}</td>
        <td>${arr[i].hometown}</td>
        </tr>`)
   
   }
   document.write('</table>')
</script>

image.png

注: arr[0]表示可以取到数组中第一个元素, arr[0].name 表示可以取到第一个对象里面的name属性值

image.png

12.内置对象

       1.内置对象 : 由js作者提前写好的对象,我们直接拿来使用即可
      * 说人话 : 相当于手机内置应用,如短信、电话。 一买来就自带的,直接使用
       2. Math:数学对象
 

image.png

     绝对值:abs
     console.log(Math.abs(-10)); //10
     向上取整Math.ceil(数字)
      console.log(Math.ceil(11.6)); //12
      console.log(Math.ceil(-11.6)); //-11
      console.log(Math.ceil(1.4)); //2
       向下取整Math.floor
       console.log(Math.floor(1.6)); //1
       console.log(Math.floor(11.6)); //11
       console.log(Math.floor(-11.6)); //-12
      求数组最大值Math.max(数字1,数字2,数字3...)
      console.log(Math.max(60, 70, 80, 90, 100)) //100
      求数组最小值Math.min(数字1,数字2,数字3...)
      console.log(Math.min(60, 70, 80, 90, 100)) //60
      //求100-255整数  0-155
      console.log(  Math.ceil( Math.random()*155 ) +100 )
  
**求0-1随机小数
console.log(Math.random()); //0.2536987256**
0-100随机整数
      console.log(Math.ceil(Math.random() * 100)); //随机整数
      幂运算: Math.pow(x,y)  求x的y次方
      console.log( Math.pow(2,3) )//2 * 2 * 2 = 8
      
      

注:如果最大值Math里面加了不能识别的数字或字母,则会出现NaN

      console.log(Math.max(10, 20, 30, 40, 'asc')); //NaN
      
      

13.案例

       需求:封装一个函数,返回一个随机颜色  rgb(255,255,255)
    function getColor(){
       let r = parseInt( Math.random()*256 )
       let g = parseInt( Math.random()*256 )
       let b = parseInt( Math.random()*256 )
       return `rgb(${r},${g},${b})`
   }

   console.log( getColor() )
   console.log( getColor() )
   console.log( getColor() )

14.案例

    需求:封装一个函数,返回一个随机颜色  #ffffff
    (1)第一种方法:
      function getHexColor() {
        let str = '#'
        for (let i = 1; i <= 6; i++) {
            str = str + parseInt(Math.random() * 16).toString(16)
        }
        return str
    }
    console.log(getHexColor());
    console.log(getHexColor());
    console.log(getHexColor());
  
  (2)第二种方法:
  
    //十六进制 :  六位 0-f之间的字母数字
  function getColor() {
    //声明数组存储 0-f每一次字符
    let arr = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
    //使用累加和思路: 生成六次数组随机下标元素,然后拼接到str中
    let str = '#'
    for(let i = 1;i<=6;i++){
        let index = parseInt( Math.random()*16 )
        str += arr[index]
    }
    return str
  }

  console.log(getColor())
  console.log(getColor())
  console.log(getColor())
    

image.png

15.案例

    猜谜游戏:生成一个1-100之间的随机整数让用户猜
    如果用户猜大了或者猜小了,提示用户,直到用户猜对位置

第一种方法:

    let randomNum = Math.ceil(Math.random() * 100)
       console.log(randomNum)
    while (true) {
      let num = +prompt('请输入一个数字')
      if (randomNum > num) {
      alert('你猜小了,请继续猜')
       } else if (randomNum < num) {
       alert('你猜大了,请继续猜')
       } else {
        alert(`你猜对了, 幸运数字是${randomNum}`)
       break
      }
    }
      console.log("用户猜对了,循环结束")
      
      

第二种方法

   function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值 
  }
    // 生成1-10的随机数
      const num = getRandom(1, 100)
    while (true) {
   //输入对应的数字
      const index = +prompt('请输入一个数字')
       if (index > num) {
       alert('你猜大了')
     } else if (index < num) {
        alert('你猜小了')
     } else {
        alert('你猜对了')
       break
     }
   }

16.引用类型 与 值类型

    引用类型 与 值类型 区别 
   
     1.值类型(简单数据类型) :  string  number boolean undefined null
    * 栈中存储数据,赋值拷贝的也是数据,修改拷贝后的数据对原数据‘没有影响’

      2.引用类型(复杂数据类型) : array function object
       栈中存储地址,数据存在堆中。赋值拷贝的是地址,修改拷贝后的数据对元素‘有影响’

       1.值类型
       let num1 = 20
       拷贝num1的数据给num2
        let num2 = num1
       修改num2的数据
        num2 = 10
        console.log(num2, num1) //10 20

        2.引用类型
        let arr1 = [10, 20, 30]
        拷贝arr1的数据给arr2
        let arr2 = arr1
        修改arr2的数据
        arr2[0] = 100
        console.log(arr1, arr2) //[100,20,30]   [100.20.30]
        

image.png

image.png

image.png

堆栈空间分配区别

1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。
   其操作方式类似于数据结构中的栈
简单数据类型存放到栈里面
2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
引用数据类型存放到堆里面,引用类型( array function object )他们在相互比较时,只比较地址, 不会比较数据 ,所以
    let arr1 = [10,20,30]
   //拷贝arr1的地址  赋值给 arr2
   let arr2 = arr1
   arr2[0] = 100
   console.log( arr1,arr2)//[100,20,30]  [100,20,30]
   let a1 = []
   let a2 = []
   console.log(a1 == a2 )//false
        

17.封装函数,生成10到30之间的随机数

   function getRandom(min, max) {
      return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值 
  }
    const num = getRandom(10, 30)
    console.log(num);
    
    

image.png

18.随机点名案例

需求:请把 [‘赵云’, ‘黄忠’, ‘关羽’, ‘张飞’, ‘马超’, ‘刘备’, ‘曹操’] 随机显示一个名字到页面中
function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值 
  }
    const arr = ['赵云', '黄忠', '关羽', '张飞', '马超', '刘备', '曹操', '大乔', '孙尚香']
    const index = getRandom(0, arr.length - 1)
    document.write(arr[index]);
    arr.splice(index, 1)

19.猜数字游戏,设定次数,最多猜8次

    function random(min, max) {

  return Math.floor(Math.random() * (max - min + 1)) + min
}
    // 生成一个数字先,猜0-20之间的数
      let num = random(0, 20)

      let flag = true
   // 最多猜8次
       for (let i = 1; i <= 8; i++) {

     let userNum = prompt('请输入您要猜的数字')

      // 比较数字
       if (userNum > num) {

          alert('您猜的数字大了')
      } else if (userNum < num) {

         alert('您猜的数字小了')
      } else {
         flag = false
        alert('恭喜猜对了!')
         break
     }
    }

      if (flag) {
         alert('太笨了,这都猜不到!O(∩_∩)O')
     }

20.案例:

 <!-- 导入css -->
 <link rel="stylesheet" href="./style.css" />
 </head>
 <body>
  <div class="box w">
    <div class="box-hd">
    <h3>精品推荐</h3>
  </div>
  <div class="box-bd">
    <ul class="clearfix">
      <!-- <li>
        <img src="images/course01.png" alt="" />
        <h4>
          Think PHP 5.0 博客系统实战项目演练
        </h4>
        <div class="info">
          <span>高级</span> • <span> 1125</span>人在学习
        </div>
      </li> -->
        
      <script>
                let data = [
            {
              src: 'images/course01.png',
              title: 'Think PHP 5.0 博客系统实战项目演练',
              num: 1125
            },
            {
              src: 'images/course02.png',
              title: 'Android 网络动态图片加载实战',
              num: 357
            },
            {
              src: 'images/course03.png',
              title: 'Angular2 大前端商城实战项目演练',
              num: 22250
            },
            {
              src: 'images/course04.png',
              title: 'Android APP 实战项目演练',
              num: 389
            },
            {
              src: 'images/course05.png',
              title: 'UGUI 源码深度分析案例',
              num: 124
            },
            {
              src: 'images/course06.png',
              title: 'Kami2首页界面切换效果实战演练',
              num: 432
            },
            {
              src: 'images/course07.png',
              title: 'UNITY 从入门到精通实战案例',
              num: 888
            },
            {
              src: 'images/course08.png',
              title: 'Cocos 深度学习你不会错过的实战',
              num: 590
            }
          ]

          //需求:根据对象数组生成多个li元素
          for(let i =0;i<data.length;i++){
            document.write(`<li>
            <img src="${ data[i].src }" alt="" />
            <h4>
              ${ data[i].title }
            </h4>
            <div class="info">
              <span>高级</span> • <span> ${data[i].num}</span>人在学习
            </div>
           </li>`)
          }
            </script>
    </ul>
    </div>
    </div>
    </body>
    

image.png