6. JavaScript函数

107 阅读5分钟

一、JavaScript函数定义

1、function定义函数

<script>
    //使用function定义函数
    let cloth = 't-shirt-dirty';
    // 定义洗衣机函数
    function name(cloth){
        let result;
        let endStr = cloth.slice(-5);
        console.log(endStr);
        if(endStr === 'dirty')
        {
            result = 'clean';
        }
        else{
            result = cloth;
        }
        // 返回干净衣服
        return result;
    }
    // 执行函数
    const cleancloth = name(cloth);
    console.log(cleancloth);
</script>

2、es6推荐的函数定义(箭头)

//使用es6推荐的函数定义
let cloth = 't-shirt-dirty';
const name = (cloth)=>{
    let result;
    // slice 截取字符串,-5代表截取后5位
    let endStr = cloth.slice(-5);
    console.log(endStr);
    if(endStr === 'dirty')
    {
        result = 'clean';
    }
    else{
        result = cloth;
    }
    // 返回干净衣服
    return result;
}
// 执行函数
const cleancloth = name(cloth);
console.log(cleancloth);

返回对象

// 返回对象
const fn = (x,y)=>{
    return {
        x,y
    }
}
const res = fn(1,2);
console.log(res);
// 简写
const fn1 = (x,y) => ({x,y})
const res = fn1(1,2);
console.log(res);

3、函数作用域

(1)局部变量

每个函数都会默认创建一个作用域

// 每个函数都会默认创建一个作用域
function fn() {
    // a局部变量
    let a = 1;
}
console.log(a);

function fn(){
 let a=1
}
fn()
console.log(a)  a还是不存在
// 顶级作用域中声明的才是全局变量 window.Function
window.Function
全局变量&局部变量

在顶级作用域声明的变量是全局变量

window的属性是全局变量,其他都是局部变量

(2)函数嵌套(函数执行顺序)

const fn1 = ()=>{
  let b = 1;
  const fn2 = () =>{
// (2)b赋值为5
      let b = 5;
    // (2)打印5
      console.log(b);
  }
  // (1)执行fn1,打印1
  console.log(b);
  // b赋值为8
  b = 8;
  // (2)执行fn2
  fn2();
}
// 执行fn1 :1,5
fn1();

const fn1 = ()=>{
    let b = 1;
    const fn2 = () =>{
        // (2) b又被复制为2,因此现在b为2
        let b = 2;
        const fn3 = ()=>{
            // (3)打印b,所以打印22
            console.log(b);
        }
        // (2)b再一次被赋值为22,因此b现在为22
        // (3)然后再执行fn3
        b = 22;
        fn3();
        // console.log(b);
    }
    // (1)  执行fn1:b = 1,  打印1
    console.log(b);
    // (2) b = 8,然后执行 fn2 
    b = 8;
    fn2();
}
fn1();

(3)arguments

当不知道传入的参数时,可以使用arguments获取传入的所有参数

function fn(){
    console.log(arguments);
}
fn(1,2,3);

箭头函数里面,没有arguments

const fn = () => {
    console.log(arguments);
}
fn(1,2,3);

出错:arguments未定义。

(4)this

使用fn2调用的时候,this是window对象

function fn2(){
    console.log(this);
}
fn2();

call可以改变this指向

function fn2(){
            console.log(this);
        }
        // fn2();
        fn2.call(fn2,1,2,3)

fn2.call(1,2,3)等价于fn2.call(window,1,2,3)

为什么用this?

不用this

let obj={
    name:'tony',
    sayhi(){
        console.log(`hello,I am ${obj.name}`);
    }
}
obj.sayhi();

用this

let obj={
    name:'tony',
    sayhi(){
        console.log(`hello,I am ${this.name}`);
    }
}
// obj.sayhi.call(obj);
obj.sayhi();
let object={
    name:'tony',
    sayhi(){
        console.log(`hello,I am ${this.name}`);
    }
}
// obj.sayhi.call(obj);
object.sayhi();

