#JavaScript(进阶)

一,作用域

目录

一,作用域

1.1,局部作用域

1.2,全局作用域

1.3,作用域链

1.4,js垃圾回收机制

1.5,闭包

1.6,变量提升

二,函数进阶

2.1,函数提升

2.2,函数参数

 2.3,展开运算符

2.4,箭头函数 

​编辑

 2.5,箭头函数参数

2.6,箭头函数的this

三,解构赋值 

3.1,数组解构

3.2,对象解构

渲染案例

综合案例:

补充 Filter方法:

三,方法

内置构造函数

案例:

四,面向对象编程

1.2,数组扩展最大值和求和方法

1.3,总结

1.4,原型继承

1.5,原型链

综合案例


1.1,局部作用域

函数作用域:

 块作用域

1.2,全局作用域

1.3,作用域链

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    let a = 1
    let b = 2
    function f() {
      let a = 1
      console.log(a);

      function g() {
        // let a = 2
        console.log(a);
      }
      g()
    }
    f()
  </script>
</body>

</html>

思考上面的结果

1.4,js垃圾回收机制

引用计数法 :

标记清除法:

1.5,闭包

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    function outer() {
      let a = 10
      function fn() {
        console.log(a);
      }
       return fn
    }
    const func = outer()
    func()
  </script>
</body>

</html>

 

闭包  就无法修改这个变量了

总结:

1.6,变量提升

二,函数进阶

2.1,函数提升

  <script>
    //会把所有函数声明提升到当前作用域的最qianmian
    //只提升函数声明  不提升函数调用
    fn()
    function fn() {
      console.log('函数提升');
    }
//函数表达式必须先声明后调用
  </script>

2.2,函数参数

动态参数:(伪数组)

function foo() {
  for (var i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}

foo('Hello', 'World', '!');

剩余参数:(真数组)

function sum(...numbers) {
  let total = 0;
  for (let number of numbers) {
    total += number;
  }
  return total;
}

console.log(sum(1, 2, 3)); // 输出 6
console.log(sum(4, 5, 6, 7, 8)); // 输出 30


动态参数是指在定义或调用函数时,不需要指定参数的个数和名称,而是可以根据实际情况传递任意数量和类型的参数。js中有两种常用的方式来处理动态参数:arguments对象和剩余参数语法。

arguments对象是一个类数组对象,它包含了传给函数的所有实参,无论是否有对应的形参。arguments对象可以通过索引访问每个实参的值,也可以通过length属性获取实参的个数。arguments对象还有一些其他的属性和方法,例如callee属性和caller属性等。arguments对象只在函数内部有效,可以用来实现一些高级的功能,例如递归调用、重载等。

剩余参数语法是ES6引入的一种新特性,它使用扩展运算符(...)来收集动态参数并将其存储在一个数组中。剩余参数语法可以让我们将一个不定数量的参数表示为一个数组,而不需要使用arguments对象。剩余参数只包含那些没有对应形参的实参,而arguments对象包含了传给函数的所有实参。剩余参数是一个真正的数组,可以直接使用所有的数组方法,例如sort、map、forEach或pop等。

动态参数和剩余参数语法都可以让我们更灵活地定义和调用函数,但它们也有一些区别和注意事项。以下是一些示例代码和网页链接,你可以参考学习:

•  使用arguments对象处理动态参数https://bing.com/search?q=js%E4%B8%AD%E5%8A%A8%E6%80%81%E5%8F%82%E6%95%B0%E5%92%8C%E5%89%A9%E4%BD%99%E5%8F%82%E6%95%B0&form=SKPBOT:

// 定义一个函数,不指定形参
function dynamicParams() {
// 使用arguments对象迭代输出所有传递的参数
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}

// 调用函数,传递任意数量和类型的实参
dynamicParams(1, 2, 3); // 输出 1 2 3
dynamicParams("a", "b", "c"); // 输出 a b c
dynamicParams(true, false, null, undefined); // 输出 true false null undefined

•  使用剩余参数语法处理动态参数https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters:

// 定义一个函数,使用扩展运算符收集剩余参数
function dynamicParams(...args) {
// args是一个数组,可以直接使用数组方法
args.forEach(function (element) {
console.log(element);
});
}

// 调用函数,传递任意数量和类型的实参
dynamicParams(1, 2, 3); // 输出 1 2 3
dynamicParams("a", "b", "c"); // 输出 a b c
dynamicParams(true, false, null, undefined); // 输出 true false null undefined

•  剩余参数 - JavaScript | MDNhttps://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters:这是一个介绍剩余参数语法的网页,它有详细的概述、语法、描述、示例和规范等内容。

•  js动态参数arguments和剩余参数、展开运算符https://blog.csdn.net/lxllxl211/article/details/129359549:这是一篇博客文章,它介绍了js中动态参数、剩余参数和展开运算符的概念、用法和区别等内容。


 2.3,展开运算符

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    const arr = [1, 2, 3]
    //展开运算符
    // console.log(...arr);

    console.log(Math.max(...arr));
  </script>
</body>

</html>

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    const arr1 = [1, 2, 3]
    //展开运算符
    // console.log(...arr);
    //  求数组最大值
    console.log(Math.max(...arr));
    //  合并数组
    const arr2 = [3,4,5]
    const arr = [...arr1,...arr2]
    console.log(arr);
  </script>
</body>

</html>


  

展开运算符(spread operator)是一种用三个点(...)表示的语法,它可以将一个可迭代的对象(如数组、字符串、集合等)在某处展开,变成多个参数或元素。展开运算符可以用在以下几种场合:

•  在函数调用时,可以将一个数组或字符串展开为多个参数,而不需要使用apply方法。例如:

function add(a, b, c) {
return a + b + c;
}

var arr = [1, 2, 3];

// 不使用展开运算符,需要使用apply方法
console.log(add.apply(null, arr)); // 6

// 使用展开运算符,直接将数组展开为参数
console.log(add(...arr)); // 6

•  在构造字面量数组时,可以将一个或多个数组或字符串展开为多个元素,而不需要使用concat方法。例如:

var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];

