ES6 基础
This commit is contained in:
parent
f0f3336641
commit
0b506230fe
@ -1,5 +1,5 @@
|
||||
(function test() {
|
||||
console.log(typeof value); // 引用错误
|
||||
let value = "blue";
|
||||
console.log(typeof value); // ReferenceError: value is not defined
|
||||
let value = "blue"; // 下面的语句都不会被输出
|
||||
console.log(value);
|
||||
})();
|
||||
|
@ -1,9 +0,0 @@
|
||||
let list = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
list.push(function () {
|
||||
console.log(i);
|
||||
});
|
||||
}
|
||||
list.forEach(function (func) {
|
||||
func();
|
||||
});
|
8
code/ES6/src/01_block_bindings/07_const.js
Normal file
8
code/ES6/src/01_block_bindings/07_const.js
Normal file
@ -0,0 +1,8 @@
|
||||
const author = {
|
||||
name: "heibai",
|
||||
};
|
||||
author.name = "ying";
|
||||
console.log(author);
|
||||
author = {
|
||||
name: "heibaiying"
|
||||
};
|
24
code/ES6/src/03_funcations/01_default_parameters.js
Normal file
24
code/ES6/src/03_funcations/01_default_parameters.js
Normal file
@ -0,0 +1,24 @@
|
||||
function request(url, timeout = 2000, callback = function() {}) {
|
||||
console.log(`url: ${url}, timeout: ${timeout}`);
|
||||
callback();
|
||||
}
|
||||
|
||||
request("GitHub"); // url: GitHub, timeout: 2000
|
||||
request("GitHub", undefined); // url: GitHub, timeout: 2000
|
||||
request("GitHub", null); // url: GitHub, timeout: null
|
||||
request("GitHub", 5000); // url: GitHub, timeout: 5000
|
||||
request("GitHub", 5000, () => console.log("超时异常")); // url: GitHub, timeout: 5000
|
||||
// 超时异常
|
||||
|
||||
function test01(first, second = first) {
|
||||
console.log(`first: ${first}, second: ${second}`);
|
||||
}
|
||||
|
||||
function test02(first = second, second) {
|
||||
console.log(`first: ${first}, second: ${second}`);
|
||||
}
|
||||
|
||||
test01(1,undefined);
|
||||
test01(1,2);
|
||||
test02(undefined,2);
|
||||
test02(1,2);
|
7
code/ES6/src/03_funcations/02_rest_parameters.js
Normal file
7
code/ES6/src/03_funcations/02_rest_parameters.js
Normal file
@ -0,0 +1,7 @@
|
||||
function each(...elements) {
|
||||
elements.forEach((element) => console.log(element));
|
||||
}
|
||||
|
||||
let list = [1, 2, 3, 4, 5];
|
||||
each(list);
|
||||
each(...list);
|
34
code/ES6/src/03_funcations/03_arrow_functions.js
Normal file
34
code/ES6/src/03_funcations/03_arrow_functions.js
Normal file
@ -0,0 +1,34 @@
|
||||
let doNothing01 = () => {
|
||||
};
|
||||
// 等效箭头表达式:
|
||||
let doNothing02 = function () {
|
||||
};
|
||||
|
||||
let reflect01 = value => value;
|
||||
// 等效箭头表达式:
|
||||
let reflect02 = function (value) {
|
||||
return value;
|
||||
};
|
||||
|
||||
|
||||
let sum01 = (num1, num2) => num1 + num2;
|
||||
// 等效箭头表达式:
|
||||
let sum02 = function (num1, num2) {
|
||||
return num1 + num2;
|
||||
};
|
||||
|
||||
let getDetail01 = id => ({id: id, name: "heibaiying"});
|
||||
// 等效箭头表达式:
|
||||
let getDetail02 = function (id) {
|
||||
return {
|
||||
id: id,
|
||||
name: "heibaiying"
|
||||
};
|
||||
};
|
||||
|
||||
function test() {
|
||||
return () => arguments[0]; // 箭头函数能访问包含它的函数的 arguments
|
||||
}
|
||||
|
||||
let arrowFunction = test("hello");
|
||||
console.log(arrowFunction()); // hello
|
46
code/ES6/src/05_destructuring/01_object_destructuring.js
Normal file
46
code/ES6/src/05_destructuring/01_object_destructuring.js
Normal file
@ -0,0 +1,46 @@
|
||||
// 1.对象结构
|
||||
(() => {
|
||||
let person = {
|
||||
name: "heibaiying",
|
||||
age: 18
|
||||
};
|
||||
let {name, age} = person;
|
||||
console.log(name); // "heibaiying"
|
||||
console.log(age); // "18"
|
||||
})();
|
||||
|
||||
//2.传递默认值
|
||||
(() => {
|
||||
let person = {
|
||||
name: "heibaiying",
|
||||
age: 18
|
||||
};
|
||||
let {name, age, occupation = "programmer"} = person;
|
||||
console.log(occupation); // programmer
|
||||
})();
|
||||
|
||||
|
||||
//3.改变变量名
|
||||
(() => {
|
||||
let person = {
|
||||
name: "heibaiying",
|
||||
age: 18
|
||||
};
|
||||
let {name: myName, age: myAge, occ: occupation = "programmer"} = person;
|
||||
console.log(myName);
|
||||
console.log(myAge);
|
||||
console.log(occupation);
|
||||
})();
|
||||
|
||||
//4.支持嵌套
|
||||
(() => {
|
||||
let person = {
|
||||
name: "heibaiying",
|
||||
age: 18,
|
||||
teacher: {
|
||||
name: "heibai"
|
||||
}
|
||||
};
|
||||
let {teacher: {name: teacherName}} = person;
|
||||
console.log(teacherName);
|
||||
})();
|
56
code/ES6/src/05_destructuring/02_array_destructuring.js
Normal file
56
code/ES6/src/05_destructuring/02_array_destructuring.js
Normal file
@ -0,0 +1,56 @@
|
||||
// 1.数组解构
|
||||
(() => {
|
||||
let colors = ["red", "green", "blue"];
|
||||
let [firstColor, secondColor] = colors;
|
||||
console.log(firstColor); // "red"
|
||||
console.log(secondColor); // "green"
|
||||
})();
|
||||
|
||||
(() => {
|
||||
let colors = ["red", "green", "blue"];
|
||||
let [, , thirdColor] = colors;
|
||||
console.log(thirdColor); // "blue
|
||||
})();
|
||||
|
||||
//3.互换值
|
||||
let a = 1,
|
||||
b = 2;
|
||||
[a, b] = [b, a];
|
||||
console.log(a); // 2
|
||||
console.log(b); // 1
|
||||
|
||||
// 4.默认值
|
||||
|
||||
(() => {
|
||||
let [firstColor, secondColor = "green"] = ["red"];
|
||||
console.log(firstColor); // "red"
|
||||
console.log(secondColor); // "green"
|
||||
})();
|
||||
|
||||
// 5.嵌套解构
|
||||
(() => {
|
||||
let colors = ["red", ["green", "lightgreen"], "blue"];
|
||||
let [firstColor, [secondColor]] = colors;
|
||||
console.log(firstColor); // "red"
|
||||
console.log(secondColor); // "green"
|
||||
})();
|
||||
|
||||
|
||||
// 6.剩余项解构
|
||||
(() => {
|
||||
let colors = ["red", "green", "blue"];
|
||||
let [firstColor, ...restColors] = colors;
|
||||
console.log(firstColor); // "red"
|
||||
console.log(restColors.length); // 2
|
||||
console.log(restColors[0]); // "green"
|
||||
console.log(restColors[1]); // "blue"
|
||||
})();
|
||||
|
||||
|
||||
// 7.在 ES6 中克隆数组
|
||||
(() => {
|
||||
let colors = ["red", "green", "blue"];
|
||||
let [...clonedColors] = colors;
|
||||
console.log(clonedColors); //"[red,green,blue]"
|
||||
})();
|
||||
|
22
code/ES6/src/05_destructuring/03_mixed_destructuring.js
Normal file
22
code/ES6/src/05_destructuring/03_mixed_destructuring.js
Normal file
@ -0,0 +1,22 @@
|
||||
let node = {
|
||||
type: "Identifier",
|
||||
name: "foo",
|
||||
loc: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 1
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 4
|
||||
}
|
||||
},
|
||||
range: [0, 3]
|
||||
};
|
||||
let {
|
||||
loc: {start},
|
||||
range: [startIndex]
|
||||
} = node;
|
||||
console.log(start.line); // 1
|
||||
console.log(start.column); // 1
|
||||
console.log(startIndex); // 0
|
20
code/ES6/src/05_destructuring/04_parameters_destructuring.js
Normal file
20
code/ES6/src/05_destructuring/04_parameters_destructuring.js
Normal file
@ -0,0 +1,20 @@
|
||||
// 1.参数解构
|
||||
function setCookie01(name, value, {secure, path, domain, expires} = {}) {
|
||||
console.log(`secure: ${secure}, path: ${path}, domain:${domain}, expires:${expires}`)
|
||||
}
|
||||
|
||||
setCookie01("type", "js", {
|
||||
secure: true,
|
||||
expires: 60000
|
||||
});
|
||||
|
||||
// 2.参数解构默认值
|
||||
function setCookie02(name, value,
|
||||
{
|
||||
secure = false,
|
||||
path = "/",
|
||||
domain = "example.com",
|
||||
expires = new Date(Date.now() + 360000000)
|
||||
} = {}
|
||||
) {
|
||||
}
|
12
code/ES6/src/06_symbols/01_assign.js
Normal file
12
code/ES6/src/06_symbols/01_assign.js
Normal file
@ -0,0 +1,12 @@
|
||||
function getPerson(name, age) {
|
||||
return {
|
||||
name,
|
||||
age,
|
||||
[Symbol("createTime")]: Date.now()
|
||||
}
|
||||
}
|
||||
|
||||
let person = getPerson("heibaiying", 10);
|
||||
let symbols = Object.getOwnPropertySymbols(person);
|
||||
person[symbols[0]] = 1000;
|
||||
console.log(person[symbols[0]]);
|
38
code/ES6/src/06_symbols/01_symbols.js
Normal file
38
code/ES6/src/06_symbols/01_symbols.js
Normal file
@ -0,0 +1,38 @@
|
||||
let mySymbol = Symbol();
|
||||
|
||||
// 第一种写法
|
||||
let a1 = {};
|
||||
a1[mySymbol] = 'Hello!';
|
||||
|
||||
// 第二种写法
|
||||
let a2 = {
|
||||
[mySymbol]: 'Hello!'
|
||||
};
|
||||
|
||||
// 第三种写法
|
||||
let a3 = {};
|
||||
Object.defineProperty(a3, mySymbol, {value: 'Hello!'});
|
||||
|
||||
// 错误的写法
|
||||
let a4 = {};
|
||||
a4.mySymbol = "hello!";
|
||||
|
||||
|
||||
console.log(a1[mySymbol]); // "Hello!"
|
||||
console.log(a2[mySymbol]); // "Hello!"
|
||||
console.log(a3[mySymbol]); // "Hello!"
|
||||
console.log(a4[mySymbol]); // "undefined"
|
||||
|
||||
let symbol01 = Symbol();
|
||||
let symbol02 = Symbol();
|
||||
console.log(symbol01 === symbol02);
|
||||
let symbol03 = Symbol("name");
|
||||
let symbol04 = Symbol("name");
|
||||
console.log(symbol03 === symbol04);
|
||||
|
||||
let symbol05 = Symbol.for("age");
|
||||
let symbol06 = Symbol.for("age");
|
||||
console.log(symbol05 === symbol06); //true
|
||||
console.log(symbol05); // Symbol(age)
|
||||
|
||||
|
67
code/ES6/src/07_set_and_map/01_sets.js
Normal file
67
code/ES6/src/07_set_and_map/01_sets.js
Normal file
@ -0,0 +1,67 @@
|
||||
// 1. Set 不会使用强制类型转换来判断值是否重复
|
||||
let set01 = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
|
||||
set01.add("5");
|
||||
set01.has("5");
|
||||
set01.delete("5");
|
||||
set01.clear();
|
||||
|
||||
let set02 = new Set(),
|
||||
key1 = {},
|
||||
key2 = {};
|
||||
set02.add(key1);
|
||||
set02.add(key2);
|
||||
console.log(set02.size); // 2
|
||||
|
||||
//4.值的遍历
|
||||
let set03 = new Set(["hei", "bai", "ying"]);
|
||||
set03.forEach(function (value, key, ownerSet) {
|
||||
console.log(key + " " + value);
|
||||
console.log(ownerSet === set03);
|
||||
});
|
||||
|
||||
// hei hei
|
||||
// true
|
||||
// bai bai
|
||||
// true
|
||||
// ying ying
|
||||
// true
|
||||
|
||||
//5. 在 foreach 中绑定作用域 两种方式
|
||||
let Set04 = new Set([1, 2]);
|
||||
let processor01 = {
|
||||
output(value) {
|
||||
console.log(value);
|
||||
},
|
||||
process(dataSet) {
|
||||
dataSet.forEach(function (value) {
|
||||
this.output(value);
|
||||
}, this);
|
||||
//如果想在回调函数中使用 this ,你可以给 forEach() 传入一个 this值作为第二个参数
|
||||
}
|
||||
};
|
||||
processor01.process(Set04);
|
||||
|
||||
//使用箭头函数绑定
|
||||
let set05 = new Set([1, 2]);
|
||||
let processor = {
|
||||
output(value) {
|
||||
console.log(value);
|
||||
},
|
||||
process(dataSet) {
|
||||
dataSet.forEach((value) => this.output(value));
|
||||
}
|
||||
};
|
||||
processor.process(set05);
|
||||
|
||||
//6. 箭头函数转换为数组
|
||||
let set06 = new Set([1, 2, 3, 3, 3, 4, 5]),
|
||||
array = [...set06];
|
||||
console.log(array); // [1,2,3,4,5]
|
||||
|
||||
// 7.对垃圾回收的影响
|
||||
let set07 = new Set(),
|
||||
item = {name: "heibaiying"};
|
||||
set07.add(item);
|
||||
item = null;
|
||||
// 将item置为null,其之前所指向的对象 {name: "heibaiying"}仍然不会被垃圾回收,因为其被Set所持有
|
||||
console.log([...set07][0]); //{ name: 'heibaiying' }
|
7
code/ES6/src/07_set_and_map/02_weak_sets.js
Normal file
7
code/ES6/src/07_set_and_map/02_weak_sets.js
Normal file
@ -0,0 +1,7 @@
|
||||
//1.与Set区别
|
||||
let set = new WeakSet(),
|
||||
key = {};
|
||||
// 将对象加入 set
|
||||
set.add(key);
|
||||
console.log(set.has(key)); // true
|
||||
key = null;
|
19
code/ES6/src/07_set_and_map/03_maps.js
Normal file
19
code/ES6/src/07_set_and_map/03_maps.js
Normal file
@ -0,0 +1,19 @@
|
||||
// 1.基本使用
|
||||
let map01 = new Map();
|
||||
map01.set("name", "Nicholas");
|
||||
map01.set("age", 25);
|
||||
map01.delete("name");
|
||||
map01.clear();
|
||||
|
||||
// 2.由数组初始化map
|
||||
let map02 = new Map([["name", "Nicholas"], ["age", 25]]);
|
||||
console.log(map02.get("name")); // "Nicholas"
|
||||
console.log(map02.get("age")); // 25
|
||||
console.log(map02.size); // 2
|
||||
|
||||
// 3.进行遍历
|
||||
let map03 = new Map([["name", "Nicholas"], ["age", 25]]);
|
||||
map03.forEach(function (value, key, ownerMap) {
|
||||
console.log(key + " " + value);
|
||||
console.log(ownerMap === map03);
|
||||
});
|
8
code/ES6/src/07_set_and_map/04_weak_maps.js
Normal file
8
code/ES6/src/07_set_and_map/04_weak_maps.js
Normal file
@ -0,0 +1,8 @@
|
||||
let key1 = {},
|
||||
key2 = {},
|
||||
map = new WeakMap([[key1, "Hello"], [key2, 42]]);
|
||||
console.log(map.has(key1)); // true
|
||||
console.log(map.get(key1)); // "Hello"
|
||||
console.log(map.has(key2)); // true
|
||||
console.log(map.get(key2)); // 42
|
||||
map.set({},"123");
|
@ -0,0 +1,16 @@
|
||||
function createIterator(items) {
|
||||
let i = 0;
|
||||
return {
|
||||
hasNext() {
|
||||
return i < items.length;
|
||||
},
|
||||
next() {
|
||||
return i < items.length ? items[i++] : undefined;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
let iterator = createIterator([1, 2, 3, 4, 5]);
|
||||
while (iterator.hasNext()) {
|
||||
console.log(iterator.next());
|
||||
}
|
23
code/ES6/src/08_iterators_and_generators/02_iterators.js
Normal file
23
code/ES6/src/08_iterators_and_generators/02_iterators.js
Normal file
@ -0,0 +1,23 @@
|
||||
function* createIterator(items) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
yield items[i];
|
||||
}
|
||||
}
|
||||
|
||||
let iterator = createIterator([1, 2, 3]);
|
||||
console.log(iterator.next()); // { value: 1, done: false }
|
||||
console.log(iterator.next()); // { value: 2, done: false }
|
||||
console.log(iterator.next()); // { value: 3, done: false }
|
||||
console.log(iterator.next()); // { value: undefined, done: true }
|
||||
|
||||
|
||||
function * getIterator() {
|
||||
yield 1;
|
||||
yield 2;
|
||||
yield 3;
|
||||
}
|
||||
// 生成器能像正规函数那样被调用,但会返回一个迭代器
|
||||
let iterator1 = getIterator();
|
||||
console.log(iterator1.next().value); // 1
|
||||
console.log(iterator1.next().value); // 2
|
||||
console.log(iterator1.next().value); // 3
|
@ -0,0 +1,14 @@
|
||||
let collection = {
|
||||
items: [],
|
||||
* [Symbol.iterator]() {
|
||||
for (let item of this.items) {
|
||||
yield item;
|
||||
}
|
||||
}
|
||||
};
|
||||
collection.items.push(1);
|
||||
collection.items.push(2);
|
||||
collection.items.push(3);
|
||||
for (let x of collection) {
|
||||
console.log(x);
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
let list = ["red", "green", "blue"];
|
||||
let set = new Set(list);
|
||||
let map = new Map();
|
||||
map.set("name", "heibaiying");
|
||||
map.set("age", "12");
|
||||
|
||||
for (let entry of list.entries()) {
|
||||
console.log(entry);
|
||||
}
|
||||
// [ 0, 'red' ]
|
||||
// [ 1, 'green' ]
|
||||
// [ 2, 'blue' ]
|
||||
|
||||
for (let entry of set.entries()) {
|
||||
console.log(entry);
|
||||
}
|
||||
// [ 'red', 'red' ]
|
||||
// [ 'green', 'green' ]
|
||||
// [ 'blue', 'blue' ]
|
||||
|
||||
for (let entry of map.entries()) {
|
||||
console.log(entry);
|
||||
}
|
||||
|
||||
// [ 'name', 'heibaiying' ]
|
||||
// [ 'age', '12' ]
|
||||
|
||||
for (let key of list.keys()) {
|
||||
console.log(key);
|
||||
}
|
||||
for (let key of set.keys()) {
|
||||
console.log(key);
|
||||
}
|
||||
for (let key of map.keys()) {
|
||||
console.log(key);
|
||||
}
|
||||
|
||||
|
||||
let colors = ["red", "green", "blue"];
|
||||
for (let color of colors){
|
||||
console.log(color)
|
||||
}
|
||||
|
||||
|
||||
let message = "abc";
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
console.log(message[i]);
|
||||
}
|
||||
// a
|
||||
// b
|
||||
// c
|
49
code/ES6/src/09_class/01_employee.js
Normal file
49
code/ES6/src/09_class/01_employee.js
Normal file
@ -0,0 +1,49 @@
|
||||
class Employee {
|
||||
|
||||
/*构造器*/
|
||||
constructor(name, age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
/*实例方法*/
|
||||
sayName() {
|
||||
console.log("员工:" + this.name);
|
||||
}
|
||||
|
||||
/*静态方法*/
|
||||
static create(name) {
|
||||
return new Employee(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let employee = new Employee("heibai");
|
||||
employee.sayName();
|
||||
|
||||
class Manager extends Employee {
|
||||
|
||||
/*覆写原有的方法*/
|
||||
sayName() {
|
||||
console.log("领导:" + this.name);
|
||||
}
|
||||
}
|
||||
|
||||
let manager = new Manager("ying");
|
||||
manager.sayName();
|
||||
|
||||
function getBase(flag) {
|
||||
if (flag) {
|
||||
return Manager;
|
||||
} else {
|
||||
return Employee;
|
||||
}
|
||||
}
|
||||
|
||||
class CEO extends getBase(true) {
|
||||
}
|
||||
|
||||
let ceo = new CEO();
|
||||
console.log(ceo instanceof Manager);
|
||||
|
||||
|
||||
|
35
code/ES6/src/10_improved_array/01_array.js
Normal file
35
code/ES6/src/10_improved_array/01_array.js
Normal file
@ -0,0 +1,35 @@
|
||||
let items = Array.of(1, 2);
|
||||
console.log(items);
|
||||
|
||||
let numbers01 = Array.from([1, 2, 3, 4, 5], (value) => value * 10);
|
||||
console.log(numbers01);
|
||||
|
||||
|
||||
let numbers02 = [25, 30, 35, 40, 45];
|
||||
console.log(numbers02.find(n => n > 33)); // 35
|
||||
console.log(numbers02.findIndex(n => n > 33)); // 2
|
||||
|
||||
|
||||
let numbers03 = [1, 2, 3, 4];
|
||||
numbers03.fill(1);
|
||||
console.log(numbers03.toString()); // 1,1,1,1
|
||||
|
||||
//指定位置
|
||||
let numbers04 = [1, 2, 3, 4];
|
||||
numbers04.fill(1, 2);
|
||||
console.log(numbers04.toString()); // 1,2,1,1
|
||||
numbers04.fill(0, 1, 3);
|
||||
console.log(numbers04.toString()); // 1,0,0,1
|
||||
|
||||
let numbers05 = [1, 2, 3, 4];
|
||||
// 从索引 2 的位置开始粘贴
|
||||
// 从数组索引 0 的位置开始复制数据
|
||||
numbers05.copyWithin(2, 0);
|
||||
console.log(numbers05.toString()); // 1,2,1,2
|
||||
|
||||
let numbers06 = [1, 2, 3, 4];
|
||||
// 从索引 2 的位置开始粘贴
|
||||
// 从数组索引 0 的位置开始复制数据
|
||||
// 在遇到索引 1 时停止复制
|
||||
numbers06.copyWithin(2, 0, 1);
|
||||
console.log(numbers06.toString()); // 1,2,1,4
|
25
code/ES6/src/12_proxies_and_reflection/01_proxies.js
Normal file
25
code/ES6/src/12_proxies_and_reflection/01_proxies.js
Normal file
@ -0,0 +1,25 @@
|
||||
let person = {
|
||||
name: "heibai",
|
||||
idCard: null
|
||||
};
|
||||
let proxy = new Proxy(person, {
|
||||
set(target, propertyKey, value, receiver) {
|
||||
if (propertyKey === "idCard" && value.length !== 18) {
|
||||
throw new Error("输入的身份证长度必须为18位");
|
||||
}
|
||||
// 调用反射进行修改
|
||||
return Reflect.set(target, propertyKey, value, receiver);
|
||||
},
|
||||
get(target, propertyKey, receiver) {
|
||||
if (propertyKey === "idCard") {
|
||||
throw new Error("身份证是私密信息,无权读取");
|
||||
}
|
||||
// 调用反射获取值
|
||||
return Reflect.get(target, propertyKey, receiver);
|
||||
}
|
||||
});
|
||||
proxy.name = "ying";
|
||||
console.log(proxy.name);
|
||||
proxy.idCard = "123456789123456789";
|
||||
console.log(proxy.idCard);
|
||||
|
1275
notes/ES6_基础.md
Normal file
1275
notes/ES6_基础.md
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user