JavaScript学习之路(五)

JS学习

一、面向对象的实例

  <script>
    let user={
      name:"Emily",
      grade:[
        {name:"js",score:99},
        {name:"css",score:76},
      ],
      average(){
        let total=this.grade.reduce((t,l)=>t+l.score,0);
        return `${this.name}的平均成绩是:${total/this.grade.length}`;
      },
    }
      console.log(user.average());
  </script>

输出:

Emily的平均成绩是:87.5

二、属性的基本操作

1、两种获取属性的方法对比:

  <script>
    let user={
      name:"Emily",
      age:18,
    };
    console.log(user.name);
    console.log(user["age"]);
  </script>

在有些情况下只能使用第二种方法:
属性名有空格时:

  <script>
    let user={
      name:"Emily",
      age:18,
      "my weight":80
    };
    console.log(user["my weight"]);//正确
    //console.log(user.my weight);//红线
  </script>

遍历属性时:

  <script>
    let user={
      name:"Emily",
      age:18,
      "my weight":80
    };
    for(const key in user){
      console.log(key,user[key]);//正确
      //console.log(key,user.key);//"user.key"undefined
    }
  </script>

2、动态添加/删除属性

  <script>
    let user={
      name:"Emily",
      age:18,
      "my weight":80
    };
    user.sex="女";//添加变量
    user.get=function(){//添加方法
      return `${this.name}的性别是${this.sex}`;
    }
    console.log(user.get());
    delete user.get;//删除方法
    console.log(user.get());
  </script>

输出:

Emily的性别是女
Uncaught TypeError: user.get is not a function
    at test1.html:20

三、对象的引用传址

函数的参数传递对比:
基本数据类型,传值
在函数内部改变参数的值不会改变外部的值:

  <script>
    let user=1;
    function show(a){
      a+=100;
      console.log(a);
    }
    show(user);
    console.log(user);
  </script>

输出:

101
1

对象类型,传址
在函数内部改变参数的值会引起外部的值的改变:

  <script>
    let user={
      age:100,
    };
    function show(a){
      a.age=18;
      console.log(a);
    }
    show(user);
    console.log(user);
  </script>

输出:

{age: 18}
{age: 18}

四、使用展开语法完成参数合并

1、展开语法在数组中的使用:

  <script>
    let arr=[1,2,3];
    let a=[...arr,5,6,7];
    console.log(a);
  </script>

输出:

(6) [1, 2, 3, 5, 6, 7]

2、展开语法在对象中的使用:

  <script>
    let user={name:"Emily",age:18};
    let a={...user,sex:"女"};
    console.log(a);
  </script>

输出:

{name: "Emily", age: 18, sex: "女"}

3、多个展开语法的使用:

  <script>
    function upload(params){
      let config={
        type:"*.png",
        size:1000
      };
      config={...config,...params};
      //config=Object.assign(config,params);//使用Object.assign更方便
      console.log(config);
    }
    upload({size:99,type:"*,gif"});
  </script>

输出:

type: "*,gif", size: 99}

当params中有config中的key时,会将config中的键值覆盖;没有的话会在config中添加。
如果将params和config的顺序反过来,config会将params中的键值覆盖。

五、解构赋值

1、对象的解构赋值(定义)

  <script>
    let user={name:"Emily",age:18};
    let {name:a,age:b}=user;
    console.log(a,b);
  </script>

输出:

Emily 18

如果将name,age分别用同名参数保存:

    let {name:name,age:age}=user;

简写为:

    let {name,age}=user;

2、对象的解构赋值(返回值)

  <script>
    function show(){
      return {name:"Emily",age:18};
    }
    let {name,age}=show();
    console.log(name,age);
  </script>

输出同上。
3、对象的解构赋值(传参)

  <script>
    function user({name,age}){
      console.log(name,age);
    }
    user({name:"Emily",age:18});
  </script>

输出同上。
4、Math也是一个数据,接收它的部分key:

  <script>
    let {random}=Math;
    console.log(random());//产生随机数
  </script>

效果同下:

  <script>
    console.log(Math.random());//产生随机数
  </script>

5、严格模式下的解构
必须使用声明语句来进行解构赋值

六、对象与原型链属性检测

1、数组检测
使用hasOwnProperty只能检测当前对象有无该属性;
但是使用in还会追溯到父级:

  <script>
    "use strict";
    let arr=[1,2,3];
    console.log(arr.hasOwnProperty("length"));
    console.log(arr.hasOwnProperty("concat"));
    console.log("length" in arr);
    console.log("concat" in arr);
  </script>

输出:

true
false
true
true

2、对象检测
a->b->c

  <script>
    "use strict";
    let a={name:"Emily"};
    let b={age:18};
    let c={sex:"女"};
    Object.setPrototypeOf(b,c);//把c设为b的原型
    Object.setPrototypeOf(a,b);//把b设为a的原型
    console.log(a.hasOwnProperty("sex"));
    console.log("sex" in a);
  </script>

输出:

false
true

in会一直检测到原型链顶端。

七、数组转对象

  <script>
    "use strict";
    let lessons=[
      {title:"数据结构",teacher:"王老师"},
      {title:"算法设计",teacher:"李老师"},
      {title:"操作系统原理",teacher:"杨老师"},
      {title:"计算机网络",teacher:"周老师"},
    ];
    let res=lessons.reduce((obj,cur,index)=>{
      obj[`${cur.teacher}-${index+1}`]=cur;
      return obj;
    },{});
    console.log(lessons);
    console.log(JSON.stringify(res,null,2));
  </script>

输出:

[
  {
    "title": "数据结构",
    "teacher": "王老师"
  },
  {
    "title": "算法设计",
    "teacher": "李老师"
  },
  {
    "title": "操作系统原理",
    "teacher": "杨老师"
  },
  {
    "title": "计算机网络",
    "teacher": "周老师"
  }
]
{
  "王老师-1": {
    "title": "数据结构",
    "teacher": "王老师"
  },
  "李老师-2": {
    "title": "算法设计",
    "teacher": "李老师"
  },
  "杨老师-3": {
    "title": "操作系统原理",
    "teacher": "杨老师"
  },
  "周老师-4": {
    "title": "计算机网络",
    "teacher": "周老师"
  }
}

八、遍历操作与DOM绘制

  <script>
    "use strict";
    let lessons=[
      {title:"数据结构",teacher:"王老师"},
      {title:"算法设计",teacher:"李老师"},
      {title:"操作系统原理",teacher:"杨老师"},
      {title:"计算机网络",teacher:"周老师"},
    ];
    let ul=document.createElement("ul");
    for(const lesson of lessons){
      let li=document.createElement("li");
      li.innerHTML=`课程:${lesson.title},老师:${lesson.teacher}`;
      ul.appendChild(li);
    }
    document.body.appendChild(ul);
  </script>

在这里插入图片描述

九、对象的浅拷贝

只拷贝一层,如果第一层有数组或者对象,址引用
1、循环遍历

  <script>
    "use strict";
    let lessons={title:"数据结构",teacher:{name:"王老师",sex:"男"}};
    let obj={};
    for(const key in lessons){
      obj[key]=lessons[key];
    }
    obj.teacher.name="杨老师";
    obj.category="软件工程";
    console.log(JSON.stringify(lessons,null,2));
    console.log(JSON.stringify(obj,null,2));
  </script>

输出:

  "title": "数据结构",
  "teacher": {
    "name": "杨老师",
    "sex": "男"
  }
}
test1.html:15 {
  "title": "数据结构",
  "teacher": {
    "name": "杨老师",
    "sex": "男"
  },
  "category": "软件工程"
}

修改obj的teacher的属性影响到了lessons的teacher。
2、Object.assign,这种方式更简单

  <script>
    "use strict";
    let lessons={title:"数据结构",teacher:{name:"王老师",sex:"男"}};
    let obj=Object.assign({},lessons);
    obj.teacher.name="杨老师";
    obj.category="软件工程";
    console.log(JSON.stringify(lessons,null,2));
    console.log(JSON.stringify(obj,null,2));
  </script>

输出同上。
3、展开语法,这种方式也不错

  <script>
    "use strict";
    let lessons={title:"数据结构",teacher:{name:"王老师",sex:"男"}};
    let obj={...lessons};
    obj.teacher.name="杨老师";
    obj.category="软件工程";
    console.log(JSON.stringify(lessons,null,2));
    console.log(JSON.stringify(obj,null,2));
  </script>

输出同上。

十、深拷贝

多层递归拷贝,每层的数组或者对象都重新开辟空间值引用

  <script>
    "use strict";
    let lessons={title:"数据结构",teacher:{name:"王老师",sex:"男"}};
    function copy(obj){
      let res=obj instanceof Array?[]:{};
      for(const [key,value] of Object.entries(obj)){
        res[key]=typeof value=="object"?copy(value):value;
      }
      return res;
    }
    let obj=copy(lessons);
    obj.teacher.name="杨老师";
    obj.category="软件工程";
    console.log(JSON.stringify(lessons,null,2));
    console.log(JSON.stringify(obj,null,2));
  </script>

输出:

{
  "title": "数据结构",
  "teacher": {
    "name": "王老师",
    "sex": "男"
  }
}
{
  "title": "数据结构",
  "teacher": {
    "name": "杨老师",
    "sex": "男"
  },
  "category": "软件工程"
}

修改obj的teacher的属性不会影响到lessons的teacher。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值