// 不使用展开运算符,需要使用concat方法
var arr3 = arr1.concat(arr2); // [1, 2, 3, 4, 5, 6]

// 使用展开运算符,直接将数组展开为元素
var arr4 = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]

•  在解构赋值时,可以将一个数组或字符串展开为多个变量,而不需要使用slice方法。例如:

var str = "hello";

// 不使用展开运算符,需要使用slice方法
var [a, b] = str.slice(0, 2); // a = "h", b = "e"

// 使用展开运算符,直接将字符串展开为字符
var [c, d] = [...str]; // c = "h", d = "e"

•  在ES2018中,还可以在构造字面量对象时,将一个或多个对象展开为多个属性,而不需要使用Object.assign方法。例如:

var obj1 = {a: 1, b: 2};
var obj2 = {c: 3, d: 4};

// 不使用展开运算符,需要使用Object.assign方法
var obj3 = Object.assign({}, obj1, obj2); // {a: 1, b: 2, c: 3, d: 4}

// 使用展开运算符,直接将对象展开为属性
var obj4 = {...obj1, ...obj2}; // {a: 1, b: 2, c: 3, d: 4}


2.4,箭头函数 


•  箭头函数使用=>符号来表示,它可以接受一个或多个参数,也可以不接受任何参数。例如:

// 无参数的箭头函数
() => {
// 函数体
}

// 一个参数的箭头函数
param => {
// 函数体
}

// 多个参数的箭头函数
(param1, param2, ...) => {
// 函数体
}

•  箭头函数的函数体可以是一个表达式或一个语句块。如果是一个表达式,那么函数会隐式地返回表达式的值。如果是一个语句块,那么需要使用return语句来返回值。例如:

// 表达式作为函数体,隐式返回
param => param + 1

// 语句块作为函数体,需要显式返回
param => {
let result = param + 1;
return result;
}

•  箭头函数不绑定自己的this值,而是继承外层作用域的this值。这样可以避免一些常见的this指向问题,例如在回调函数或对象方法中。例如:

// 普通函数中的this指向问题
var obj = {
name: "obj",
sayName: function () {
setTimeout(function () {
console.log(this.name); // this指向window,输出undefined
}, 1000);
}
};

obj.sayName();

// 箭头函数中的this继承问题
var obj = {
name: "obj",
sayName: function () {
setTimeout(() => {
console.log(this.name); // this指向obj,输出"obj"
}, 1000);
}
};

obj.sayName();

•  箭头函数不能用作构造函数,也就是说不能用new关键字来调用它们,否则会抛出错误。这是因为箭头函数没有自己的原型属性和构造器。例如:

// 尝试用new调用箭头函数
var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

•  箭头函数也不绑定自己的arguments对象,而是继承外层作用域的arguments对象。这样可以避免一些常见的arguments使用问题,例如在嵌套函数或默认参数中。例如:

// 普通函数中的arguments对象问题
function foo(a) {
var f = function (b) {
return arguments[0]; // arguments指向f的实参,而不是foo的实参
};
return f(a + 1);
}

console.log(foo(1)); // 输出2,而不是1

// 箭头函数中的arguments对象继承
function foo(a) {
var f = (b) => {
return arguments[0]; // arguments指向foo的实参,而不是f的实参
};
return f(a + 1);
}

console.log(foo(1)); // 输出1,而不是2


  <script>
    //箭头函数
    const fn = () => {
      console.log(123);
    }
    fn()
  </script>
  <script>
    //箭头函数
     const fn = x => {
        console.log(x);
      }
      fn(14)
      //只有一个形参的时候括号可以省
  </script>
  <script>
    //箭头函数
     const fn = x =>  console.log(x);
      
      fn(14)
      //只有一个形参的时候括号可以省  函数体只有一行的时候大括号可以省
  </script>
  <script>
    //箭头函数
     const fn = x => x+x ;
      //只有一行代码可以省略return
    console.log(fn(1))
      //只有一个形参的时候括号可以省  函数体只有一行的时候大括号可以省
  </script>
  <script>
    //箭头函数
    //  const fn = x => x+x ;
    //只有一行代码可以省略return
    // console.log(fn(1))
    //只有一个形参的时候括号可以省  函数体只有一行的时候大括号可以省
    //返回一个对象
    const fn = (uname) => ({ uname: uname })
    console.log(fn('bestwishes'));
  </script>

 2.5,箭头函数参数