为什么用this?,对象名称会变,this的名称不会变

如果没有this我们只能通过obj.name来访问obj的属性

如果obj改名,我们就要去修改sayhi这个函数

如果有this,我们就不需要去改sayhi了

箭头函数的this

箭头函数的this永远是外面得到this

// 箭头函数的this,这里是window
const fn=()=>{
    console.log(this);
}
fn.call(fn,1,2,3)

二、JS数组

1、数组的创建

(1)直接使用[]

let array = [1,2,3,4,5];
let arr1 = [1,'str',{
    name:'tony',
    age:18
},[1,2,3]]
console.log(arr1);

(2)Array

// Array
let arr2 = new Array(1,2,3);
console.log(arr2);

(3)从字符串变为数组

①使用Array.from将字符串转为数组
const arr5 = Array.from('abcdefg');
console.log(arr5);

②使用split
let str = '123';
let arr6 = str.split('');
console.log(arr6);

(4)从对象转为数组(使用Array.from将对象转为数组)

如果想要对象直接变为数组形式,

需要加上length属性,并且length属性值为数组长度。

②key(数组下标)必须为连续数字:0,1,2,3.....

// 如果想要对象直接变为数组形式,需要加上length属性,
let obj = {
    a:1,
    b:2,
    c:3,
    length:3
}
// 使用Array.from将对象转为数组
const arr4 = Array.from(obj);
// const arr4 = Array.from.call({}, { length: 1, 0: "foo" });
console.log(arr4);

出错:

查看mdn文档

①key为连续数字

const arr4 = Array.from.call({}, { 
    length: 2, 
    0: "foo",
    1:'foot' });
console.log(arr4);

②key为不连续数字

const arr4 = Array.from.call({}, { 
    length: 2, 
    0: "foo",
    3:'foot' });
console.log(arr4);

找出原因:key(数组下标)必须为连续数字:0,1,2,3.....

// 如果想要对象直接变为数组形式,需要加上length属性,
let obj = {
   0:'a',
   1:'b',
   2:'c',
    length:3
}
// 使用Array.from将对象转为数组
const arr4 = Array.from(obj);
// const arr4 = Array.from.call({}, { length: 1, 0: "foo" });
console.log(arr4);

(5)拼接数组(从数组到数组)

使用concat进行拼接
const array1 = [1,2,3,4];
const array2 = [5,6,7,8,9];
const longAtr = array1.concat(array2);
console.log(longAtr);

slice截取数组

slice不会改变原来的arr slice,截取数组

slice(起始位置,最终位置)

const array1 = [1,2,3,4];
const array2 = [5,6,7,8,9];
const longAtr = array1.concat(array2);
console.log(longAtr);

const shortAtr = longAtr.slice(0,4);
console.log(shortAtr);

(6)伪数组

伪数组的原型链中没有数组的原型

伪数组与真数组最大的区别在于:伪数组没有真数组的原型

<li class="code"></li>
<li class="code"></li>
<li class="code"></li>
<li class="code"></li>
<li class="code"></li>
<li class="code"></li>
<li class="code"></li>
const codelist = document.querySelectorAll('.code');
console.log(codelist);
伪数组的原型对象

真数组的原型对象

三、js数组增删改查

1、增

1-1、push从尾部增加

①一次增加一个元素

// push
const array = [1,2,3,4];
array.push(9);
console.log(array);

②一次增加多个元素

const array = [1,2,3,4];
// array.push(9);
array.push(5,6,7,8,9);
console.log(array);

③一次增加一个数组

// push
const array = [1,2,3,4];
// array.push(9);
// array.push(5,6,7,8,9);
array.push([5,6,7,8,9]);
console.log(array);

1-2、扩展运算符

...arr  可以将一个数组展开

array.push(...[6,7,8])类似于array.push(6,7,8)

const array = [1,2,3,4];
array.push(...[6,7,8])
console.log(array);

