JavaScript 箭头函数与 function 函数的区别

见过箭头函数后,知道箭头函数是 function 定义函数的简写,然后还有一点是箭头函数中的 this 是上级代码的 this
其实除了这两点外,箭头函数和 function 函数还有很多区别。

1、基本语法

1
2
3
4
5
6
7
8
9
10
11
12
// 没有参数时
() => {
// code ...
}
// 有参数时
(param1, param2, ..., paramN) => {
// code ...
}
// 只有1个参数时,圆括号可以省略
param => {
// code ...
}

2、this 指向

  • 顶级代码中, this 指向 window 对象;
  • function 定义的函数中, this 指向该函数的对象;
  • 箭头函数中,箭头函数不会创建自己的 this,始终指向箭头函数所在作用域下的 this

用原型方法 apply()call()bind() 不能改变箭头函数中 this 的指向。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const bar = {
name: 'johnny'
};
function foo () {
console.log(this.name);
}

const fa = () => {
console.log(this.name);
};

// bar 作为 foo() 实例的 this
foo.call(bar); // johnny
fa.call(bar); // TypeError: Cannot read properties of undefined (reading 'name')

3、箭头函数不能做构造函数

阅读更多

用可变变量访问 JavaScript 类、对象的方法(动态访问 JS 类、对象的方法)

JavaScript中,用可变变量访问对象方法或类静态方法,如果访问的方法中 this,此时 this 将会是 undefined
用对象解构赋值获得函数名(如:xxx)后,用函数名后面加括号(如:xxx())执行函数,this 也是 undefined

问题复现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 动态访问方法
class Cls1 {
fn () {
console.log(this);
}
}

const obj = new Cls1();

// ❌ 错误方法
const fn1 = obj.fn;
fn1(); // this undefined

// 解构赋值取得
const { fn } = obj;

// ❌ 错误方法
fn(); // this undefined

阅读更多

彻底搞清 JavaScript Promise

基本用法

我们知道,一个 js Promise 对象,我们可以用 then()catch()finally() 进行链式操作,如:

1
2
3
4
5
6
7
promiseObj.then((res) => {
// do something
}).catch((error) => {
// do something
}).finally(() => {
// do something
})

这是 js Promise 的基本使用,但是要用好 Promise,还有一下几个问题需要搞清楚。

怎样创建 Promise 对象

Promise 对象创建 Promise 实例

阅读更多

Vue3 组件间相互访问(单文件 + <script setup> + 组合式 API 举例)

父组件传参数到子组件 - props

<script setup> 中用 defineProps() 声明组件的属性,在父组件模板中引用子组件时,就可以给通过属性给子组件传参数(可以是值、变量、函数、对象等)。

defineProps 是编译器宏,Vue3 编译器宏不需要导入,并且只能在 <script setup> 中使用。

ex: 子组件声明、调用属性

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- HelloWorld.vue 子组件-->
<script setup>
// 声明属性
defineProps([{
msg: String
}])
</script>

<template>
<div>
{{ msg }}
</div>
</template>

ex: 父组件使用属性

1
2
3
4
5
6
7
8
<!-- Demo.vue 父组件 -->
<script setup>
import HelloWorld from './HelloWorld.vue'
</script>

<template>
<HelloWorld msg="Welcome"/>
</template>

父组件传递事件到子组件

阅读更多

VueRouter 后退页面刷新问题解决方案

用 VueRouter hash 模式时,点击浏览器上的后退按钮,浏览器显示上一次浏览页面的时候,会重新执行页面,像页面刷新一样。

跟微信小程序不一样,微信小程序后退的时候不会重新执行,只是给我们一个 onShow 事件,这样如果需要刷新数据,我们就可以在 onShow 里面解决。

阅读更多

在 Vue3 单文件组件中使用 <script setup> + 组合式 API

<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。当同时使用 SFC 与组合式 API 时该语法是默认推荐。

基本语法

<script> 标签上添加 setup 属性启用该语法,里面的代码会背编译成组件 setup() 函数的内容,每次组件实例被创建时执行。