箭头函数没有动态参数 有剩余参数

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    const getSum = (...arr) => {
      let sum = 0
      for (let i = 0; i < arr.length; i++) {
        sum += arr[i]
      }

      return sum
    }
    const res = getSum(2, 3, 4)
    console.log(res);
  </script>
</body>

</html>

2.6,箭头函数的this

  <script>
    //指向window
    console.log(this);
    function fn() {
      console.log(this);  //指向window
    }
    fn()
    const obj = {
      // 属性
      name:'bestiwhiuse',
      //方法
      siHello:function(){
        console.log(this);
      }
    }
    obj.siHello()   //指向obj
  </script>
  <script>
    //指向window
    console.log(this);
    function fn() {
      console.log(this);  //指向window
    }
    fn()
    const obj = {
      // 属性
      name:'bestiwhiuse',
      //方法
      siHello:function(){
        console.log(this);
      }
    }
    obj.siHello()   //指向obj


    //箭头函数中的this  
    const fn = () => {
      console.log(this);  //window
    } 
    fn()  //指向window    this 往上一层找  上一层就指向window  本层没有

    //对象方法的箭头函数的this 
    const obj2 ={
      name:'bestwishes',
      sayHi:() => {
        console.log(this);   // this指向window
      }
    }
    obj2.sayHi()

  </script>
  <script>
    //指向window
    console.log(this);
    function fn() {
      console.log(this);  //指向window
    }
    fn()
    const obj = {
      // 属性
      name:'bestiwhiuse',
      //方法
      siHello:function(){
        console.log(this);
      }
    }
    obj.siHello()   //指向obj


    //箭头函数中的this  
    const fn = () => {
      console.log(this);  //window
    } 
    fn()  //指向window    this 往上一层找  上一层就指向window  本层没有

    //对象方法的箭头函数的this 
    const obj2 ={
      name:'bestwishes',
      sayHi:() => {
        console.log(this);   // this指向window
      },
      Hello:function(){
        let i = 0
        const count = () =>{
          console.log(this); //指向 obj 指向对象  指向调用者
        }
      }
    }
    obj2.sayHi()

  </script>

三,解构赋值 

3.1,数组解构

应用  

  <script>
    //交换两个变量
    let a = 1
    let b = 2;  //必须加分号
    [b, a] = [a, b]
    console.log(a, b);
  </script>
  <script>
    const str = 'pink';   //必须加分号
    [1, 2, 3].map(function (item) {
      console.log(item);
    })
    //交换两个变量
    let a = 1
    let b = 2;
    [b, a] = [a, b]
    console.log(a, b);
  </script>
  <script>
    const pc = ['海尔', '联想', '小米', '方正']
    [hr, lx, mi, fz] = ['海尔', '联想', '小米', '方正']
    console.log(pc[0]);

    const [max,min] = getValue()

    function getValue(){
      return [20,10]
    }
  </script>
    const arr = [1, 2, [3, 4]] //二维数组
    console.log(arr[2][0]);
    const [a, b, [c, d]] = [1, 2, [3, 4]]
    console.log(a);
    console.log(b);
    console.log(c);
    console.log(d);

3.2,对象解构

      //  对象解构     等价于 const uname = obj.uname
      //要求对象名和属性名必须一致
    const { uname, age } = { uname: 'bestwishes', age: 18 }
    console.log(uname);    
    console.log(age);
    const { uname: username, age } = { uname: 'bestwishes', age: 18 }
    console.log(username);
    console.log(age);

例子:

 <script>
    // const obj ={
    //   uname:'bestwishes',
    //   age:18
    // }
    //  对象解构     等价于 const uname = obj.uname
    //要求对象名和属性名必须一致
    // const { uname, age } = { uname: 'bestwishes', age: 18 }
    // console.log(uname);
    // console.log(age);

    // const { uname: username, age } = { uname: 'bestwishes', age: 18 }
    // console.log(username);
    // console.log(age);
    // const pig = {name:"帕奇",age:6}
    const { name, age } = { name: "帕奇", age: 6 }
    console.log(name);
    console.log(age);

    // const goods = {
    //   goodsName:'小米',
    //   price:1999
    // }
    const { goodsName: gName, price: p } = { goodsName: '小米', price: 1999 }
    console.log(gName);
    console.log(p);
  </script>
    const pig = {
      name:"bes",
      family:{
        mother:'ma',
        father:'fa',
        sister:'si'
      },
      age:6
    }
    //对象解构
    const {name,family:{mother,father,sister}} = pig

