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
- }
- ];
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 ...
大约在全文 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;
- }
Eloquent JavaScript #04# Objects and Arrays的更多相关文章
- Eloquent JavaScript #13# HTTP and Forms
索引 Notes fetch form focus Disabled fields form’s elements property 阻止提交 快速插入单词 实时统计字数 监听checkbox和rad ...
- Objects、Arrays、Collectors、System工具类
Objects类 定义 位于java.util包中,JDK1.7以后操作对象的类,对对象的空,对象是否相等进行判断. 常用方法 1.public static boolean equals(Objec ...
- Javascript笔记--Objects
Javascript的简单数据类型包括: 数字,字符串,true/false,null 和undefined. 其他所有值都是对象. 数组是对象,方法也是对象.属性值是除开undefined值以外的 ...
- javascript . 04 匿名函数、递归、回调函数、对象、基于对象的javascript、状态和行为、New、This、构造函数/自定义对象、属性绑定、进制转换
匿名函数: 没有名字的函数,函数整体加小括号不报错, 函数调用 : a:直接调用 (function (){函数体}) ( ) ; b:事件绑定 document.onlick = functio ...
- Eloquent JavaScript #12# Handling Events
索引 Notes onclick removeEventListener Event objects stopPropagation event.target Default actions Key ...
- Eloquent JavaScript #11# The Document Object Model
索引 Notes js与html DOM 在DOM树中移动 在DOM中寻找元素 改变Document 创建节点 html元素属性 布局 style CSS选择器 动画 Exercises Build ...
- Eloquent JavaScript #10# Modules
索引 Notes 背景问题 模块Modules 软件包Packages 简易模块 Evaluating data as code CommonJS modules ECMAScript modules ...
- Eloquent JavaScript #05# higher-order functions
索引 Notes 高阶函数 forEach filter map reduce some findIndex 重写课本示例代码 Excercises Flattening Your own loop ...
- Eloquent JavaScript #03# functions
索引: let VS. var 定义函数的几种方式 more... 1.作者反复用的side effect side effect就是对世界造成的改变,例如说打印某些东西到屏幕,或者以某种方式改变机器 ...
随机推荐
- Devops路线
自动化运维工具 Docker学习 .
- EditText的一些使用技巧
1.让EditText不自动获取焦点 将EditText的某个父级控件设置成 android:focusable="true" android:focusableInTouchMo ...
- 118A
#include <iostream> #include <cctype> #include <string> using namespace std; int m ...
- centos7部署fabric-ca错误解决
1.fabric-ca 编译错误:ltdl.h: no such file 在fabric-ca目录中使用make编译时,会出现如下错误: 解决方案: 如果在ubunt操作系统中,只需安装:apt i ...
- Mac Maven配置
Maven下载链接,解压到指定目录,我这里是 /Users/JYH/Desktop/Hadoop-2.7.2/apache-maven-3.3.9 打开终端,配置环境变量 输入命令 vi ~/.bas ...
- TextBox显示提示信息
属性placeholder可以设置TextBox 提示信息如: <asp:TextBox ID ="txt1" runat ="server" Tool ...
- 从零开始一起学习SLAM | 三维空间刚体的旋转
刚体,顾名思义,是指本身不会在运动过程中产生形变的物体,如相机的运动就是刚体运动,运动过程中同一个向量的长度和夹角都不会发生变化.刚体变换也称为欧式变换. 视觉SLAM中使用的相机就是典型的刚体,相机 ...
- Unittest + python
Unittest简单应用 #_*_coding:utf8_*_ import unittest from selenium import webdriver import time class Tes ...
- 12月centos单词
---恢复内容开始--- UNreachable:adj.(network server unreachable) 不能达到的; 及不到的; 取不到的; 不能得到的; rsync: rsync [re ...
- MyBatis基础入门《十八》动态SQL(if-where)
MyBatis基础入门<十八>动态SQL(if-where) 描述: 代码是在<MyBatis基础入门<十七>动态SQL>基础上进行改造的,不再贴所有代码,仅贴改动 ...