1
2
3
<script setup>
// 组合式 API 写在这里
</script>

如果要使用 TypeScript,加上 lang="ts" 属性即可。

1
2
<script lang="ts" setup>
</script>

当使用 <script setup> 的时候,任何在 <script setup> 声明的顶层的绑定 (包括变量,函数声明,以及 import 导入的内容) 都能在模板中直接使用。

响应式

响应式即变量数据变化的时候,视图跟着变化。
响应式状态需要明确使用 响应式 API 来创建.
常用 API:

  • ref()
  • reactive()
  • computed()
  • watch()
  • watchEffect()
  • readonly()
阅读更多

Laravel Eloquent 数据库关联查询

一对一 HasOne

tables

1
2
3
4
5
6
- users
- id
- name
- avatars
- user_id
- image

HasOne 关联

1
2
3
4
5
6
7
8
9
// App\Models\User
public function avatar(): HasOne
{
// $this->hasOne('class_name', 'foreign_key', 'local_key');
// foreign_key默认是表名去掉 s 加上 '_id' 后缀
// local_key 默认是 id
return $this->hasOne(Avatar::class);
// 即 $this->hasOne(Avatar::class, 'user_id', 'id');
}

HasOne 反向关联

1
2
3
4
5
6
7
// App\Models\Avatar
public function user(): BelongsTo
{
// $this->belongsTo(User::class, 'foreign_key', 'owner_key');
// return $this->belongsTo(User::class, 'user_id', 'id');
return $this->belongsTo(User::class); // 省略 'foreign_key', 'owner_key' 参数
}

数据操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 新建
$user = User::create(['name', '...']);
Avatar::create([
'user_id' => $user->id,
'image' => '...',
]);

// 更新
$user = User::find(1);
// 更新关联数据
$user->avatar()->update(['image' => '...']);
// 更新模型
$user->update(['name' => '...']);

// 反向关联操作 belongsTo 的 associate/dissociate
$avatar = Avatar::find(1);
$avatar->user()->dissociate(); // 把 user_id 设为 null
$avatar->save(); // 保存更改

$user = User::find(10);
$avatar->user()->associate($user); // 把 user_id 改为 10
$avatar->save();

一对多 HasMany

tables

1
2
3
4
5
6
7
- posts
- id
- title
- comments
- id
- post_id
- comment

模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// App\Models\Post 关联
public function comments(): HasMany
{
// return $this->hasMany('class_name', 'foreign_key', 'local_key');
return $this->hasMany(Comment::class, 'post_id', 'id');
return $this->hasMany(Comment::class); // 使用默认参数
}

// App\Models\Comment 反向关联
public function post(): BelongsTo
{
// $this->belongsTo(Post::class, 'foreign_key', 'owner_key');
return $this->belongsTo(Post::class, 'post_id', 'id');
return $this->belongsTo(Post::class); // 省略 'foreign_key', 'owner_key' 参数
}

//TODO

子查询

1
2
3
4
5
6
7
User::query()->whereIn(
'id',
UserRolePivot::query()
->select('user_id')
->where('role_id', $roleId)
)->get();
// SELECT * FROM user WHERE id IN( SELECT user_id FROM user_role_pivot WHERE role_id = $roleId)

分组查询

阅读更多