案例:

    const msg = {
      "code": 200,
      "msg": "获取新闻列表成功",
      "data": [
        {
          "id": 1,
          "title": "5G商用自己,三大运用商收入下降",
          "count": 58
        },
        {
          "id": 2,
          "title": "国际媒体头条速览",
          "count": 56
        },
        {
          "id": 3,
          "title": "乌克兰和俄罗斯持续冲突",
          "count": 1669
        },

      ]
    }

解构data:

   // 需求1: 请将以上msg对象  采用对象解构的方式 只选出  data 方面后面使用渲染页面

    const { data } = msg
    function render(arr) {
      console.log(arr);
    }
    render(msg)

    // // 需求2: 上面msg是后台传递过来的数据,我们需要把data选出当做参数传递给 函数

 function render({ data }) {
      console.log(data);
    }
    render(msg)

 // 需求3, 为了防止msg里面的data名字混淆,要求渲染函数里面的数据名改为 myData

    function render({ data: myData }) {
      console.log(myData);
    }
    render(msg)

 遍历数组forEach方法(重点)

渲染案例

  <script>
    const goodsList = [
      {
        id: '4001172',
        name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
        price: '289.00',
        picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
      },
      {
        id: '4001594',
        name: '日式黑陶功夫茶组双侧把茶具礼盒装',
        price: '288.00',
        picture: 'https://yanxuan-item.nosdn.127.net/3346b7b92f9563c7a7e24c7ead883f18.jpg',
      },
      {
        id: '4001009',
        name: '竹制干泡茶盘正方形沥水茶台品茶盘',
        price: '109.00',
        picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
      },
      {
        id: '4001874',
        name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
        price: '488.00',
        picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
      },
      {
        id: '4001649',
        name: '大师监制龙泉青瓷茶叶罐',
        price: '139.00',
        picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
      },
      {
        id: '3997185',
        name: '与众不同的口感汝瓷白酒杯套组1壶4杯',
        price: '108.00',
        picture: 'https://yanxuan-item.nosdn.127.net/8e21c794dfd3a4e8573273ddae50bce2.jpg',
      },
      {
        id: '3997403',
        name: '手工吹制更厚实白酒杯壶套装6壶6杯',
        price: '99.00',
        picture: 'https://yanxuan-item.nosdn.127.net/af2371a65f60bce152a61fc22745ff3f.jpg',
      },
      {
        id: '3998274',
        name: '德国百年工艺高端水晶玻璃红酒杯2支装',
        price: '139.00',
        picture: 'https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg',
      },
    ]



  </script>

 +

    //声明空字符变量
    let str = ''

    const { name, price, picture } = goodsList  //列表解构
    goodsList.forEach(index => {
      //渲染
      str += `
    <div class="item">
      <img src="${picture}" alt="">
      <p class="name">${name}</p>
      <p class="price">${price}</p>
    </div>
      `
      // 追加到大盒子去
      document.querySelector('.list').innerHTML = str
    })


数组中嵌套 对象   解构时 解构名和对象属性名相同

综合案例:

css实现

    /* tab栏切换 */
    .filter a:active,
    .filter a:focus {
      background: #05943c;
      color: #fff;
    }
  <script>
    // 2. 初始化数据
    const goodsList = [
      {
        id: '4001172',
        name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
        price: '289.00',
        picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
      },
      {
        id: '4001594',
        name: '日式黑陶功夫茶组双侧把茶具礼盒装',
        price: '288.00',
        picture: 'https://yanxuan-item.nosdn.127.net/3346b7b92f9563c7a7e24c7ead883f18.jpg',
      },
      {
        id: '4001009',
        name: '竹制干泡茶盘正方形沥水茶台品茶盘',
        price: '109.00',
        picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
      },
      {
        id: '4001874',
        name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
        price: '488.00',
        picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
      },
      {
        id: '4001649',
        name: '大师监制龙泉青瓷茶叶罐',
        price: '139.00',
        picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
      },
      {
        id: '3997185',
        name: '与众不同的口感汝瓷白酒杯套组1壶4杯',
        price: '108.00',
        picture: 'https://yanxuan-item.nosdn.127.net/8e21c794dfd3a4e8573273ddae50bce2.jpg',
      },
      {
        id: '3997403',
        name: '手工吹制更厚实白酒杯壶套装6壶6杯',
        price: '99.00',
        picture: 'https://yanxuan-item.nosdn.127.net/af2371a65f60bce152a61fc22745ff3f.jpg',
      },
      {
        id: '3998274',
        name: '德国百年工艺高端水晶玻璃红酒杯2支装',
        price: '139.00',
        picture: 'https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg',
      },
    ]



  </script>