1-3 unshift 从头部往数组添加元素(跟push用法类似)

①一次增加一个元素
const array2 = [5,6,7,8];
array2.unshift(4);
console.log(array2);

②一次增加多个元素
const array2 = [5,6,7,8];
// array2.unshift(4);
array2.unshift(2,3,4)
console.log(array2);

③一次增加一个数组
const array2 = [5,6,7,8];
// array2.unshift(4);
array2.unshift([2,3,4])
console.log(array2);

④...将添加的数组进行展开
const array2 = [5,6,7,8];
// array2.unshift(4);
array2.unshift(...[2,3,4])
console.log(array2);

1-4 splice(startIndex,0,元素...)  增加 

从下标的前面添加

第一个参数:开始下标,第二个参数:删除个数,后面的参数:添加的内容

//splice
const array3 = [1,2,3,4];
// 第一个参数:开始下标,第二个参数:删除个数,后面的参数:添加的内容
array3.splice(1,0,5,6,7);
console.log(array3);

mdn的实例

const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// Inserts at index 1
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "April", "June"]

months.splice(3, 1, 'May');
// Replaces 1 element at index 4
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "May", "June"]

语法:

splice(start)
splice(start, deleteCount)
splice(start, deleteCount, item1)
splice(start, deleteCount, item1, item2, itemN)

2、删

1-1 pop

pop与push对应,从尾巴删除元素,pop没有参数,只能删除一个元素

let array = [1,2,3,4];
array.pop();
console.log(array);

1-2 shift

shift 与unshift对应,从头部删除元素

let array = [1,2,3];
// shift 与unshift对应,从头部删除元素
array.shift();
console.log(array);

3、查询

3-1 indexOf

const array2 = ['爸爸','爷爷','儿子','妈妈',1,2,3,4,5]
// indexOf能够返回,传入值的第一个下标元素
const index = array2.indexOf('妈妈');
console.log(index);

const array2 = ['爸爸','爷爷','儿子','妈妈',1,2,3,4,5]
const index2 = array2.indexOf(4);
console.log(index2);

// 结果:7

传入不存在数组中的元素,indexOf会返回-1,我们可以根据这个结论来判断,元素是否在数组中。

const array2 = ['爸爸','爷爷','儿子','妈妈',1,2,3,4,5]
const indexNone = array2.indexOf('弟弟');
console.log(indexNone);

// 输出结果:-1

3-2 includes

includes  判断元素是否在数组中,返回布尔。(返回FALSE,或者true)

const array2 = ['爸爸','爷爷','儿子','妈妈',1,2,3,4,5]
const isInAtr = array2.includes('弟弟')
console.log(isInAtr);
// 输出结果:false
const isInAtr2 = array2.includes('爷爷');
console.log(isInAtr2);
// 输出结果:true

3-3 获取数组中某个元素

const array2 = ['爸爸','爷爷','儿子','妈妈',1,2,3,4,5]
// indexOf能够返回,传入值的第一个下标元素
const index = array2.indexOf('妈妈');
const mom = array2[index];
console.log(mom);

// 结果:妈妈

3-4、slice(start,end) 截取 (包含开始,不含结束)

// slice(startIndex,endIndex) 截取 包含开始不含结束
// slice(startIndex) 截取从startIndex开始到后面的所有值
var arr = [1,2,3,4]
console.log(arr.slice(1,3));  // [2,3]
console.log(arr.slice(1)); // [2,3,4]

例子:

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <input type="text" id="input">
    <ul id="list">

    </ul>
    <script>
        var input = document.getElementById("input");
        var list = document.getElementById("list");
        var arr = [];
        input.onkeydown = function (e) {
            if (e.keyCode == 13) {
                /* indexOf -1数组中不存在这个值 */
                if (arr.indexOf(this.value)==-1) {
                    arr.push(this.value);
                    console.log(arr);
                    var li = document.createElement("li");
                    li.innerHTML = this.value;
                    list.append(li);
                }else{
                    alert("数组中已经有值了")
                }

            }
        }
    </script>
