初读js权威指南犀牛书

1. 目录
- 第三章-值、类型、变量
- 第四章-表达式与操作符
- 第五章-语句
- 第六章-对象
- 第十二章-迭代器与生成器
第三章-值、类型、变量
/**
* 结论
*
* 两个比较类似的方法
* toString()
* valueOf()
*
* toString: 将返回对象的字符串表示
* 5 ==> '5'
* 'abc' ==> 'abc'
* [1, 2 ,3] ==> '1,2,3' 数组的每个元素将转换为字符串,在使用逗号分隔符将它们连接起来
* { name: '杨志文', age: 18 } ==> '[object Object]'
* 函数 ==> '源码的字符串表示'
*
* 这种 { } 对象除外,它将表示为 '[object Object]' 这个字符串
*
*
* valueOf: 大体可以认为把对象转换为代表对象的原始值 默认情况下 返回对象本身 (数据类型 log打印的表现形式)
*/
const bool = new Boolean(true)
console.log(bool)
console.log(bool.toString())
console.log(bool.valueOf())
const string = new String("asd")
console.log(string)
console.log(string.toString())
console.log(string.valueOf())
const string2 = new String([
1,
2,
[32131],
{ name: "sda" },
3,
(a) => {
return a
},
])
console.log(string2)
console.log(string2.toString())
console.log(string2.valueOf())
const num = new Number(321321312)
console.log(num)
console.log(num.toString())
console.log(num.valueOf())
const arr = [
1,
2,
[32131],
{ name: "sda" },
3,
(a) => {
return a
},
]
console.log(arr)
console.log(arr.toString())
console.log(arr.valueOf())
function fn() {
console.log(1231)
}
console.log(fn)
console.log(fn.toString())
console.log(fn.valueOf())
const obj = {
name: "杨志文",
age: 18,
likes: ["苹果", "香蕉"],
}
console.log(obj)
console.log(obj.toString())
console.log(obj.valueOf())
console.log(Number([1]))
console.log(Number('1,2,3'))
console.log(parseInt('1,2,3'))
console.log(Number(''))
console.log(Number(['bbc']))
var abc = "abc";
console.log(window);
delete window.abc;
console.log(window);
function fn() {
a = "a";
}
fn()
delete window.a;
console.log(window);
第五章-语句
/**
* for-in循环 后面可以是任意对象,这个语法是一开始就有的,for-of是新增的
*/
// for( variable in object )
// statement
/**
* 执行for-in循环时,会求值 object 表达式 如果为 nudefined 或者 null 会跳过循环转移到下一个语句
* 在每次迭代前,都会求值 variable 表达式,并将属性名字赋值给他
*
* for-in循环不会枚举对象的所有属性,比如符号属性
* 对于名字是字符串的属性,它只会遍历可枚举的属性,js内置方法不可枚举
* 继承的可枚举属性也可以被for-in循环枚举 所以这样子 用for-in循环可能会出现意外
* 好的选择是 基于 Object.keys()的for-of循环
*
* 如果 for/in循环的循环体删除一个尚未被枚举的属性,则该属性不会再被枚举
* 如果循环体在对象上又定义了新属性,则新属性可能会也可能不会被枚举(关于for-in对象枚举属性的顺序)
*/
/**
* for of 循环 专门用于可迭代对象
* 现在只需要知道 数组,字符串,集合,映射都是可迭代的就行,他们都是一组或者一批元素可以使用 for-of
* 注意:
* 数组的迭代是实时的,在每次执行循环体之前,都会把数组的下一个元素赋值给元素变量,因此在循环体内 push语句,会无限循环
*
* 常规对象 默认是不可迭代的
* 使用 for-of会报错,因此可以使用for-in 或者Object.keys()/values()/entries()
*
* 注意:
* 这个不是实时的
*/
第六章-对象
/**
* 属性赋值 会查询原型链只为确定是否允许赋值
* 注意:
* 如果o继承了一个名为x的只读属性,则不允许赋值,不过,如果允许赋值,则只会在原始对象上创建或者设置属性,而不会修改原型链中的对象
* 查询属性时会用到原型链,而设置属性时不影响原型链是一个重要的js特性
*
* 属性赋值要么失败要么在原始对象上创建或设置属性的规则有一个例外。
* 如果o继承了属性x,而该属性是一个通过设置方法定义的访问器属性,那么就会调用,该设置方法而不会在o上创建新的属性x,要注意,会在对象o上而不是
* 在定义该属性的原型对象上掉用设置方法。以你如果这个设置方法定义了别的属性,那也会在o上定义同样的属性,但容然不会修改原型链
*/
const obj = {}
console.log(obj)
Object.defineProperty(obj, "name", {
value: "yzw",
configurable: false,
})
console.log(obj)
const newObj = Object.create(obj)
newObj.age = 18
newObj.name = "杨志文"
console.log(newObj.name)
console.log(newObj)
属性
/**
* 属性测试
*
* in 操作符 要求左边是一个属性名,右边是一个对象,如果对象有包含相应名字的自有属性或继承属性,将返回true (可枚举)
*
* hasOwnProperty() 方法,用于测试对象是否有给定名字的属性,对继承的属性返回 false
*
* propertyIsEnumerable()方法细化了hasOwnProperty()方法, 如果该属性是自有属性且这个属性的 enumerable特性为true,这个方法会返回true
*/
/**
* 属性枚举
*
* in 指定对象的每个可枚举 自有属性或继承属性
*
* Object.keys() 返回对象可枚举自有属性名的数组。 不包括 不可枚举属性,继承属性, 名字是符号的属性
*
* Object.getOwnPropertySymbols() 返回名字是符号的自有属性 无论是否可枚举
*
* Object.getOwnPropertyNames() 与 Object.keys()类似,但也会返回不可枚举的自有属性,只要他们的名字是字符串
*
* Reflect.ownKeys() 返回所有属性名 包括可枚举属性与不可枚举属性,以及字符串和符号属性
*/
const abc = Symbol("abc");
const obj = {
"-100": "-100",
hobbies: ["苹果"],
[Symbol("abc")]: "Symbol('abc')",
"-60": -60,
name: "杨志文",
age: 18,
100: 100,
0: 0,
};
obj[12] = '阿苏孤独啊事故'
console.log(obj);
console.log(Object.keys(obj));
for (const key in obj) {
console.log(key);
}
// ['0', '12', '100', '-100', 'hobbies', '-60', 'name', 'age']
/**
* Object.create()用于创建一个新对象,使用其第一个参数作为新对象的原型, 还可以接受第二个参数,用于描述新对象的属性,这个参数属于高级特性
* 提示 如果 第一个参数为 null 该对象不会继承任何的东西,toString()都没有
*
* 如果想创建一个 普通的控对象
* Object.create(Object。prototype)
*
* 用途:
* Object.creat()的一个用途是防止对象被某个第三方库意外修改
* 这种情况下,不要把对象直接传给库函数,而要传入一个继承自它的对象,
* 如果函数读取这个对象的属性,可以读取到继承的属性,而如果它要设置这个对象的属性,则修改不会影响原始对象
*
*
*/
第十二章-迭代器与生成器
class Range {
constructor(from, to) {
this.from = from;
this.to = to;
}
has(val) {
return val >= this.from && val <= this.to;
}
toString() {
return `${this.from}-${this.to}`;
}
[Symbol.iterator]() {
let nextVal = this.from;
let last = this.to;
return {
abc: "123,",
next() {
return {
done: nextVal > last ? true : false,
value: nextVal <= last ? nextVal++ : undefined,
};
},
return() {
console.log("提前退出");
return {};
},
[Symbol.iterator]() {
console.log(this);
return this;
},
};
}
[Symbol.iterator]() {
}
}
const range = new Range(1, 10);
console.log(range);
console.log(range.has(1231));
console.log(range.has(10));
console.log(range.toString());
const iterator = range[Symbol.iterator]();
console.log(iterator);
for (let result = iterator.next(); !result.done; result = iterator.next()) {
if (result.value === 5) {
break;
}
console.log(result.value);
console.log(result);
}
function* oneDigitPrimes() {
yield 2;
yield 3;
yield 5;
yield 7;
yield 99;
}
let primes = oneDigitPrimes();
let iterator = primes[Symbol.iterator]();
console.log(iterator);
console.log(primes);
for (let key of primes) {
console.log(key);
}
class Range {
constructor(from, to) {
this.from = from;
this.to = to;
}
has(val) {
return val >= this.from && val <= this.to;
}
toString() {
return `${this.from}-${this.to}`;
}
*[Symbol.iterator]() {
for (let start = this.from; start <= this.to; start++) {
yield start;
}
}
}
const range = new Range(1, 100);
console.log(range);
console.log([...range]);