博客列表 >js 急速入门之二

js 急速入门之二

培(信仰)
培(信仰)原创
2021年01月11日 23:38:32533浏览

js 急速入门之二

值传递与引用传递

  1. // 1. 赋值
  2. // 1.1 值传递:原始类型(string,number,bool)
  3. let a = 1;
  4. let b = a;
  5. console.log("a=%d,b=%d", a, b);
  6. a = 2;
  7. console.log("a=%d,b=%d", a, b);
  8. // 1.2 引用传递:引用类型(object,array)
  9. let obj1 = { a: 1, b: 2 };
  10. console.log(obj1);
  11. let obj2 = obj1;
  12. obj1.a = 2;
  13. console.log(obj2);
  14. // 引用类型指向的是相同内存地址
  15. // 2. 传参
  16. // 传参时,不论什么类型,都是“值传递”
  17. const f1 = (x) => (x = 10);
  18. let m = 5;
  19. f1(m);
  20. // 入参:调用函数时传入的参数,简称:入参
  21. // 函数中对参数的更新,并不会影响到入参
  22. console.log("m = %d", m);
  23. const f2 = (x) => (x.a = 10);
  24. let o = { a: 1, b: 2 };
  25. f2(o);
  26. console.log(o);
  27. // 看上去函数中对于o.a的更新生效,实际上只是值传递
  28. // 对于引用类型,只有全新赋值才算是更新,修改属性不算。
  29. const obj = { x: 1, y: 2 };
  30. obj.x = 20;
  31. // 函数中对于对象参数/引用参数的更新并没有影响
  32. // 深拷贝:值传递
  33. // 浅拷贝:引用传递

模板字面量与标签函数

  1. // 1. 模板字面量:将表达式嵌入字符串中
  2. let a = 1,
  3. b = 2;
  4. let res = a + " + " + b + " = " + (a + b);
  5. console.log(res);
  6. // 模板字面量使用反应“`”
  7. res = `${a} + ${b} = ${a + b}`;
  8. console.log(res);
  9. // 模板字面量的组成:
  10. // 1. 字符串字面量:“+,=”
  11. // 2. 变量或表达式:a,b,(a + b)
  12. let menu = ["首页", "视频", "文章"];
  13. let htmlStr = `<ul>
  14. <li><a href="">${menu[0]}</a></li>
  15. <li><a href="">${menu[1]}</a></li>
  16. <li><a href="">${menu[2]}</a></li>
  17. </ul>`;
  18. console.log(htmlStr);
  19. document.body.insertAdjacentHTML("beforeend", htmlStr);
  20. // document.body.insertAdjacentHTML("beforebegin",htmlStr);
  21. // 2. 标签函数:自定义模板字面量的行为
  22. // 遍历,加样式,动态渲染,放到迭代器中循环
  23. // let hello = name => alert(name);
  24. // hello("朋友");
  25. // hello`朋友`;
  26. // 模板字面量可以当参数使用,函数调用的小括号都可以不写
  27. // 使用自定义函数处理模板字面量,他的参数约定
  28. // 1. 第一个参数:模板字面量中的字符串字面量组成的数组
  29. // 2. 从第二个参数开始,将模板字面量中的变量依次传入
  30. let sum = (strs, a, b) => {
  31. console.log(strs);
  32. console.log(a, b);
  33. };
  34. sum(["+", "=", ""], a, b);
  35. sum`${a} + ${b} =`;
  36. sum = (strs, ...args) => {
  37. console.log(strs);
  38. console.log(args);
  39. };
  40. sum`${a}+${b} = `;

解构赋值

  1. //解构赋值:快速从集合中(数组/对象)解构出独立变量
  2. //1. 数组
  3. let [a, b, c] = [1, 2, 3];
  4. console.log(a, b, c);
  5. [a, b] = [1, 2, 3];
  6. console.log(a, b);
  7. [a, b, c, d] = [1, 2, 3];
  8. console.log(a, b, c, d);
  9. // 还可以使用默认值
  10. [a, b, c, d = "xxx"] = [1, 2, 3];
  11. console.log(a, b, c, d);
  12. // 取部分值,其他值通过rest语法压入数组
  13. [a, b, ...c] = [1, 2, 3, 4, 5];
  14. console.log(a, b, c);
  15. // 想拿到固定位置的值
  16. [, , a, ,] = [1, 2, 3, 4, 5];
  17. console.log(a);
  18. // 两个值交换
  19. let x = 1,
  20. y = 2;
  21. // let t
  22. // t = x;
  23. // x = y;
  24. // y = t;
  25. // console.log(x,y);
  26. [y, x] = [x, y];
  27. console.log(x, y);
  28. // 2. 对象解构
  29. let { id, name } = { id: 10, name: "phone" };
  30. console.log(id, name);
  31. // 属性名与变量名必须对应,顺序无所谓
  32. //当变量名冲突时,可以使用别名
  33. let email = "admin@php.cn";
  34. let { role, email: userEmail } = { role: "user", email: "user@php.cn" };
  35. console.log(userEmail);
  36. console.log(email);
  37. // 3. 参数解构
  38. // 数组传参
  39. let sum = ([a, b]) => a + b;
  40. console.log(sum([10, 20]));
  41. //对象传参
  42. let getUser = ({ name, email }) => [name, email];
  43. console.log(getUser({ email: "tp@php.cn", name: "TP" }));

总结:太好用了。
注意:结构数量不完全匹配的时候,如何接解构的值

  1. [, , a, ,] = [1, 2, 3, 4, 5];

