0%

for … of 功能

javascript中的for ... of语句用来遍历可迭代对象,比如遍历数组可以使用如下代码:

1
2
3
4
5
const nums = [1, 2, 3, 4, 5];
for (const num of nums) {
console.log(num);
}

可迭代对象有很多,包括以下这些:

  1. Array
  2. String
  3. TypeArray
  4. Map
  5. Set
  6. NodeList(and other DOM collections)
  7. Array like objects(arguments)
  8. generators produced by generator functions
  9. User-defined iterables.

for … of 执行原理

for ... of首先会调用可迭代对象的@@iterator()方法获取一个iterator,然后反复调用这个iteratornext方法来获取对应的值。

for … of 何时结束迭代?

以下三种情况都会导致for … of结束迭代。

  1. 遇到break语句
  2. 遇到continue语句
  3. iteratornext方法返回 done: true时(也就是正常遍历结束)

for … of 不会修改被迭代的对象

for … of底层使用generator实现,每次迭代都会生成一个新的变量,所以不会改变被迭代的对象。下面的代码将数组中每个值加1,并不会改变原来的数组,因为变量num时迭代时生成的,而且每次迭代就重新生成一个。

1
2
3
4
5
6
7
const nums = [1, 2, 3];
for (let num of nums) {
num += 1;
console.log(num); // 2, 3, 4
}
console.log(nums); // still [1, 2, 3]

for … of 中可以使用destruction

1
2
3
4
5
6
7
8
9
10
const students = [
{ name: 'Alice', age: 20 },
{ name: 'Bob', age: 21 },
{ name: 'Cindy', age: 22 },
];

for (const { name, age } of students) {
console.log(name, age);
}

何时使用经典的for循环?

所谓经典for循环就是使用下标遍历的循环,类似C语言中的for循环。

1
2
3
4
const nums = [1, 2, 3];
for (let i = 0; i < nums.length; i++) {
console.log(nums[i]);
}

是否使用经典的for循环有一个简单的判断标准,在遍历的过程中是否要改变原数组,如果需要,就使用,否则就可以使用其他循环代替,比如for … of, forEach, filter, map, reduce等。

for…of vs for…in

for ... offor ... in都是用来遍历对象的,但是有一些区别:

  1. for ... of遍历的是可迭代对象,而for ... in遍历的是可枚举对象。
  2. for ... of遍历的是值,而for ... in遍历的是键。

Array

对于数组来说,for ... of遍历的是数组的值,而for ... in遍历的是数组的键(下标)。

1
2
3
4
5
6
7
8
9
10
const nums = [1, 2, 3];
nums.foo = 'bar';

for (const num of nums) {
console.log(num); // 1, 2, 3
}

for (const key in nums) {
console.log(key); // 0, 1, 2, foo
}

Object

在对象上使用for ... of会报错,因为对象不是可迭代对象,但是可以使用for ... in来遍历对象的键。

1
2
3
4
5
6
7
8
9
10
11
12
const obj = {
foo: "bar",
baz: "qux",
};

for (const value of obj) {
console.log(num); // TypeError: obj is not iterable
}

for (const key in obj) {
console.log(key); // 0, 1, 2, foo
}

使用for...of可以对Object.keys或者Object.values来进行遍历。

1
2
3
4
5
6
7
8
9
10
11
12
const obj = {
foo: "bar",
baz: "qux",
};

for (const key of Object.keys(obj)) {
console.log(key); // foo, baz
}

for (const value of Object.values(obj)) {
console.log(value); // bar, qux
}

Android dependencies conflict resolve

今天在编译Android应用“草书字典”时突然发现以下错误:

1
Duplicate class com.google.common.util.concurrent.ListenableFuture found in modules jetified-guava-18.0 (com.google.guava:guava:18.0) and jetified-listenablefuture-1.0 (com.google.guava:listenablefuture:1.0)

大意是说com.google.common.util.concurrent.ListenableFuture这个class出现在不同的package中,属于重复依赖,gradle无法处理,要手动处理一下。

app.gradle文件中加入如下一行就好了。

1
implementation 'com.google.guava:guava:27.0.1-android'

Hexo Usage

How to Write a new post

  1. Generate new post in your terminal: hexo new "Your post name"
  2. Open your project by vscode, then open file: source\_post\Your post name.md
  3. Edit your post with vscode, hexo support markdown and ejs files

Clean cache

  1. After finish editing, you can type hexo clean in your terminal to clean the cache, clean is short for clean here.
1
hexo clean

Generate static files

  1. After finish editing, you can type hexo g in your terminal to generate static files, g is short for generate here.
