欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

闭包的原理与经典应用场景 、访问器属性、类与对象的创建与成员引用 、数组与对象的解构、JS引入到浏览器中的的方法

程序员文章站 2022-05-29 12:49:11
...

闭包的原理与经典应用场景

  • 私有变量: 声明在函数内部的变量
  • *变量: 声明在函数外面,相对于私有变量
  1. let w = 100;
  2. let fn = function (x, y) {
  3. // x, y, z 都是私有变量
  4. // w 就是*变量
  5. let z = 50;
  6. return x + y + z +w;
  7. }
  8. console.log(fn(1, 2));

闭包

    1. 父子函数;2. 子函数调用了父函数中的变量
  • 优点: 父函数调用完成,因为内部子函数引用了父函数参数, 所以父函数创建的作用域不消失;可用于分块获取服务器大量数据, 参数分批传入
  • 缺点: 大量使用闭包,父函数调用后作用域不消失,占用内存
  1. cha = function (a) {
  2. // a = 10;
  3. // 1. 父子函数, f: 子函数
  4. let con = function (b) {
  5. // b = 20;
  6. return a + b;
  7. };
  8. // 2. 返回一个子函数
  9. return con;
  10. };
  11. let f = cha(10);
  12. // cha()调用完成,因为内部的a被子函数con引用, 所以fn()创建的作用域不消失
  13. console.log(typeof f);
  14. console.log(f(20));
  15. // 闭包的应用-偏函数(高阶函数的一种)
  16. // 当一个函数需要多个参数的时候,不一定一次性全部传入,可以分批传入
  17. // 将参数逐个传入, 叫"柯里化"函数,可用于分块获取服务器大量数据, 参数分批传入
  18. fn = function (a, b, c) {
  19. return a + b + c;
  20. };
  21. console.log(fn(1, 2, 3));
  22. console.log(fn(1, 2));
  23. fn = function (a, b) {
  24. return function (c) {
  25. return a + b + c;
  26. };
  27. };
  28. // 使用闭包, 可以将三个参数分2次传入
  29. f = fn(1, 2);
  30. console.log(f(3));
  31. // 能不能分3次
  32. fn = function (a) {
  33. return function (b) {
  34. return function (c) {
  35. return a + b + c;
  36. };
  37. };
  38. };
  39. console.log(fn(1)(2)(3));
  40. // 将上面的柯里化函数,改为箭头函数
  41. fn = a => b => c => a + b + c;
  42. console.log(fn(1)(2)(3));

反闭包: 纯函数

  • 纯函数: 函数中用到的变量全间自己的, 没有”*变量”
  • 如果函数内部必须要用到外部变量,通过参数传入
  1. // 反闭包: 纯函数
  2. // 纯函数: 函数中用到的变量全间自己的, 没有"*变量"
  3. // 如果函数内部必须要用到外部变量,通过参数传入
  4. // 外部变量
  5. let discound = 0.8;
  6. function getPrice(price, discound = 1) {
  7. // 纯函数中禁用有*变量
  8. return price * discound;
  9. }
  10. console.log(getPrice(12000, discound));

访问器属性

  • 访问器属性: 进行属性伪装, 将方法伪装成属性进行访问
  • 虽然是访问属性的形式, 但实际上调用的是方法
  1. // 访问器属性
  2. let aadg = {
  3. ovrn: { qkob: "qqpgfhfm", wwov: 1800 },
  4. getwwov() {
  5. return this.ovrn.wwov;
  6. },
  7. setwwov(wwov) {
  8. if (wwov >= 5000 && wwov <= 800) {
  9. this.ovrn.wwov = wwov;
  10. } else {
  11. console.log("人数不符合生产规模!!!");
  12. }
  13. },
  14. };
  15. console.log(aadg.ovrn.qkob, aadg.ovrn.wwov);
  16. console.log(aadg.getwwov());
  17. aadg.setwwov(60);
  18. console.log(aadg.getwwov());
  19. // 根据用户习惯, 访问属性=>undefined
  20. // 读
  21. // console.log(aadg.wwov);
  22. // 写
  23. // aadg.wwov = wwov;
  24. // 进行属性伪装, 将一个方法伪装成属性进行访问
  25. aadg = {
  26. ovrn: { qkob: "qqpgfhfm", wwov: 1800 },
  27. get wwov() {
  28. return this.ovrn.wwov;
  29. },
  30. set wwov(wwov) {
  31. if (wwov >= 800 && wwov <= 5000) {
  32. this.ovrn.wwov = wwov;
  33. } else {
  34. console.log("人数不符合生产规模!!!");
  35. }
  36. },
  37. };
  38. // 读
  39. console.log(aadg.wwov);
  40. // 写
  41. aadg.wwov = 2000;
  42. console.log(aadg.wwov);
  43. // 访问器属性: 看上去我们访问的是属性, 实际上调用的是方法

类与对象的创建与成员引用

  • 通过构造函数创建对象
  • 通过实例化类创建对象

构造函数

  • 对象方法一般是公共, 操作的是当前对象的属性
  • 任何一个函数都有一个属性, 叫原型, 这个原型,对于普通函数来说没用,只有把函数当成构造函数来创建对象时, 原型属性才有用
  • 给类构造函数添加自定义方法,必须添加到它的原型对象属性上
  • 声明在构造函数原型上的方法, 被所有类实例/对象所共用
  • 静态成员: 直接挂载到构造函数对象上的属性,构造函数.静态成员来调用
  1. // 类与对象
  2. // 构造函数执行过程
  3. Car = function (color, model) {
  4. // 1. 创建一个新对象
  5. // let this = new Car;
  6. // 2. 给新对象添加自定义的属性
  7. this.color = color;
  8. this.model = model;
  9. // 3. 返回 这个新对象
  10. // return this;
  11. // 以上, 1, 3 都是new的时候,自动执行, 不需要用户写
  12. };
  13. const car1 = new Car("red", "small");
  14. console.log(car1);
  15. const car2 = new Car("green", "big");
  16. console.log(car2);
  17. // 对象方法一般是公共, 操作的是当前对象的属性
  18. // 任何一个函数都有一个属性, 叫原型, 这个原型,对于普通函数来说,没用
  19. // 只有把函数当成构造函数来创建对象时, 这个原型属性才有用
  20. console.log(Car.prototype, typeof Car.prototype);
  21. // 给类User添加自定义方法,必须添加到它的原型对象属性上
  22. // 声明在 User.prototype原型上的方法, 被所有类实例/对象所共用
  23. Car.prototype.getInfo = function () {
  24. return `color = ${this.color}, model = ${this.model}`;
  25. };
  26. console.log(car1.getInfo());
  27. console.log(car1.getInfo());
  28. // 静态成员: 直接挂载到构造函数对象上的属性
  29. Car.status = "da ban";
  30. console.log(Car.status);
  31. // 私有成员
  32. Car = function (color, model, seats) {
  33. // 私有变量
  34. let seat = seats;
  35. this.color = color;
  36. this.model = model;
  37. console.log(seat);
  38. };
  39. const car3 = new Car("vang", "track", "16");
  40. console.log(car3);

类:ES6 才有

  • 传统的基于构造函数的类与对象,语法上非常的复杂, 对于从其他语言转到 js 来的同学来说, 不友好
  1. // ES6, class
  2. class Mobilephone {
  3. // 公共字段(可选)
  4. brand = "huawei";
  5. ram = "16G";
  6. // 私有成员,像id一样,前面加#号
  7. #baohanh = "2";
  8. // 构造方法
  9. constructor(name, price, thoigian) {
  10. this.name = name;
  11. this.price = price;
  12. this.#baohanh = thoigian;
  13. }
  14. // 公共方法: 原型
  15. getInfo() {
  16. return `name = ${this.name}, price = ${this.price}, baohanh=${this.#baohanh}`;
  17. }
  18. // 静态成员
  19. static status = "kichhoat";
  20. }
  21. const mobilephone1 = new Mobilephone("mate-12", "8000", "2");
  22. console.log(mobilephone1.getInfo());
  23. // 继承, 为了扩展
  24. class Mobile extends Mobilephone {
  25. constructor(name, price, thoigian, pecent) {
  26. super(name, price, thoigian,);
  27. // 子类中的新属性
  28. this.pecent = pecent;
  29. }
  30. getInfo() {
  31. return `${super.getInfo()}, pecent = ${this.pecent}`;
  32. }
  33. }
  34. const mobilephone2 = new Mobile("mete20", "10000", "5", 50);
  35. console.log(mobilephone2.getInfo());
  36. // 在类中可以使用访问器属性
  37. // 在类中可以使用访问器属性
  38. class Maytinh {
  39. #nam = 0;
  40. get nam() {
  41. return this.#nam;
  42. }
  43. set nam(nam) {
  44. if (nam >= 0 && nam <= 10) {
  45. this.#nam = nam;
  46. } else {
  47. console.log("非法数据");
  48. }
  49. }
  50. }
  51. let stu = new Maytinh();
  52. console.log(stu.nam);
  53. stu.nam = 5;
  54. console.log(stu.nam);

数组与对象的解构

  • 暂且理解为用一个模板将数组和对象中元素一一对应起来
  • 两数交换
  • 对象解构传参数

数组解构

  1. const user = ["朱老师", "498668472@qq.com"];
  2. let userName = user[0];
  3. let userEmail = user[1];
  4. console.log(userName, userEmail);
  5. // es6: 解构, 将以上操作变得非常简单
  6. // 1. 数组解构
  7. // 模板 = 数组
  8. let [iPhone, price] = ["13", "10000"];
  9. console.log(iPhone, price);
  10. [iPhone, price] = ["14", "20000"];
  11. console.log(iPhone, price);
  12. // 参数不足, 默认参数
  13. [iPhone, price, year = 2021] = ["12", "8000"];
  14. console.log(iPhone, price,year);
  15. // 参数过多, ...rest
  16. let [a, b, c, ...d] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  17. console.log(a, b, c, d);
  18. // 二数交换
  19. let x = 100;
  20. let y = 200;
  21. console.log([x, y]);
  22. [y, x] = [x, y];
  23. console.log([x, y]);

对象解构

  1. // 对象模板 = 对象字面量
  2. let { msnv, attence, kpi} = { msnv: 900117, attence: 27, kpi: 1250 };
  3. console.log(msnv, attence, kpi );
  4. // 大括号 不能出现在等号左边, {}不能充当"左值", 使用括号包一下转为表达式就可以了
  5. ({msnv, attence, kpi}) = {msnv: 900118, attence: 20, kpi: 1500};
  6. console.log(msnv, attence, kpi);
  7. // 当左边模板中的变量出现命名冲突,使用别名解决
  8. let { msnv:msnvjv, attence:attencet12, kpi:kpi12 } = { msnv: 3, attence: 27, kpi: 800 };
  9. console.log(msnvjv, attencet12, kpi12);
  10. // 克隆对象
  11. let {...obj} ={msnv: 900118, attence: 20, kpi: 1500};
  12. console.log(obj);
  13. // 3. 应用场景
  14. function getUser(user) {
  15. console.log(user.msnv,user.attence,user.kpi);
  16. }
  17. // 用对象解构传参
  18. function getUser({msnv, attence, kpi}) {
  19. console.log(msnv, attence, kpi);
  20. }
  21. getUser({msnv = 900117, attence = 27, kpi = 1500})

JS 引入到浏览器中的方法

  • js 的工作环境/宿主环境: 浏览器, 服务器 node.js
  • js 可写到元素的事件属性
  • 绑定 js 函数,函数代码写在<script></script>
  • <script>标签src属性中引入 JS 文档
  1. <body>
  2. <!-- js的工作环境/宿主环境: 浏览器, 服务器 node.js -->
  3. <!-- 1. 事件属性, 写到元素的事件属性 -->
  4. <button onclick="alert('hello help_10086');">按钮1</button>
  5. <!-- 2. 事件属性, 写到元素的事件属性 -->
  6. <button onclick="setBg(this)">按钮2</button>
  7. <script>
  8. // 使用script标签引入js脚本, 写到这对标签中, 仅于当前的html文档
  9. function setBg(ele) {
  10. document.body.style.backgroundColor = "wheat";
  11. ele.style.backgroundColor = "yellow";
  12. ele.textContent = "保存成功";
  13. }
  14. </script>
  15. <!-- 3. 如果这个按钮的功能, 需要在多个页面中使用, 可以将这个js脚本保存为外部脚本,然后再引入到当前的html -->
  16. <!-- <script src="outer.js"></script> -->
  17. </body>

获取 DOM 元素实例演示

    1. 一组: querySelectorAll(css 选择器)
    1. 一个(一组中第 1 个): querySelector(css 选择器)
  1. <body>
  2. <ul class="list">
  3. <li class="item">item1</li>
  4. <li class="item">item2</li>
  5. <li class="item">item3</li>
  6. <li class="item">item4</li>
  7. <li class="item">item5</li>
  8. </ul>
  9. <script>
  10. // 1. 一组: querySelectorAll(css选择器)
  11. // 2. 一个(一组中第1个): querySelector(css选择器)
  12. // 1. 将所有的item变成红色
  13. // html怎么表示?
  14. console.log(document);
  15. const items = document.querySelectorAll(".list > .item");
  16. console.log(items);
  17. for (let i = 0, length = items.length; i < length; i++) {
  18. items[i].style.fontSize = "30px";
  19. }
  20. // items.forEach(item => (item.style.color = "green"));
  21. // 2. 将第一个改为黄色背景
  22. const thunhat = document.querySelector(".list > .item");
  23. console.log(thunhat === items[0]);
  24. thunhat.style.backgroundColor = "yellow";
  25. const three = document.querySelector(".list > .item:nth-of-type(3)");
  26. three.style.backgroundColor = "wheat";
  27. // 3. 快捷方式
  28. // body
  29. console.log(document.querySelector("body"));
  30. console.log(document.body);
  31. //head
  32. console.log(document.head);
  33. // title
  34. console.log(document.title);
  35. // html
  36. console.log(document.documentElement);
  37. </script>
  38. </body>