</body>

</html>

4、小练习

(1)增

<body>
    <!-- 界面上的文本框 -->
    <input type="text" id="input">
    <!-- 用来记录,输入信息的列表 -->
    <ul id="list"></ul>
    <script>
        // dom,通过id获取到界面中的元素
        const input = document.getElementById('input');
        // 同理,我们获取到list对象
        const list = document.getElementById('list');
        // 数组用来存放,我们input中输入的数据
        const arr = [];
        // 对input元素,监听事件:按键按下的事件
        // (浏览器提供的事件,默认给函数,传入了一个参数叫做e)
        input.onkeydown=(e)=>{
            console.log(e);
            // 通过e的keycode,知道了是否按下回车键
            if(e.keyCode === 13)
            {
                // 说明不在数组中
                if(arr.indexOf(e.target.value)<0){
                    arr.push(e.target.value);
                    // 创建li标签
                    const li = document.createElement('li');
                    // 将input中的数据,放入li标签中
                  
                  // li标签里面的123 就是innerHTML
                  // <li>
                  // 			123
                  // </li>
                  
                    li.innerHTML = e.target.value;
                    // 将li标签,放入list  ul标签里面
                    list.appendChild(li);
                }
                else
                {
                    alert('数组已经有这个值!')
                }
            }
        }
    </script>
</body>

(2)删

一步:

<input type="text" id="input">
<ul id="list"></ul>

二步:

const array = [
    {
        name:'张三',
        id:1001
    },
    {
        name:'李四',   
        id:1002         
    },
    {
        name:'王五',   
        id:1003         
    },
    {
        name:'小刘',   
        id:1004         
    },
    {
        name:'小雷',   
        id:1005         
    }
];

三步:先清空

// 获取li对象
const list = document.getElementById('list');
// 获取到input对象
const input = document.getElementById('input');
// 删除list下面所有元素
const removeAllChile = () =>{
    const lis = document.querySelectorAll('li');
    if (lis.length) {
        // 循环伪数组,删除list下面的所有元素
        for(let i = 0;i < lis.length; i++){
            list.removeChild(lis[i]);
        }
    }
}

四步:重渲染

// 渲染逻辑:先清空,再渲染

// 重新渲染ul list
const renderList = (array) =>{
    // 先 清空list下面的所有元素
    removeAllChile();
    // 再 将array中的数据添加到列表中
    for(let i = 0; i < array.length; i++){
        // 得到数据
        const item = array[i];
        console.log(item);
        // 创建新的li标签
        const li = document.createElement('li');
        // 将数据放入li标签
        li.innerHTML = item.name;
        // 将li标签放在list标签下边
        list.appendChild(li)
    }
}
renderList(array);

五步:

// 根据id删除
// 监听input按键事件,当按下回车键的时候,通过输入的id值,
// 找到数组中对应的下标,然后调用splice方法,删除数组中对应的项目
input.onkeydown=(e)=>{
    // keyCode===13,说明按下了回车键
    if(e.keyCode === 13){
        // input当中的数据
        // const value = e.target.value;
        const value = Number(e.target.value);
        // array部分每个都是对象的时候,通过id找到数据的index
        // (找到id为value的数据下标)
        const targetIndex = array.findIndex(item=>{
            return item.id === value;
        })
        // 删除
        array.splice(targetIndex,1);
        console.log(array);
        // 将得到的新数组传到重新渲染函数里面
        renderList(array);
    }
}

采用数据驱动视图

四、数组遍历

(1)forEach遍历

forEach循环,传入一个函数作为参数,函数的参数自带数组的每一项以及索引

forEach循环,没有返回值,直接修改原数组

const array = [{
    name: 'tony',
    id: 1001
},2,3,4,5];
array.forEach((item,index) => {
    console.log(item);
    console.log(index);
})