补充 Filter方法:

 <script>
    // 2. 初始化数据
    const goodsList = [
      {
        id: '4001172',
        name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
        price: '289.00',
        picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
      },
      {
        id: '4001594',
        name: '日式黑陶功夫茶组双侧把茶具礼盒装',
        price: '288.00',
        picture: 'https://yanxuan-item.nosdn.127.net/3346b7b92f9563c7a7e24c7ead883f18.jpg',
      },
      {
        id: '4001009',
        name: '竹制干泡茶盘正方形沥水茶台品茶盘',
        price: '109.00',
        picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
      },
      {
        id: '4001874',
        name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
        price: '488.00',
        picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
      },
      {
        id: '4001649',
        name: '大师监制龙泉青瓷茶叶罐',
        price: '139.00',
        picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
      },
      {
        id: '3997185',
        name: '与众不同的口感汝瓷白酒杯套组1壶4杯',
        price: '108.00',
        picture: 'https://yanxuan-item.nosdn.127.net/8e21c794dfd3a4e8573273ddae50bce2.jpg',
      },
      {
        id: '3997403',
        name: '手工吹制更厚实白酒杯壶套装6壶6杯',
        price: '99.00',
        picture: 'https://yanxuan-item.nosdn.127.net/af2371a65f60bce152a61fc22745ff3f.jpg',
      },
      {
        id: '3998274',
        name: '德国百年工艺高端水晶玻璃红酒杯2支装',
        price: '139.00',
        picture: 'https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg',
      },
    ]


    //渲染函数 
    function render() {
      let str = ''
      goodsList.forEach(item => {
        const { name, price, picture, id } = goodsList
        str += `
          <div class="item">
      <img src="${picture}" alt="">
      <p class="name">${name}</p>
      <p class="price">${price}</p>
    </div>
      `
        document.querySelector('.list').innerHTML = str
      })
    }
    render(goodsList)
    //过滤筛选 
    document.querySelector('.filter').addEventListener('click',e => {
      //解构e.target
      const {dataset,tagName} = e.target
      let arr = goodsList
      if(tagName ==='A'){
        if(dataset.index ==='1'){
          arr = goodsList.filter(item => item.price>=0&&item.price<=100)
        }
        else if(dataset.index ==='2'){
          arr = goodsList.filter(item => item.price >= 100 && item.price <= 300)
        }
          else if (dataset.index === '3') {
          arr = goodsList.filter(item => item.price >= 300)
        }
      }
    })
    render(arr)
  </script>

三,方法

  • 构造函数&&常用方法
  • 创建对象三种方式

构造函数:

  <script>
    function Pig(uname, age) {
      this.uname = uname
      this.age = age
    }
   const p = new Pig('佩奇', 6)
  </script>

  <script>
    function Pig(uname, age) {
      this.uname = uname
      this.age = age
    }
    const p1 = new Pig('佩奇', 6)
    const p2 = new Pig('佩', 7)
    console.log(p1 === p2); //false  
    //构造函数创建的对象互不影响
  </script>

实例成员是指没有用static修饰的类成员,例如实例变量和实例方法。实例成员属于类的对象,每个对象都有自己的实例成员的副本。实例成员只能通过对象来访问和调用,不能直接通过类名来访问和调用。例如:

class Person {
// 实例变量
String name;
int age;

// 实例方法
void sayHello() {
System.out.println("Hello, I am " + name);
}
}

// 创建一个Person对象
Person p1 = new Person();
// 通过对象访问和修改实例变量
p1.name = "Alice";
p1.age = 20;
// 通过对象调用实例方法
p1.sayHello(); // 输出 Hello, I am Alice

静态成员是指用static修饰的类成员,例如静态变量和静态方法。静态成员属于类本身,不属于任何一个对象,所有对象共享同一个静态成员。静态成员可以直接通过类名来访问和调用,也可以通过对象来访问和调用,但是推荐使用前者。例如:

class Person {
// 静态变量
static int count;

// 静态方法
static void showCount() {
System.out.println("There are " + count + " persons.");
}
}

// 直接通过类名访问和修改静态变量
Person.count = 10;
// 直接通过类名调用静态方法
Person.showCount(); // 输出 There are 10 persons.

// 创建一个Person对象
Person p1 = new Person();
// 通过对象访问和修改静态变量
p1.count = 20;
// 通过对象调用静态方法
p1.showCount(); // 输出 There are 20 persons.

实例成员和静态成员的区别主要有以下几点:

•  实例成员需要创建对象后才能使用,而静态成员不需要创建对象就能使用。

•  实例成员在内存中为每个对象分配一份空间,而静态成员在内存中只占一份空间。

•  实例成员可以访问静态成员和其他实例成员,而静态成员只能访问其他静态成员,不能访问实例成员。

•  静态成员在类加载时就初始化,而实例成员在创建对象时才初始化


实例成员是指没有用static修饰的类成员,例如实例属性和实例方法。实例成员属于类的对象,每个对象都有自己的实例成员的副本。实例成员只能通过对象来访问和调用,不能直接通过类名来访问和调用。例如:

class Person {
// 实例属性
constructor(name, age) {
this.name = name;
this.age = age;
}

// 实例方法
sayHello() {
console.log(`Hello, I am ${this.name}`);
}
}