对象字面量的简化

  1. let user = {
  2. userName: 'tp',
  3. userEmail: 'tp@php.cn',
  4. getInfo:function() {
  5. return `${this.userName} ( ${this.userEmail} )`;
  6. }
  7. }
  8. console.log(user.getInfo());
  9. let {userName,userEmail}=user;
  10. console.log(userName,userEmail);
  11. user = {
  12. // 当属性名与同一个作用域中的变量名向同时
  13. // 可以直接使用属性名来引用该变量的值
  14. // userName:userName,
  15. // userEmail:userEmail,
  16. userName,
  17. userEmail,
  18. // getInfo:function() {
  19. // return `${this.userName} ( ${this.userEmail} )`;
  20. // }
  21. // 方法也可以简化
  22. getInfo() {
  23. return `${this.userName} ( ${this.userEmail} )`;
  24. }
  25. // getInfo:()=>
  26. // return `${this.userName} ( ${this.userEmail} )`;
  27. }
  28. console.log("简化后",user.getInfo());
  29. //箭头函数中的this总是指向定义它的作用域(静态作用域/词法作用域),并非调用是的作用域
  30. // js中,只有函数和块才能创建作用域
  31. // user对象不能创建作用域 此时的this指向了上user的作用域/作用域链;
  32. // 全局没有userName,userEmail,所以输出 undefined。

认识bind,call,apply

  1. <button>click</button>
  2. <script>
  3. // function f1() {}
  4. // console.dir(f1);
  5. // bind,call,apply定义在原型上的方法
  6. function hello(name) {
  7. this.name = name;
  8. console.log(this.name);
  9. }
  10. const obj = {
  11. name: "admin",
  12. // hello(name) {
  13. // this.name = name;
  14. // console.log(this.name);
  15. // },
  16. // 代码冗余
  17. };
  18. //经典调用
  19. console.log(hello("hi 你好"));
  20. //bind()不会立即执行,只返回一个函数声明
  21. // 将hello()这个函数绑定到obj对象上,第二个参数是hello的参数
  22. let f = hello.bind(obj, "tp");
  23. console.log(f());
  24. // call / apply 立即执行
  25. //将hello()这个函数绑定到obj对象上,第二个是hello的参数
  26. f = hello.call(obj, "xx");
  27. console.log(f);
  28. //使用apply第二个参数要是数组
  29. f = hello.apply(obj, ["yy"]);
  30. console.log(f);
  31. //bind()应用案例:动态改变this
  32. document.querySelector("button").addEventListener(
  33. "click",
  34. function () {
  35. console.log(this.name);
  36. console.log(this);
  37. document.body.appendChild(document.createElement("p")).innerHTML="欢迎"+this.name;
  38. }.bind({ name: "新对象" })
  39. );

总结:bind不会立即执行,call 和 apply 立即执行 其中apply 要求第二个参数是数组
使用此三个方法的好处是可以动态改变this指向,相应的也会是代码可读性变差。

访问器属性

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

总结:感觉很重要的样子。

访问器属性的优先级

  1. // let user = {
  2. // name: "phone",
  3. // get name() {
  4. // return "HUAWEI";
  5. // },
  6. // set name(value) {
  7. // this.name = value;
  8. // },
  9. // };
  10. //访问器属性优先级高于同名的普通属性
  11. // console.log(user.name);
  12. // 怎么解决普通属性与访问器属性重名问题?
  13. let user = {
  14. data:{name},
  15. get name() {
  16. return this.data.name;
  17. },
  18. set name(value) {
  19. this.data.name = value;
  20. },
  21. };
  22. user.name = "HUAWEI";
  23. console.log(user.name);

总结:开发中尽量避免访问器属性与不同属性重名。

流程控制-分支

  1. // let score = 64;
  2. //单分支
  3. // if (score >= 60) {
  4. // console.log("及格");
  5. // }
  6. // let score = 54;
  7. // // 双分支
  8. // if (score >= 60) {
  9. // console.log("及格");
  10. // //默认分支
  11. // } else {
  12. // console.log("补考");
  13. // }
  14. let score = 100;
  15. // 双分支
  16. if (score >= 60 && score < 80) {
  17. console.log("合格");
  18. //默认分支
  19. } else if (score >= 80 && score <= 100) {
  20. console.log("学霸");
  21. } else if (score > 100 || score < 0) {
  22. console.log("非法数据");
  23. } else {
  24. console.log("补考");
  25. }
  26. // switch 来简化多分支
  27. // 只要是区间一定要用true,switch是严格匹配
  28. score = 70;
  29. switch (true) {
  30. case score >= 60 && score < 80:
  31. console.log("合格");
  32. break;
  33. case score >= 80 && score <= 100:
  34. console.log("学霸");
  35. break;
  36. case score > 100 || score < 0:
  37. console.log("非法数据");
  38. break;
  39. default:
  40. console.log("补考");
  41. }
  42. // 一般区间判断不用switch,用if更直观
  43. // switch 一般用做单值判断
  44. let response = 'Success';
  45. switch (response.toLowerCase()) {
  46. case 'fail':
  47. console.log("请求失败");
  48. break;
  49. case 'success':
  50. console.log("请求成功");
  51. break;
  52. default:
  53. console.log("未知错误");
  54. }
  55. // 三元运算符
  56. // 条件 ? true: false;
  57. // if (score >= 60) {
  58. // console.log("及格");
  59. // //默认分支
  60. // } else {
  61. // console.log("补考");
  62. // }
  63. console.log(score >= 60 ? "及格" : "补考");

总结:作为重要内容。三元运算符简化了双分支条件语句。熟练运用可以简化代码,看起来更优雅。
值判断尽量使用switch,如果是区间判断一定要使用true作为条件。

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议