forEach修改数组
// forEach
const array = [{
    name: 'tony',
    id: 1001
},2,3,4,5];
// forEach循环,传入一个函数作为参数,函数的参数自带数组的每一项以及索引
// forEach循环,没有返回值,直接修改原数组
array.forEach((item,index) => {
    console.log(item);
    console.log(index);
    // 修改元素
    if(index === 0){
        item.name = '狗蛋';
    }
})
console.log(array);

(2)map 地图,映射 (需加return)

// forEach
const array = [{
    name: 'tony',
    id: 1001
},'str',3,4,5];
// forEach循环,传入一个函数作为参数,函数的参数自带数组的每一项以及索引
// forEach循环,没有返回值,直接修改原数组
array.forEach((item,index) => {
    console.log(item);
    console.log(index);
    // 修改元素
    if(index === 0){
        item.name = '狗蛋';
    
console.log(array);

// map 地图,映射,
// 需要给函数添加return
// 有返回值,返回一个新数组
const newArr = array.map((item,index) => {
    console.log(item);
    console.log(index);
    // 修改元素
    if(index === 1){
        // item.name = '张三';
        return 'changed'
    }
    // map必须要有返回值
    return item;
})
console.log(array);
console.log(newArr);

(3)some返回一个布尔值(需加return)

只要数组中有一项满足条件,返回true

有返回值,返回一个布尔值

// some返回一个布尔值
// 只要数组中有一项满足条件,返回true
// 有返回值,返回一个布尔值
const res = array.some((item,index)=>{
    return item>4
})
console.log(res);

// 结果:true
// some返回一个布尔值
// 只要数组中有一项满足条件,返回true
// 有返回值,返回一个布尔值
const res = array.some((item,index)=>{
    return item>6
})
console.log(res);

// 结果:false

(4)findIndex

// findIndex
// 只要数组中有满足条件,就返回对应的下标
const index = array.findIndex((item,index)=>{
    return item.name === '狗蛋'
})
console.log(index);

// 结果:0

// 若数组中没有一个满足条件,则返回 -1

(5)find(需加return)

// find方法
// 只要数组中有满足条件,就返回满足条件的项
const target = array.find((item,index) =>{
  return item.name === '狗蛋'
})
console.log(target);

结果:

(6)filter 方法 (筛选,过滤)(需加return)

// filter 方法 (筛选,过滤)(需加return)
// 过滤,筛选数组中所有符合条件的项
// 有返回值,返回一个数组
const arr = [1,2,3,4,5];
const resulArr = arr.filter((item,index)=>{
    return item > 3
})
console.log(resulArr);

// 结果:[4,5]
小练习:
const students = [
    {name:'李四',age:'18岁'},
    {name:'李二',age:'11岁'},
    {name:'李五',age:'19岁'},
    {name:'王四',age:'22.5岁'},
];
// 筛选出大于15岁的男孩
const result = students.filter((item,index) =>{
    // 字符串强制转换为浮点数
    return parseFloat(item.age)>15
})
console.log(result);

五、最大,最小值,reverse

1、最大值 && 最小值

(1)Math.max(...arr)  对数组取最大值

const arr = [1,2,3,4,5];
const arrMax = Math.max(...arr);
console.log(arrMax);

// 结果:5

(2)Math.min(...arr) 取最小值

const arr = [1,2,3,4,5];
const arrMin = Math.min(...arr);
console.log(arrMin);

// 结果:1

(3)翻转数组 arr.reverse

let arr = ['html','css','js'];
const arrReverse = arr.reverse();
console.log(arrReverse);

// 

六、join,sort,reduce

1、join 数组变为字符串

join() 方法用于把数组中的所有元素转换一个字符串。

元素是通过指定的分隔符进行分隔的。

let arr = ['html','css','js'];
const arrStr = arr.join('');
console.log(arrStr);
console.log(arr.join(','));
console.log(arr.join('|'));

// 结果:
// htmlcssjs
// html,css,js
// html|css|js

2、sort 数组排序

升序和降序

let arr = [1,2,3,4,5,6,7,8,9];
// 升序
arr.sort((pre,now)=>{
    return pre-now;
})
console.log(arr);
// 降序
arr.sort((pre,now)=>{
    return now-pre;
})
console.log(arr);

// 结果:
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
// [9, 8, 7, 6, 5, 4, 3, 2, 1]

3、reduce 数组求和

let arr = [1,2,3,4,5,6,7,8,9];
// reduce
// 0 + pre
// pre + now
// 一直累加
const sum = arr.reduce((pre,now)=>{
    return pre + now;
}, 0);
console.log(sum);

// 结果:
// 45

七、数组练习

1、根据年龄升序、降序

const students = [
    {name: 'zhang',age:20},
    {name: 'li',age:18},
    {name: 'wang',age:19},
    {name: 'chen',age:24}
];
// 升序排序
// 当数组内部是对象的时候,直接比较对象中的值,可以将对应的值进行排序
const up = students.sort((a, b)=>{
    return a['age'] - b['age'];
});
console.log(up);
// 降序
const down = students.sort((a, b)=>{
    return b['age'] - a['age'];
});
console.log(down);

2、按值进行排序(有代码冗余)

<body>
    <button id="like">通过好评排序</button>
    <button id="price">通过价格排序</button>
    <ul id="list"></ul>
    <script>
        const sales = [
            {name: '张三', like: 40, distance: 1000, price: 10},
            {name: '李四', like: 60, distance: 500, price: 50},
            {name: '王五', like: 30, distance: 600, price: 40}
        ];
        // 张三 李四 王五
        const list = document.getElementById('list');
        // 删除list下面所有元素
        const removeAllChile = () =>{
            const lis = document.querySelectorAll('li');
            if (lis.length) {
                // 循环伪数组,删除list下面的所有元素
                for(let i = 0;i < lis.length; i++){
                    list.removeChild(lis[i]);
                }
            }
        }
        // 渲染逻辑:先清空,再渲染

        // 重新渲染ul list
        const renderList = (array) =>{
            // 先 清空list下面的所有元素
            removeAllChile();
            // 再 将array中的数据添加到列表中
            for(let i = 0; i < array.length; i++){
                // 得到数据
                const item = array[i];
                console.log(item);
                // 创建新的li标签
                const li = document.createElement('li');
                // 将数据放入li标签
                li.innerHTML = `${item.name}------好评:${item.like}------价格:${item.price}`;
                // 将li标签放在list标签下边
                list.appendChild(li)
            }
        }
        renderList(sales);
        // 获取到两个按钮的对象
        const like = document.getElementById('like');
        const price = document.getElementById('price');

        // 点击事件: onclick
        like.onclick = () => {
            const likeList = sales.sort((a, b) =>{
                return a['like']-b['like']
            })
            renderList(likeList);
        };
        price.onclick = () =>{
            const priceList = sales.sort((a, b)=>{
                return a['price'] - b['price']
            })
            renderList(priceList);
        };

    </script>
</body>

2、按值进行排序(代码优化)

使用函数消除重复

第一个参数,需要进行排序的数组

第二个参数,通过什么值进行排序

<body>
    <button id="like">通过好评排序</button>
    <button id="price">通过价格排序</button>
    <ul id="list"></ul>
    <script>
        const sales = [
            {name: '张三', like: 40, distance: 1000, price: 10},
            {name: '李四', like: 60, distance: 500, price: 50},
            {name: '王五', like: 30, distance: 600, price: 40}
        ];
        // 张三 李四 王五
        const list = document.getElementById('list');
        // 删除list下面所有元素
        const removeAllChile = () =>{
            const lis = document.querySelectorAll('li');
            if (lis.length) {
                // 循环伪数组,删除list下面的所有元素
                for(let i = 0;i < lis.length; i++){
                    list.removeChild(lis[i]);
                }
            }
        }
        // 渲染逻辑:先清空,再渲染

        // 重新渲染ul list
        const renderList = (array) =>{
            // 先 清空list下面的所有元素
            removeAllChile();
            // 再 将array中的数据添加到列表中
            for(let i = 0; i < array.length; i++){
                // 得到数据
                const item = array[i];
                console.log(item);
                // 创建新的li标签
                const li = document.createElement('li');
                // 将数据放入li标签
                li.innerHTML = `${item.name}------好评:${item.like}------价格:${item.price}`;
                // 将li标签放在list标签下边
                list.appendChild(li)
            }
        }
        renderList(sales);

        // 使用函数消除重复
        // 第一个参数,需要进行排序的数组
        // 第二个参数,通过什么值进行排序
        const orderd = (arr, value)=>{
            const result = arr.sort((a, b) =>{
                return a[value]-b[value]
            })
            return result;
        }

        // 获取到两个按钮的对象
        const like = document.getElementById('like');
        const price = document.getElementById('price');

        // 点击事件: onclick
        like.onclick = () => {
        const results = orderd(sales,'like');
            renderList(results);
        };
        price.onclick = () =>{
            const results = orderd(sales,'price');
            renderList(results);
        };

    </script>
</body>

八、构造函数

一、小兵练习目标:生产100个小兵

1、创建一个小兵

// -----------1、 创建一个小兵-----------------
//1、 创建一个小兵
let solider = {
    atk: 5,
    dfs: 5,
    attack(){
        console.log('捶你胸口');
    }
}

2、for循环创建100个小兵

代码非常占内存空间

 // -----------2、创建100个小兵-----------------
// 2、创建100个小兵
// 循环100次,太占内存空间
let soliders = [];
for(let i = 0; i < 100; i ++)
{
    let solider = {
        atk: 5,
        dfs: 5,
        attack(){
            console.log('捶你胸口');
        }
    }
    soliders.push(solider);
}

3、使用原型改善内存(创建100个小兵)

// -----------3、使用原型-----------------
// 3、使用原型
// 原型只会占用一份内存空间,不会因为你调用的次数多,就占用多内存空间
let soliderProtoType = {
    dfs: 5,
    attack(){
        // console.log('捶你胸口');
      return this.atk;
    }
}
let soliders = [];
for(let i = 0; i < 100; i ++)
{
  // 使用我们创建的原型去生成一个对象,这样可以节省内存
    let solider = Object.create(soliderProtoType)
    solider.atk = 5;
    soliders.push(solider);
}

4、使用构造函数1

// -----------4、使用构造函数-----------------
let soliders = [];
let akts = [5, 5, 5, 5, 7, 8, 4, 1, 5, 5];
let soliderProtoType = {
    dfs: 5,
    attack() {
        console.log('捶你胸口');
    }
}
const creatsolider = (atk) => {
    // 
    const obj = Object.creat(soliderProtoType);
}

5、使用构造函数(再优化)

// -----------4、使用构造函数-----------------
// 构造函数原理
let soliders = [];
let akts = [5, 5, 5, 5, 7, 8, 4, 1, 5, 5];

// (1)为了节省内存空间使用原型
const creatSolider = (atk) => {
    // object.create使用原型创建对象
    // 1. 自动创建对象,
    // (2)为了生成对象,使用Object.creat来创建新的对象,
    // (3)并且将它的原型指定为我们自己指定的原型
    const obj = Object.create(soliderProtoType);
    // 2. 绑定原型
    obj.atk = atk;
    // 3. 返回对象
    return obj;
}

let soliderProtoType = {
    dfs: 5,
    attack() {
        return this.atk;
    },
    // 构造函数

    constructor: creatSolider
}

// 自动关联原型
creatSolider.soliderProtoType = soliderProtoType;
for (let i = 0; i < 10; i++) {
    soliders[i] = creatSolider(akts[i]);
}
console.log(soliders);

6、es6使用class构造对象

// es6使用class构造对象
// new 优化代码,节省内存
// (1)使用class构造一个类(相当于造一个工厂)
class soliderClass {
    // 把原料atk放进去
    constructor(atk) {
        // 用this绑定对象的属性
        this.atk = atk;
    }
    // class中自带的属性只占一份内存
    defend() {
        console.log('防御');
    }
    attack() {
        console.log('攻击力' + this.atk);
        return this.atk;
    }
}

// const solider = new soliderClass(atk);
const solider = new soliderClass(5);
solider.attack();
console.log(solider);

九、类

类:帮助我们构造一个对象

1、构造一只狗

let obj={
    a:1,
    b:1
}
let dog={
    size:'big',
    legNumber:4,
    bar(){
        console.log('bar');
    }
}

2、构造两只狗(直接构造)

添加了Sameya狗,多了name属性,因为多了一个属性就重新写了新的对象,导致代码重复率很高

let obj={
    a:1,
    b:1
}
let dog={
    size:'big',
    legNumber:4,
    bar(){
        console.log('bar');
    }
}
// dogSameya
let dogSameya={
    name:'sameya',
    size:'big',
    legNumber:4,
    bar(){
        console.log('bar');
    }
}

3、类

为了方便,我们构造通用对象。类能够帮助我们快速构造一个通用对象

并且使用了构造函数

作用:

1、帮助我们在类生成一些属性

(1)狗4条腿:生成4条腿

(2)种类为大狗:所以生成大狗的种类

2、接收外部传来的属性:将接收来的属性放到新对象上

// 类
class doggie {
  // 构造函数
  // 作用:
  // 1、帮助我们在类生成一些属性
  // (1)狗4条腿:生成4条腿
  // (2)种类为大狗:所以生成大狗的种类
  // 2、接收外部传来的属性:将接收来的属性放到新对象上
    constructor(name) {
        this.legNumber = 4,
            this.size = 'big',
            this.name = name
    }
    bar() {
        console.log('bar');
    }
}
// 通过类,再创建一个对象,一只新的狗
// 博美犬
let dogButty = new doggie('bomei');
// 泰迪
let dogTaady = new doggie('taddy');
console.log(dogButty);
console.log(dogTaady);

4、小练习----构造人

class people{
    // 构造函数
    constructor(name){
        this.coutry='China',
        this.height=180,
        this.sex='man',
        this.name=name
    }
    bar(){
        console.log('bar');
    }
} 
// 人
let people1=new people('小敏');
let people2=new people('小王');
let people3=new people('小张');
console.log(people1);
console.log(people2);
console.log(people3);

5、小练习--计算器

计算器:要求:

1、传入两个数

2、实现两数 相加,相减,相乘,相除

// 计算器:要求:
// 1、传入两个数
// 2、实现两数  相加,相减,相乘,相除
class caculate {
    constructor(a, b) {
        // this指代生成的对象
        this.a = a;
        this.b = b;
    }
    // 相加
    sum() {
        return this.a + this.b;
    }
    // 相减
    subtract() {
        return this.a - this.b;
    }
    // 相乘
    multiply() {
        return this.a * this.b;
    }
    // 相除
    divide() {
        return this.a / this.b;
    }
  // 平均数
    average(){
        return (this.a + this.b) / 2;
    }
}
const calobj = new caculate(10, 30);
console.log(calobj);
const sumNumber = calobj.sum();
console.log(sumNumber);

// 计算结果:
// 40

new操作符: 帮助我们将一些函数挂在对象calobj的原型上面,所以原型Prototype上多了四个函数(divide()、multiply()、subtract()、sum())

所以才能调用这些函数。

const subtractNumber = calobj.subtract();
const mutiplyNumber = calobj.multiply();
const divideNumber = calobj.divide();
const averageNumber = calobj.average();
console.log(subtractNumber);
console.log(mutiplyNumber);
console.log(divideNumber);
console.log(averageNumber);

// 计算结果
// -20
// 46 300
// 0.3333333333333333
// 20