1
hexo g

Publish your post

  1. Type hexo d to deploy your post to github.io, d is short for deploy here.
1
hexo d

View your post

  1. open zdd.github.io to see your post, good job!

you can use npm run deploy to combine generate and deploy in a single command.

View post locally

  1. Run hexo s in terminal, then open localhost:4000 to see your post, this is very convenient to check your post before publish.
1
hexo s

404 File not found

When you encounter the 404 error, make sure to do the following

  1. Check your source\_post\Your post name.md file name, make sure it is the same as the title in the file.
  2. run hexo clean to clean the cache
  3. run hexo g to generate static files
  4. run hexo d to deploy your post to github.io

Tags not working

  1. Make sure you have a tags folder under source folder
  2. Install easy tag plugin by npm install hexo-easy-tags-plugin --save
  3. Delete .deploy_git folder
  4. Run hexo clean to clean the cache
  5. Run hexo g to generate static files
  6. Run hexo d to deploy your post to github.io
  7. Force refresh your browser by Ctrl + F5

Make sure tags config in themes\next\_config.yml is correct, remember to set amount to a large number

1
2
3
4
5
6
7
tagcloud:
# All values below are same as default, change them by yourself.
min: 12 # Minimun font size in px
max: 30 # Maxium font size in px
start: "#ccc" # Start color (hex, rgba, hsla or color keywords)
end: "#111" # End color (hex, rgba, hsla or color keywords)
amount: 2000 # <--------------- Set this to a large number

How to add tags

  1. Run hexo new post "tags"
  2. Make sure tags/index.md has the following content
    1
    2
    3
    4
    5
    ---
    title: tags
    date: 2023-06-30 23:21:34
    type: "tags"
    ---

Add multiple tags for a post

  1. Add tags in the front matter of your post, for example:
    1
    2
    3
    4
    5
    6
    7
    ---
    title: Hexo Usage
    date: 2023-04-16 22:03:56
    tags:
    - hexo
    - blog
    ---

Insert Read more tag to post

1. Insert `<!-- more -->` in your post, for example:
   
1
2
3
4
5
6
7
8
9
10
11
12
---
title: Hexo Usage
date: 2023-04-16 22:03:56
tags:
- hexo
- blog
---

# Hexo Usage
## How to Write a new post
<!-- more -->
# other content

ng-template

顾名思义,ng-template是一个模板元素,通常与结构化指令ng-if, ng-for, ng-switch及模板变量配合使用.

ng-template配合ng-if

1
2
3
<ng-template [ngIf]="true">
<div>Hello, world!</div>
</ng-template>

在实际编程中,我们一般不用上面的写法,而是采用指令的简写形式,也就是用*ngIf代替[ngIf]

1
<div *ngIf="true">Hello, world!</div>

这段代码编译后的结果和第一段代码是相同的。关于指令的简写形式,请参考这篇。注意:在ng-template上使用指令的简写形式是无效的,必须使用属性绑定的方式,下面的代码无法正常工作。

1
2
3
<ng-template *ngIf="true">
<div>Hello, world!</div>
</ng-template>

作为elseBlock使用

假设有如下需求,当conditiontrue时,显示Hello, world!,否则显示Goodbye, world!, 该如何实现呢?
我们可以在ngIf指令后面添加else关键字,然后在else后面添加一个模板引用变量,然后定义一个ng-template并用该模版变量标识之,如下所示:

1
2
<div *ngIf="condition else otherTemplate">Hello, world!</div>
<ng-template #otherTemplate>Goodbye, world!</ng-template>

如果你使用的是Angular17及以上版本,那么你可以使用built-in control flow语法。

1
2
3
4
5
@if(condition) {
<div>Hello, world!</div>
} @else {
<div>Goodbye, world!</div>
}

If-then-else

如果两个分支对应的模板都很大,那么可以采用这种方式,使结构更清晰,代码更易读。

1
2
3
<div *ngIf="condition; then thenBlock else elseBlock"></div>
<ng-template #thenBlock>Content to render when condition is true.</ng-template>
<ng-template #elseBlock>Content to render when condition is false.</ng-template>

同样的,如果你使用的是Angular17及以上版本,那么你可以使用built-in control flow语法。

1
2
3
4
5
@if(condition) {
<div>Hello, world!</div>
} @else {
<div>Goodbye, world!</div>
}

看到了吗,built-in control flow语法的可读性更强,更符合人类的思维方式。

References:

  1. Angular ng-template
  2. ng-container - https://zdd.github.io/2024/07/09/angular-ng-container/

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment