PHP8.1.21版本已发布
vue8.1.21版本已发布
jquery8.1.21版本已发布

博客列表 > 细说(值传递、引用传递)的区别, 数组和对象解构的常用方法, call.apply.bind的区别与联系, 访问器属性的原理与实现

细说(值传递、引用传递)的区别, 数组和对象解构的常用方法, call.apply.bind的区别与联系, 访问器属性的原理与实现

lus菜
lus菜 原创
2021年01月07日 16:32:54 770浏览

值传递与引用传递的区别与联系:

  1. 深拷贝:
  2. 值传递: 原始类型,string,number,bool
  3. 引用传递: 引用类型,object,array
  4. 浅拷贝: 引用传递
  5. 入参:调用函数是传入的参数,简称:"入参"

样式代码:

  1. <script>
  2. let a = 1; //赋值、值传递:原始类型,string,number,bool
  3. console.log("a = %d, b = %d", a, b);
  4. a = 2;
  5. console.log("a = %d, b = %d", a, b); //更新a,不影响b
  6. let obj1 = { a: 1, b: 2 }; //引用传递:引用类型,object,array
  7. console.log(obj1);
  8. let obj2 = obj1;
  9. console.log(obj2);
  10. obj1.a = 10; // 更新obj1
  11. console.log(obj1);
  12. console.log(obj2); //obj2同步更新
  13. const f1 = (x) => (x = 10); //传参时,不论什么类型,都是"值传递"
  14. let m = 5;
  15. console.log("m = %d", m);
  16. f1(m);
  17. console.log("m = %d", m); //函数中对参数的更新,并不会影响到入参
  18. const f2 = (x) => (x.a = 10);
  19. let o = { a: 1, b: 2 };
  20. console.log(o);
  21. f2(o);
  22. console.log(o); //看上去函数中对于o.a的更新生效,实际上仍是值传递
  23. const obj = { x: 1, y: 2 }; //对于引用类型,只有全新赋值才算是更新,修改属性不算的
  24. obj.x = 20;
  25. const f3 = (x) => (x = {}); // 赋值一个全新对象,才是更新
  26. f3(o);
  27. console.log(o); // 函数中对于对象/引用参数的更新并没有影响到入参
  28. </script>

效果预览:

数组和对象解构的常用方法与函数传数:

  1. 解构赋值: 快速从集合数据(数组/对象解构出独立变量)
  1. <script>
  2. let [a, b, c] = [1, 2, 3]; //数组
  3. console.log(a, b, c);
  4. [a, b] = [1, 2, 3];
  5. console.log(a, b);
  6. [a, b, c, d = "xxxx"] = [1, 2, 3];
  7. console.log(a, b, c, d);
  8. [a, b, ...c] = [1, 2, 3, 4, 5];
  9. console.log(a, b, c);
  10. [, , a, ,] = [1, 2, 3, 4, 5];
  11. console.log(a);
  12. let x = 1,
  13. y = 2,
  14. t;
  15. console.log("x = %d, y = %d", x, y);
  16. [y, x] = [x, y];
  17. console.log("x = %d, y = %d", x, y);
  18. let { id, name } = { id: 10, name: "手机" }; //对象解构
  19. console.log(id, name);
  20. ({ name, id } = { id: 10, name: "手机" }); //属性名与变量名必须一一对应,顺序无所谓
  21. console.log(id, name);
  22. let email = "admin@php.cn";
  23. let { role, email: userEmail } = { role: "user", email: "user@php.cn" };
  24. console.log(userEmail);
  25. console.log(email);
  26. //参数解构
  27. let sum = ([a, b]) => a + b; //数组传参
  28. console.log(sum([10, 20]));
  29. let getUser = ({ name, email }) => [name,email]; // 对象传参
  30. console.log(getUser({ email: "tp@php.cn", name: "老师" }));
  31. </script>

效果预览:

bind,call,apply的区别与联系:

  1. bind()不会立即执行,只返回一个函数声明
  2. call/apply立即执行

样式代码:

  1. <body>
  2. <button>click</button>
  3. <script>
  4. function hello(name) {
  5. this.name = name;
  6. console.log(this.name);
  7. }
  8. const obj = { name: "admin" };
  9. //经典调用
  10. console.log(hello("朱老师"));
  11. //bind()不会立即执行
  12. let f = hello.bind(obj, "天蓬老师");
  13. console.log(f());
  14. //call/apply立即执行
  15. f = hello.call(obj, "灭绝老师");
  16. console.log(f);
  17. f = hello.apply(obj, ["西门老师"]);
  18. console.log(f);
  19. </script>
  20. </body>

效果预览:

访问器属性的原理与实现过程:

  1. 将方法伪造成一个属性

样式代码:

  1. <script>
  2. const product = {
  3. data: [
  4. { name: "电脑", price: 5000, num: 5 },
  5. { name: "手机", price: 4000, num: 10 },
  6. { name: "电视", price: 9000, num: 4 },
  7. ],
  8. get total() { // 将方法伪造成一个属性
  9. return this.data.reduce((t, c) => (t += c.price * c.num), 0);
  10. },
  11. set setPrice(price) {
  12. this.data[1].price = price;
  13. },
  14. };
  15. console.log("总金额 :", product.total);
  16. console.log(product.data[1].price);
  17. product.setPrice = 9988;
  18. console.log(product.data[1].price);
  19. </script>

访问器属性的优先级:

  1. 访问器属性优先级高于同名的普通属性
  1. <script>
  2. let user = {
  3. data: { name },
  4. get name() {
  5. return this.data.name;
  6. },
  7. set name(value) {
  8. this.data.name = value;
  9. },
  10. };
  11. user.name = "今天天气真不错";
  12. console.log(user.name);
  13. </script>

多分支与swithc转换的技巧:

  1. score = 90; //多分支
  2. if (score >= 60 && score < 80) {
  3. console.log("合格");
  4. } else if (score >= 80 && score <= 100) {
  5. console.log("学霸");
  6. }
  7. else if (score > 100 || score < 0) { // 判断成绩是否合法
  8. console.log("非法数据");
  9. } else {
  10. console.log("补考吧");
  11. }
  12. score = 90; //switch来简化多分支时,switch是严格匹配
  13. switch (true) {
  14. case score >= 60 && score < 80:
  15. console.log("合格");
  16. break;
  17. case score >= 80 && score <= 100:
  18. console.log("学霸");
  19. break;
  20. case score > 100 || score < 0: //判断成绩是否合法
  21. console.log("非法数据");
  22. break;
  23. default:
  24. console.log("补考吧");
  25. }
  26. let response = "Success"; // switch用在单值判断
  27. switch (response.toLocaleLowerCase()) {
  28. case "fail":
  29. console.log("请求失败");
  30. break;
  31. case "success":
  32. console.log("请求成功");
  33. break;
  34. default:
  35. console.log("未知错误");
  36. }
  37. </script>

效果预览:

三元运算符:

  1. 简化双分支:条件? true : false
  2. 如果为真执行第一个分支,
  3. 如果为假执行第二个分支,
  4. 三元运算符会将:右边的视为一个整体,其优先级应该是很低的,如果要先求三元运算符中的顺,必须先将其用括号括起来:
  1. <script>
  2. //双分支
  3. score = 60;
  4. console.log(score >= 60 ? "及格" : "补考吧");
  5. </script>
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议