zoukankan      html  css  js  c++  java
  • Eloquent JavaScript #04# Objects and Arrays

     要点索引:

    1、补:js字符串的表达方式有三种: "" 和 '' 没什么区别,唯一区别在于 "" 中写 "要转义字符,在 '' 中写 ' 要转义字符。最后一种是 `` ,允许 'xx = ${算式}' 的简写方式。

    2、两种主要的访问对象属性的方式 —— 点号与 [ ]

    [ ] 会获取 [ ] 中的计算后字符串,点号则不会。

    必须用 [ ] 的场景是访问数组属性 x[1], 因为点号后不能跟数字。

    3、js数组自带push和pop方法。

    队列也可以很容易实现:

    let todoList = [];
    function remember(task) {
      todoList.push(task);
    }
    function getTask() {
      return todoList.shift();
    }
    // 紧急事件插入到队列前面
    function rememberUrgently(task) {
      todoList.unshift(task);
    }

    4、对象的属性中,非有效引用名(例如包含空格↓)必须用字符串形式表达:

    let descriptions = {
      work: "Went to work",
      "touched tree": "Touched a tree"
    };

    且必须要用 [ ] 访问该属性:

    descriptions["touched tree"]

    5、js对象允许动态添加属性:

    descriptions["another property"] = "new one";

    如果已经存在就替换。点号也是可以的,但 [ ] 比较通用。

    6、动态删除属性:

    /*
     * 可以把对象想象成一只章鱼,对象的属性想象成带着便签
     * 的章鱼触手,数组也是一种对象,typeof [];的结果是object
     * 所以数组是一种触手上的便签全为顺序数字的章鱼。
     */
    let octopuse = {
        tentacleA: 1,
        tentacleB: 2,
        tentacleC: 3
    };
    
    console.log(octopuse.tentacleA);
    // → 1
    delete octopuse.tentacleA;
    console.log(octopuse.tentacleA);
    // → undefined
    console.log('tentacleA' in octopuse);
    // → false

    用in来判断属性是否存在才是准确的,因为值本身可能为undefined

    注意,delete删除是有后遗症的!并不会删除干净(会留引用)。所以能用filter尽量不用delete

    【PS. in和includes貌似可以互相替换?】

    7、列出对象的所有属性名:

    console.log(Object.keys(octopuse));
    // → ["tentacleB", "tentacleC"]

    8、Object.assign:

    let objectA = {a: 1, b: 2};
    Object.assign(objectA, {b: 3, c: 4});
    console.log(objectA);
    // → {a: 1, b: 3, c: 4}

    9、多个引用可以指向同一个对象,obj1==obj2比较的是引用的值(只有指向同一个对象才返回true),而不是对象的内容。

    const obj只是引用的值不变,不能保证所指向对象的内容不变。

    (上述两点都可以类比Java)

    10、直接传入绑定(键值对):

    let journal = [];
    
    function addEntry(events, squirrel) {
      journal.push({events, squirrel});
    }

    11、重写书上的示例(探究xxx变成松鼠的原因):

    /**
     * getPhi返回变成松鼠和事件的
     * 相关性,返回的值为-1~1,-1表示
     * 负相关,1表示正相关,0表示毫无关系。
     * table表示一个二维表,用于统
     * 计下面四种事件发生的次数:
     * 1、不变松鼠,事件没发生00=0,
     * 2、不变松鼠,事件发生01=1,
     * 3、变成松鼠,事件没发生10=2,
     * 4、变成松鼠,事件发生11=3
     * 测试:
     * console.log(getPhi([76, 9, 4, 1]));
     * → 0.06859943405700354
     */
    const getPhi = (table) => {
      return (table[3] * table[0] - table[2] * table[1]) /
        Math.sqrt((table[2] + table[3]) *
                  (table[0] + table[1]) *
                  (table[1] + table[3]) *
                  (table[0] + table[2]));
    };
    
    /**
     * 获取特定事件对应的表格,测试:
     * console.log(getTable(JOURNAL, "pizza"));
     * → [76, 9, 4, 1]
     */
    const getTable = (JOURNAL, specificEvent) => {
        let result = [0, 0, 0, 0];
        for (let someday of JOURNAL) {
            let tableIndex = 0;
            if (someday.squirrel) tableIndex += 2;
            if (someday.events.includes(specificEvent)) tableIndex += 1;
            result[tableIndex]++;
        }
        return result;
    };
    
    /**
     * 返回包括日志所记录的所有事件的字符串数组
     */
    const getAllEvents = (JOURNAL) => {
        let result = [];
        for (let x of JOURNAL) {
            for (let theEvent of x.events) {
                if (!result.includes(theEvent)) {
                    result.push(theEvent);
                }
            }
        }
        return result;
    };
    
    
    const main = () => {
        let allEvents = getAllEvents(JOURNAL);
        for (let specificEvent of allEvents) {
            let table = getTable(JOURNAL, specificEvent);
            console.log(specificEvent + ":", getPhi(table));
        }
    };

    数据:

    let JOURNAL = [{
            "events": ["carrot", "exercise", "weekend"],
            "squirrel": false
        },
        {
            "events": ["bread", "pudding", "brushed teeth", "weekend", "touched tree"],
            "squirrel": false
        },
        {
            "events": ["carrot", "nachos", "brushed teeth", "cycling", "weekend"],
            "squirrel": false
        },
        {
            "events": ["brussel sprouts", "ice cream", "brushed teeth", "computer", "weekend"],
            "squirrel": false
        },
        {
            "events": ["potatoes", "candy", "brushed teeth", "exercise", "weekend", "dentist"],
            "squirrel": false
        },
        {
            "events": ["brussel sprouts", "pudding", "brushed teeth", "running", "weekend"],
            "squirrel": false
        },
        {
            "events": ["pizza", "brushed teeth", "computer", "work", "touched tree"],
            "squirrel": false
        },
        {
            "events": ["bread", "beer", "brushed teeth", "cycling", "work"],
            "squirrel": false
        },
        {
            "events": ["cauliflower", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["pizza", "brushed teeth", "cycling", "work"],
            "squirrel": false
        },
        {
            "events": ["lasagna", "nachos", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["brushed teeth", "weekend", "touched tree"],
            "squirrel": false
        },
        {
            "events": ["lettuce", "brushed teeth", "television", "weekend"],
            "squirrel": false
        },
        {
            "events": ["spaghetti", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["brushed teeth", "computer", "work"],
            "squirrel": false
        },
        {
            "events": ["lettuce", "nachos", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["carrot", "brushed teeth", "running", "work"],
            "squirrel": false
        },
        {
            "events": ["brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["cauliflower", "reading", "weekend"],
            "squirrel": false
        },
        {
            "events": ["bread", "brushed teeth", "weekend"],
            "squirrel": false
        },
        {
            "events": ["lasagna", "brushed teeth", "exercise", "work"],
            "squirrel": false
        },
        {
            "events": ["spaghetti", "brushed teeth", "reading", "work"],
            "squirrel": false
        },
        {
            "events": ["carrot", "ice cream", "brushed teeth", "television", "work"],
            "squirrel": false
        },
        {
            "events": ["spaghetti", "nachos", "work"],
            "squirrel": false
        },
        {
            "events": ["cauliflower", "ice cream", "brushed teeth", "cycling", "work"],
            "squirrel": false
        },
        {
            "events": ["spaghetti", "peanuts", "computer", "weekend"],
            "squirrel": true
        },
        {
            "events": ["potatoes", "ice cream", "brushed teeth", "computer", "weekend"],
            "squirrel": false
        },
        {
            "events": ["potatoes", "ice cream", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["peanuts", "brushed teeth", "running", "work"],
            "squirrel": false
        },
        {
            "events": ["potatoes", "exercise", "work"],
            "squirrel": false
        },
        {
            "events": ["pizza", "ice cream", "computer", "work"],
            "squirrel": false
        },
        {
            "events": ["lasagna", "ice cream", "work"],
            "squirrel": false
        },
        {
            "events": ["cauliflower", "candy", "reading", "weekend"],
            "squirrel": false
        },
        {
            "events": ["lasagna", "nachos", "brushed teeth", "running", "weekend"],
            "squirrel": false
        },
        {
            "events": ["potatoes", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["carrot", "work"],
            "squirrel": false
        },
        {
            "events": ["pizza", "beer", "work", "dentist"],
            "squirrel": false
        },
        {
            "events": ["lasagna", "pudding", "cycling", "work"],
            "squirrel": false
        },
        {
            "events": ["spaghetti", "brushed teeth", "reading", "work"],
            "squirrel": false
        },
        {
            "events": ["spaghetti", "pudding", "television", "weekend"],
            "squirrel": false
        },
        {
            "events": ["bread", "brushed teeth", "exercise", "weekend"],
            "squirrel": false
        },
        {
            "events": ["lasagna", "peanuts", "work"],
            "squirrel": true
        },
        {
            "events": ["pizza", "work"],
            "squirrel": false
        },
        {
            "events": ["potatoes", "exercise", "work"],
            "squirrel": false
        },
        {
            "events": ["brushed teeth", "exercise", "work"],
            "squirrel": false
        },
        {
            "events": ["spaghetti", "brushed teeth", "television", "work"],
            "squirrel": false
        },
        {
            "events": ["pizza", "cycling", "weekend"],
            "squirrel": false
        },
        {
            "events": ["carrot", "brushed teeth", "weekend"],
            "squirrel": false
        },
        {
            "events": ["carrot", "beer", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["pizza", "peanuts", "candy", "work"],
            "squirrel": true
        },
        {
            "events": ["carrot", "peanuts", "brushed teeth", "reading", "work"],
            "squirrel": false
        },
        {
            "events": ["potatoes", "peanuts", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["carrot", "nachos", "brushed teeth", "exercise", "work"],
            "squirrel": false
        },
        {
            "events": ["pizza", "peanuts", "brushed teeth", "television", "weekend"],
            "squirrel": false
        },
        {
            "events": ["lasagna", "brushed teeth", "cycling", "weekend"],
            "squirrel": false
        },
        {
            "events": ["cauliflower", "peanuts", "brushed teeth", "computer", "work", "touched tree"],
            "squirrel": false
        },
        {
            "events": ["lettuce", "brushed teeth", "television", "work"],
            "squirrel": false
        },
        {
            "events": ["potatoes", "brushed teeth", "computer", "work"],
            "squirrel": false
        },
        {
            "events": ["bread", "candy", "work"],
            "squirrel": false
        },
        {
            "events": ["potatoes", "nachos", "work"],
            "squirrel": false
        },
        {
            "events": ["carrot", "pudding", "brushed teeth", "weekend"],
            "squirrel": false
        },
        {
            "events": ["carrot", "brushed teeth", "exercise", "weekend", "touched tree"],
            "squirrel": false
        },
        {
            "events": ["brussel sprouts", "running", "work"],
            "squirrel": false
        },
        {
            "events": ["brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["lettuce", "brushed teeth", "running", "work"],
            "squirrel": false
        },
        {
            "events": ["candy", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["brussel sprouts", "brushed teeth", "computer", "work"],
            "squirrel": false
        },
        {
            "events": ["bread", "brushed teeth", "weekend"],
            "squirrel": false
        },
        {
            "events": ["cauliflower", "brushed teeth", "weekend"],
            "squirrel": false
        },
        {
            "events": ["spaghetti", "candy", "television", "work", "touched tree"],
            "squirrel": false
        },
        {
            "events": ["carrot", "pudding", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["lettuce", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["carrot", "ice cream", "brushed teeth", "cycling", "work"],
            "squirrel": false
        },
        {
            "events": ["pizza", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["spaghetti", "peanuts", "exercise", "weekend"],
            "squirrel": true
        },
        {
            "events": ["bread", "beer", "computer", "weekend", "touched tree"],
            "squirrel": false
        },
        {
            "events": ["brushed teeth", "running", "work"],
            "squirrel": false
        },
        {
            "events": ["lettuce", "peanuts", "brushed teeth", "work", "touched tree"],
            "squirrel": false
        },
        {
            "events": ["lasagna", "brushed teeth", "television", "work"],
            "squirrel": false
        },
        {
            "events": ["cauliflower", "brushed teeth", "running", "work"],
            "squirrel": false
        },
        {
            "events": ["carrot", "brushed teeth", "running", "work"],
            "squirrel": false
        },
        {
            "events": ["carrot", "reading", "weekend"],
            "squirrel": false
        },
        {
            "events": ["carrot", "peanuts", "reading", "weekend"],
            "squirrel": true
        },
        {
            "events": ["potatoes", "brushed teeth", "running", "work"],
            "squirrel": false
        },
        {
            "events": ["lasagna", "ice cream", "work", "touched tree"],
            "squirrel": false
        },
        {
            "events": ["cauliflower", "peanuts", "brushed teeth", "cycling", "work"],
            "squirrel": false
        },
        {
            "events": ["pizza", "brushed teeth", "running", "work"],
            "squirrel": false
        },
        {
            "events": ["lettuce", "brushed teeth", "work"],
            "squirrel": false
        },
        {
            "events": ["bread", "brushed teeth", "television", "weekend"],
            "squirrel": false
        },
        {
            "events": ["cauliflower", "peanuts", "brushed teeth", "weekend"],
            "squirrel": false
        }
    ];
    View Code

    12、重写getPhi

    function phi([n00, n01, n10, n11]) {
      return (n11 * n00 - n10 * n01) /
        Math.sqrt((n10 + n11) * (n00 + n01) *
                  (n01 + n11) * (n00 + n10));
    }

    13、JSON是方便在网络上传输的数据,详情直接阅读百度百科。它的格式规定是非常严格的:JSON的属性必须由双引号包围,JSON中不能有注释 ...

    let obj = {
        a: 123,
        b: "456"
    };
    
    console.log(obj);
    // → {a: 123, b: "456"}
    
    let string = JSON.stringify(obj);
    
    console.log(string);
    // → {"a":123,"b":"456"}
    
    let obj2 = JSON.parse(string);
    console.log(obj2);
    // → {a: 123, b: "456"}
    
    console.log(obj == obj2);
    // → false

    PS. === 是精确比较,不会进行类型转换,== 会进行类型转换(例如 1 == '1' 是true),在类型确定相同的情况下可以用。

    14、各种语言中的可变参数(java、python、c++、javascript)

    15、More ...

    常用数组方法

    常用string方法

    常用Math方法

    大约在全文 2 /3 处 

    16、练习

    ① 实现range(a, b),返回[a, ... , b]。

    (省略sum)

    onst range = (start, end, step=1) => {
        let result = [];
        if (start <= end && step > 0) {
            for (let i = start; i <= end; i+=step) {
                result.push(i);
            }
        } else if (step < 0) {
            for (let i = start; i >= end; i+=step) {
                result.push(i);
            }        
        }
        return result;
    };
    
    console.log(range(1, 10));
    console.log(range(5, 2, -1));
    console.log(range(5, 2, 1));
    // → [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    // → [5, 4, 3, 2]
    // → []

    - - -- - - - - - -        -- -  -- -  - -- - - -          -- -  -- - - -- - - - - -- - - -- -- 

    ② 字符串倒序

    let x = ['A', 'b', 'C'];
    console.log(x.reverse());
    console.log(x);
    // → ["C", "b", "A"]
    // → ["C", "b", "A"]
    
    const reverseArray = arr => {
        let result = [];
        for (let i = 0; i != arr.length; ++i) {
            result.unshift(arr[i]); // 进队
        }
        return result;
    };
    
    console.log(reverseArray(x));
    console.log(x);
    // → ["A", "b", "C"]
    // → ["C", "b", "A"]
    
    const reverseArrayInPlace = arr => {
        let start = 0;
        let end = arr.length - 1;
        while (start < end) {
            let temp = arr[start];
            arr[start++] = arr[end];
            arr[end--] = temp;
        }
    };
    
    console.log(reverseArrayInPlace(x));
    console.log(x);
    // → undefined
    // → ["A", "b", "C"]

    - - -- - - - - - -        -- -  -- -  - -- - - -          -- -  -- - - -- - - - - -- - - -- --  

    ③ 单向链表

    const arrayToList = arr => {
        // 空数组直接返回null
        if(arr.length == 0) return null;
    
        let index = 0;
        let result = {
            value: arr[index++],
            rest: null    
        };
        // 数组元素数量为1在初始化后立刻返回结果
        if(arr.length == 1) return result;
    
        // 数组元素数量大于1继续添加元素到list
        let next = result;
        while(index < arr.length) {
            next = next.rest = {
                value: arr[index],
                rest: null
            };
            index++;
        }
        return result;
    };
    
    console.log(arrayToList([10, 20, 30]));
    // → {value: 10, rest: {…}}
    
    const listToArray = list => {
        let result = [];
        
        while (list.rest != null) {
            result.push(list.value);
            list = list.rest;
        }
        result.push(list.value);
        
        return result;
    };
    
    console.log(listToArray(arrayToList([10, 20, 30])));
    // → [10, 20, 30]
    
    const prepend = (x, list) => {
        let result = {
            value: x,
            rest: list
        };
        return result;
    };
    
    console.log(prepend(10, prepend(20, null)));
    // → {value: 10, rest: {…}}
    
    const nth = (list, x) => {
        for (let i = 0; i < x; ++i) {
            list = list.rest;
        }
        return list.value;
    };
    
    console.log(nth(arrayToList([10, 20, 30]), 1));
    // → 20

    递归版本nth:

    const nth = (list, x) => {
        if (x == 0) return list.value;
        return nth(list.rest, --x);
    };

    课本解法(简洁了一倍。。):

    function arrayToList(array) {
      let list = null;
      for (let i = array.length - 1; i >= 0; i--) {
        list = {value: array[i], rest: list};
      }
      return list;
    }
    
    function listToArray(list) {
      let array = [];
      for (let node = list; node; node = node.rest) {
        array.push(node.value);
      }
      return array;
    }
    
    function prepend(value, list) {
      return {value, rest: list};
    }
    
    function nth(list, n) {
      if (!list) return undefined;
      else if (n == 0) return list.value;
      else return nth(list.rest, n - 1);
    }

    - - -- - - - - - -        -- -  -- -  - -- - - -          -- -  -- - - -- - - - - -- - - -- --  

    ④ 深度比较

    const deepEqual = (a, b) => {
        let typeA = typeof a;
        let typeB = typeof b;
        // 类型不同直接返回false
        if (typeA != typeB) return false;
        
        // 判断是不是可以直接比较的类型
        let comparedDirectly = ["boolean", "number", "string"];
        if (comparedDirectly.includes(typeA)) return a === b;
        
        // 先排除值为null的情况
        if (a == null && b == null) return true;
        if (a == null && b != null || a !=null && b == null) return false;
        // 递归判断
        if (typeA == "object") {
            let keyA = Object.keys(a);
            let keyB = Object.keys(b);
            if (keyA.length != keyB.length) return false;
            for (let k of keyA) {
                if (keyB.includes(k)) {
                    return deepEqual(a[k], b[k]);
                } else {
                    return false;
                }
            }
        }
        
        // 其它情况一律返回未定义
        return undefined;
    };
    
    let obj = {here: {is: "an"}, object: 2};
    console.log(deepEqual(obj, obj));
    // → true
    console.log(deepEqual(obj, {here: 1, object: 2}));
    // → false
    console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
    // → true

     课本解法:

    function deepEqual(a, b) {
      if (a === b) return true;
      
      // null == null 的情况在 a === b 时已经过滤掉了。
      if (a == null || typeof a != "object" ||
          b == null || typeof b != "object") return false;
    
      let keysA = Object.keys(a), keysB = Object.keys(b);
    
      if (keysA.length != keysB.length) return false;
    
      for (let key of keysA) {
        if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
      }
    
      return true;
    }
  • 相关阅读:
    界面控件DevExpress Blazor UI组件v20.2新版亮点:集成Visual Studio
    如何打印超长图片
    使用you-get库下载视频自动化
    数组求最值和平均数的算法
    如何删除git所有提交历史
    计算机图形学应知应会
    通过终端登录FTP服务器的方式
    局域网内通过ARP欺骗获取他人账号密码
    如何在局域网下用他人的流量上网
    XAMPP下的项目进行内网穿透时的注意点
  • 原文地址:https://www.cnblogs.com/xkxf/p/9546554.html
Copyright © 2011-2022 走看看