// 创建一个Person对象
let p1 = new Person("Alice", 20);
// 通过对象访问和修改实例属性
p1.name = "Bob";
p1.age = 21;
// 通过对象调用实例方法
p1.sayHello(); // 输出 Hello, I am Bob

静态成员是指用static修饰的类成员,例如静态属性和静态方法。静态成员属于类本身,不属于任何一个对象,所有对象共享同一个静态成员。静态成员可以直接通过类名来访问和调用,也可以通过对象来访问和调用,但是推荐使用前者。例如:

class Person {
// 静态属性
static count = 0;

// 静态方法
static showCount() {
console.log(`There are ${Person.count} persons.`);
}

// 实例属性
constructor(name, age) {
this.name = name;
this.age = age;
// 每创建一个对象,静态属性加一
Person.count++;
}
}

// 直接通过类名访问和修改静态属性
Person.count = 10;
// 直接通过类名调用静态方法
Person.showCount(); // 输出 There are 10 persons.


基本包装类型: 


内置构造函数

Object静态方法:

  <script>
    const o = { uname: 'pink', age: 18 }
    console.log(Object.keys(o));  //返回数组['uname','age']
    //获得所有的属性
    console.log(Object.values(o));  //['pink',18]
  </script>

 拷贝对象

  <script>
    const o = { uname: 'pink', age: 18 }
    console.log(Object.keys(o));  //返回数组['uname','age']
    //获得所有的属性
    console.log(Object.values(o));  //['pink',18]
    //拷贝对象
    const oo = {}
    Object.assign(oo, o)
    console.log(oo);
  </script>

数组常用方法

reduce方法

  <script>
    const arr = [1, 5, 8]

    //没有初始值
    const total = arr.reduce(function (prev, current) {
      return prev + current
    })
    console.log(total);


  </script>

  <script>
    const arr = [1, 5, 8]

    //没有初始值
    // const total = arr.reduce(function (prev, current) {
    //   return prev + current
    // })
    // console.log(total);
    //有初始值
    const total = arr.reduce(function (prev, current) {
      return prev + current
    }, 10)
    console.log(total);

  </script>
  <script>
    const arr = [1, 5, 8]

    //没有初始值
    // const total = arr.reduce(function (prev, current) {
    //   return prev + current
    // })
    // console.log(total);
    //有初始值
    // const total = arr.reduce(function (prev, current) {
    //   return prev + current
    // }, 10)
    // console.log(total);
    const total = arr.reduce( (prev, current)=> prev + current
    , 10)
    console.log(total);
  </script>
  <script>
    // const arr = [1, 5, 8]

    //没有初始值
    // const total = arr.reduce(function (prev, current) {
    //   return prev + current
    // })
    // console.log(total);
    //有初始值
    // const total = arr.reduce(function (prev, current) {
    //   return prev + current
    // }, 10)
    // console.log(total);
    // const total = arr.reduce( (prev, current)=> prev + current
    // , 10)
    // console.log(total);
    //上一次值       当前值       返回值
    // 
    const arr = [
       {
        name: 'z',
        salary: 10000
      }, {
        name: 'z',
        salary: 10000
      }  ,{
        name: 'z',
        salary: 10000
      }
    ]
    const total = reduce((prev,current)=> prev + current.salary*13,0)





  </script>

常见的方法(前三个知道,后面几个了解)

 every 方法:

    const arr = [10, 20, 30, 40]
    const flag = arr.every(item => item >= 10)
    console.log(flag);
  
 

  <script>
    const spec = { size: '40com*40com', color: '黑色' }
    //拿到所有值的数组
    // Object.values(spec)
    // console.log(Object.values(spec));

    document.querySelector('div').innerHTML = Object.values(spec).join('/')
  </script>

将伪数组转转换为真数组

<body>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
  <script>
   const lis = document.querySelector('ul li')  //伪数组
   const liss = Array.from(lis)  //转为真数组
   console.log(liss);  
  </script>
</body>

 String

•  startswith和endswith方法都接受一个字符串类型的参数,用于指定要检索的子字符串。

•  startswith和endswith方法都返回一个布尔值,如果字符串以参数值为开头或结尾则返回true,否则返回false。

•  startswith和endswith方法都区分大小写,如果参数值和字符串的大小写不一致,则返回false。

•  startswith和endswith方法都可以接受一个可选的第二个参数,用于指定字符串的长度。如果提供了第二个参数,那么只会在字符串的前length个字符中进行检索。

以下是一些使用startswith和endswith方法的示例代码和网页链接,你可以参考学习:

•  使用startswith和endswith方法判断字符串https://www.x1y1z1.com/javascript/startsendwith.html

let text = "Hello world!";
let result1 = text.startsWith("Hello"); // true
let result2 = text.startsWith("hello"); // false
let result3 = text.endsWith("world!"); // true
let result4 = text.endsWith("World!"); // false

•  使用startswith和endswith方法指定字符串长度https://www.runoob.com/jsref/jsref-endswith.html:

let text = "Hello world!";
let result1 = text.startsWith("world", 6); // true
let result2 = text.startsWith("world", 5); // false
let result3 = text.endsWith("Hello", 5); // true
let result4 = text.endsWith("Hello", 6); // false



•  substring方法接受两个参数,分别是开始索引和结束索引,它会返回从开始索引到结束索引(不包括)之间的子字符串。

•  substring方法不会修改原始字符串,而是返回一个新的字符串。

•  如果开始索引大于结束索引,substring方法会自动交换两个参数的位置,这意味着substring(4, 1)等同于substring(1, 4)。

•  如果开始索引或结束索引为负数或NaN,substring方法会将它们视为0。

•  substring方法和substr方法、slice方法都可以用来提取子字符串,但它们有一些区别和注意事项。

以下是一些使用substring方法的示例代码和网页链接,你可以参考学习:

•  使用substring方法提取子字符串https://www.w3school.com.cn/jsref/jsref_substring.asp

let text = "Hello world!";
let result = text.substring(1, 4); // "ell"

•  使用substring方法交换两个参数https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/substring

let text = "Hello world!";
let result = text.substring(4, 1); // "ell"

•  使用substring方法处理负数或NaNhttps://bing.com/search?q=js%E4%B8%AD%E7%9A%84substring%E6%96%B9%E6%B3%95&form=SKPBOT:

let text = "Hello world!";
let result = text.substring(-3); // "Hello world!


小案例:

<body>
  <div></div>
  <script>
    //  const lis = document.querySelector('ul li')  //伪数组
    //  const liss = Array.from(lis)  //转为真数组
    //  console.log(liss); 

    //split 将 字符串转换为数组
    const gift = '50g的茶叶,清洗球'
    // const arr = gift.split(',').map(function (item) {
    //   return `<span>【赠品】${item}</span>  <br>`
    // }).join()

    // document.querySelector('div').innerHTML = arr
    // console.log(arr);
    document.querySelector('div').innerHTML = gift.split(',').map(item => `<span>【赠品】${item}</span> <br>`) 
  </script>
</body>

Number:


•  toFixed方法接受一个参数,表示要保留的小数位数,它是0到20之间的整数,包括0和20。如果省略了该参数,或者提供了非法的值,将默认使用0。

•  toFixed方法返回一个新的字符串,不会修改原始的数字。返回的字符串可能会用0来填充小数部分,以达到指定的长度。

•  toFixed方法在进行四舍五入时可能会产生一些不准确的结果,这是因为toFixed方法在处理浮点数时,实际上使用的是舍入到最近的偶数(银行家舍入)策略,而不是标准的四舍五入。这种舍入策略是为了在大量运算时减小累积误差。

目录

一,作用域

1.1,局部作用域

1.2,全局作用域

1.3,作用域链

1.4,js垃圾回收机制

1.5,闭包

1.6,变量提升

二,函数进阶

2.1,函数提升

2.2,函数参数

 2.3,展开运算符

2.4,箭头函数 

​编辑

 2.5,箭头函数参数

2.6,箭头函数的this

三,解构赋值 

3.1,数组解构

3.2,对象解构

渲染案例

综合案例:

补充 Filter方法:

三,方法

内置构造函数

案例:

四,面向对象编程

1.2,数组扩展最大值和求和方法

1.3,总结

1.4,原型继承

1.5,原型链

综合案例


以下是一些使用toFixed方法的示例代码和网页链接,你可以参考学习:

•  使用toFixed方法转换数字https://www.w3school.com.cn/jsref/jsref_tofixed.asp

let num = 5.56789;
let n = num.toFixed(2); // "5.57"

•  使用toFixed方法处理非法参数https://www.runoob.com/jsref/jsref-tofixed.html

let num = 5.56789;
let n = num.toFixed(-1); // "6"

•  使用toFixed方法产生不准确结果https://bing.com/search?q=js+tofixed+%E6%96%B9%E6%B3%95&form=SKPBOT

let num = 0.615;
let n = num.toFixed(2); // "0.61" 而非 "0.62"


案例:

<body>
  <div class="list">
    <!-- <div class="item">
      <img src="https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg" alt="">
      <p class="name">称心如意手摇咖啡磨豆机咖啡豆研磨机 <span class="tag">【赠品】10优惠券</span></p>
      <p class="spec">白色/10寸</p>
      <p class="price">289.90</p>
      <p class="count">x2</p>
      <p class="sub-total">579.80</p>
    </div> -->
  </div>
  <div class="total">
    <div>合计:<span class="amount">1000.00</span></div>
  </div>
  <script>
    const goodsList = [
      {
        id: '4001172',
        name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
        price: 289.9,
        picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
        count: 2,
        spec: { color: '白色' }
      },
      {
        id: '4001009',
        name: '竹制干泡茶盘正方形沥水茶台品茶盘',
        price: 109.8,
        picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
        count: 3,
        spec: { size: '40cm*40cm', color: '黑色' }
      },
      {
        id: '4001874',
        name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
        price: 488,
        picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
        count: 1,
        spec: { color: '青色', sum: '一大四小' }
      },
      {
        id: '4001649',
        name: '大师监制龙泉青瓷茶叶罐',
        price: 139,
        picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
        count: 1,
        spec: { size: '小号', color: '紫色' },
        gift: '50g茶叶,清洗球'
      }
    ]
    //把主体数据渲染到页面
    document.querySelector('.list').innerHTML = goodsList.map(item => {
      //对象 解构
      const { name, price, picture, spec, gift, count } = item


      //赠品模块
      const text = gift ? gift.split(',').map(item => `<span class="tag">【赠品】${item}</span>`).join() : ''



      const spe = Object.values(spec).join('/')
      //总金额
      const sub_total = ((price * 100 * count) / 100).toFixed(2)  //乘除100处理精度问题.
      // 合计模块
      // const total = price.reduce((prev,current) =>{(prev*100*current)/100})  写外面





      return `
          <div class="item">
      <img src=${picture} alt="">
      <p class="name">${name} <span class="tag">【赠品】${text}</span></p>
      <p class="spec">${spe}</p>
      <p class="price">${price.toFixed(2)}</p>
      <p class="count">${count}</p>
      <p class="sub-total">${sub_total}</p>
    </div>  
      `
    }).join('')  //将返回的数组转换为字符串
    // const { price, count } = current
    // 有bug
    document.querySelector('.amount').innerHTML = goodsList.reduce((prev, current) => {
      const { price, count } = current
      //prev + (price * count).toFixed(2)
      return prev + (price * count).toFixed(2)
    }, 0)

  </script>

四,面向对象编程

1.2,数组扩展最大值和求和方法

                                                   自定义数组方法

  <script>
    const arr = [1, 2, 3]

    //求最大
    Array.prototype.max = function () {
      return Math.max(...this) //this  ->  arr
    }

    //求最小
    Array.prototype.min = function () {
      return Math.min(...this) //this  ->  arr
    }
    console.log(arr.max());
    console.log(arr.min());

    //求和

    Array.prototype.sum = function () {
      return this.reduce((prev, item) => prev + item, 0)
    }
    console.log(arr.sum());
  </script>

1.3,总结

  <script>
    //constructor
    function Star() {

    }
    const p1 = new Star()
    console.log(Star.prototype.constructor === Star);
    Star.prototype.sing = function () {
      console.log('唱歌');
    }
    Star.prototype.dance = function () {
      console.log('跳舞');
    }

    Star.prototype = { 
      //重新指回Star 构造函数
      constructor:Star,
      sing:function(){
        console.log('cg');
      },
      dance:function(){
        console.log('tw');
      }
    }
  </script>

1.4,原型继承

<script>

    // 公共的部分放到原型上
    const Person = {
      age: 18,
      eyes: 2
    }
    // 女人 
    function Wonman() {

    }
    Wonman.prototype = Person   //继承Person 的属性  继承后就覆盖coonstructor类了  要重新指回类
    //指回类 原来的构造函数
    Wonman.prototype.constructor = Wonman
    //实例化对象
    const w1 = new Wonman()
    console.log(w1);
    //男人
    function Man() {

    }
    Man.prototype = Person   //继承Person 的属性
    Man.prototype.constructor = Man
    //实例化对象
    const m1 = new Man()
    console.log(m1);
  </script>

添加新方法出现问题  woman 和man 都被添加这个方法

  <script>

    // 公共的部分放到原型上
    const Person = {
      age: 18,
      eyes: 2
    }
    // 女人 
    function Wonman() {

    }
    Wonman.prototype = Person   //继承Person 的属性  继承后就覆盖coonstructor类了  要重新指回类
    //指回类 原来的构造函数
    Wonman.prototype.constructor = Wonman

    //添加方法
    Wonman.prototype.baby = function () {
      console.log('baby');
    }
    //实例化对象
    const w1 = new Wonman()
    console.log(w1);
    //男人
    function Man() {

    }
    Man.prototype = Person   //继承Person 的属性
    Man.prototype.constructor = Man
    //实例化对象
    const m1 = new Man()
    console.log(m1);
  </script>

所以要抽取一个父类

  <script>
    //父类
    function Person() {
      this.age = 18
      this.eyes = 2
    }
    console.log(new Person);
    // 女人 
    function Wonman() {

    }
    Wonman.prototype = new Person()   //继承Person 的属性  继承后就覆盖coonstructor类了  要重新指回类
    //指回类 原来的构造函数
    Wonman.prototype.constructor = Wonman

    //添加方法
    Wonman.prototype.baby = function () {
      console.log('baby');
    }
    //实例化对象
    const w1 = new Wonman()
    console.log(w1);
    //男人
    function Man() {

    }
    Man.prototype = new Person()   //继承Person 的属性
    Man.prototype.constructor = Man
    //实例化对象
    const m1 = new Man()
    console.log(m1);
  </script>

1.5,原型链

综合案例

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值