PhpStorm 快捷键

  • 文件

    • option + command + y 同步文件/文件夹,文件夹中外部新增或删除文件时刷新有延迟,使用该快捷键同步
    • Ctrl + n 新建文件/文件夹
  • 编辑

    • command + x 剪切行
    • command + c 复制行/复制选中文本
    • command + shift + c 复制文件/文件夹路径
    • command + d 复制行
    • option + ↑ 选择更多代码
    • option + ↓ 选择更少代码
    • option + → 下一个代码(令牌)位置
    • option + ← 上一个代码(令牌)位置
    • command + → 代码行尾
    • command + ← 代码行头
    • tab 增加缩进
    • shift + tab 减少缩进
    • command + shift + enter 完成代码声明
  • 查找相关

    • command + f 查找当前文件
    • command + r 查找替换
    • command + shift + o 快速查询文件
    • command + shift + f 关键字查找,更强大的查询器
    • command + shift + r 高级替换
    • command + option + b 找到当前类(接口的)所有继承(实现类)
    • option + shift + c 查找最近修改的文件
    • option + f7 直接查询选中的字符
    • ctrl + f7 文件中查询选中字符
    • command + 鼠标点击 跳到类或方法或变量等声明处
    • command + shift + tab 切换tab页文件
    • command + shift + +,- 展开或缩起
    • command + . 折叠或展开选中的代码
  • View

    • command + e 打开最近的文件
    • shift + command + e 最近打开文件具体代码位置
  • Bookmarks

    • F3 加入/取消书签
    • option + F3 加入(可设置数字字母记号的)/取消书签
    • command + F3 弹窗显示/隐藏书签
  • Code

    • shift + command + ↑ 声明段上移
    • shift + command + ↓ 声明段下移
    • shift + option + ↑ 行上移
    • shift + option + ↓ 行下移
  • 自动代码

    • option + 回车 选中类名/接口名后按快捷键,导入包,自动修正
    • command + n 快速生成代码,为每个成员属性生成 getter/setter/__construct/方法、文档注释、单元测试等
    • ctrl + i 快速生成插入魔术方法
    • ctrl + o 复写父类方法
    • command + option + l 对当前文件进行格式化排版
    • command + d 复制当前行
    • command + / // 单行注释
    • command + shift + / 多行注释
  • 显示窗口

    • command + 1 Project
    • command + 2 Favorites
    • command + 6 TODO
    • command + 7 Structure
    • command + 9 Version Control 版本控制
    • option + F12 Terminal 终端
  • Git

    • ctrl + v 版本控制相关操作
    • option + command + a Add
    • option + command + z revert (取消Add)
    • shift + command + p pull
    • shift + command + k push
    • command + k commit

Composer 包下载加速

Composer的元数据存在国外的服务器,每次执行composer命令的时候,经常要下载很多的元数据,需要几分钟到十几分钟,效率极低。

我们可以设置使用国内composer镜像来加速。

1
2
3
4
# 查看 composer 项目配置
composer config -l
# 查看 composer 全局配置
composer config -gl

设置镜像命令:

1
2
3
4
5
# 阿里云镜像(不同步了,不推荐用)
# composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

# 腾讯云镜像(推荐用)
composer config -g repos.packagist composer https://mirrors.tencent.com/composer/

恢复默认源:

1
composer config -g --unset repos.packagist

从阿里云镜像换腾讯云镜像

最近安装 Laravel 10 总提示 匹配不到 doctrine/inflector 最小版本的错误:

1
- laravel/framework[v10.0.0, ..., v10.4.1] require doctrine/inflector ^2.0.5 -> found doctrine/inflector[2.0.x-dev, 2.1.x-dev] but it does not match your minimum-stability.

打开 packagist.org 看,明明最新包是 2.0.6,怎么会没有。

composer show doctrine/inflector -a 命令,看到的最新版本是 2.0.4 😭。可以实锤是镜像没同步,应用包太老了。

用命令 composer config -g --unset repos.packagist 恢复默认源,再执行 composer show doctrine/inflector -a,果然最新包时 2.0.6。

换腾讯云镜像,问题解决。

PhpStorm + Xdebug 远程调试PHP

这篇文章解决:

  • PhpStorm + xdebug 单步调试PHP的设置
  • 远程服务器PHP源码调试
  • 微信公众号接口/小程序接口服务的调试

有些应用需要部署到外网环境才能运行,我们使用 PhpStorm + Xdebug 在本地调试远程web服务器跑的代码。

安装xdebug扩展

1
pecl install xdebug

如果服务器部署的是php很新,安装xdebug不成功,可以试试 pecl install xdebug-beta

配置xdebug

在php.ini中添加如下配置

阅读更多