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

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

赵大叔
赵大叔原创
2022年01月06日 21:57:12493浏览

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

  • 私有变量: 声明在函数内部的变量
  • 自由变量: 声明在函数外面,相对于私有变量
  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>
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议