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就是对世界造成的改变,例如说打印某些东西到屏幕,或者以某种方式改变机器 ...
随机推荐
- model browser 不出现时
1:当 创建 component 时, 创建完成后,没有出现model browser, 这时需要在model上面添加一个model,然后保存退出,重新进入,就会出现model browser
- 虚拟主机是设置在httpd-vhosts.conf还是vhosts.conf还是httpd.conf
https://blog.csdn.net/weisubao/article/details/43536723 解决方案:虚拟主机是设置在httpd-vhosts.conf还是vhosts.conf还 ...
- 116A
#include <stdio.h> int main() { int n; int a1,a2; int min=0; int cap=0; scanf("%d",& ...
- mysql相关SQL
1.mysql分组获取最新数据 sql> select max(column_name) from table group by column_name having count(*) orde ...
- NgDL:【第二周】NN基础
1.计算图的导数计算 正向比如说是计算代价函数值,反向就是增大多少a/b/c对J的影响,也就是导数的意义,这里讲的是求导链式法则. 2.向量化 节约大量计算时间 简直是100倍的时间,看来之前实现的那 ...
- wordvector to sentence vector
wordvector已经通过word2vec训练出来了,可是如何通过WV得到SV(Sentence Vector)? 思路1: 直接将句子的向量叠加取平均:效果很不好,每个词没有考虑权重,获取的向量会 ...
- Objective-C中NSArray的基本用法示例
NSArray的一些用法 NSArray只允许装OC对象,并且不能装空值,空代表数组元素的结束 #pragma mark - NSArray的基本用法 // 创建一个空数组 NSArray *arra ...
- AsssetBunlder打包
unity3d,资源过多的话.可以压缩成一个资源包.加载出来后.可以解压.找到自己需要的资源 就想.net网站.很多图标都是放一个大图片上.而不是一个图标就是一个图片 因为是在项目编辑时候给资源打包. ...
- vue中使用base64和md5
1.在项目根目录下安装 cnpm install --save js-base64 cnpm install --save js-md5 2.在项目文件中引入 import md5 from 'js- ...
- 自学oracle数据库
1.因为自己要自学oracle数据库,所以就上网查了一下资料,总结了一下. 在以下连接有自学oracle的一下资料 博文中不让加入一些有广告的网站,请谅解,如有需要评论我私发. 2.学习Oracle的 ...