globalThis
объект верхнего уровня
Язык JavaScript имеет объект верхнего уровня, который обеспечивает глобальную среду (т. е. глобальную область действия), в которой выполняется весь код. Однако объекты верхнего уровня неодинаковы для разных реализаций. В среде браузера относится к
window
объект, вNode
Относитсяglobal
объект.ES5
Среди них свойства объекта верхнего уровня эквивалентны глобальным переменным.
var a = 2;
window.a // 2
ES6
Чтобы изменить это, оговорено, с одной стороны, что для сохранения совместимостиvar
команда иfunction
Объявленная командой глобальная переменная по-прежнему является свойством объекта верхнего уровня, с другой стороны оговаривается, чтоlet
Заказ,const
Заказ,class
Глобальная переменная, объявленная командой, не является свойством объекта верхнего уровня. То есть изES6
Первоначально глобальные переменные будут постепенно отделяться от свойств объекта верхнего уровня.
var a = 2;
window.a // 2
let b = 3
window.b //undefined
- Внутри браузера объект верхнего уровня
window
,ноNode
а такжеWeb Worker
нетwindow
. - браузер и
Web Worker
в,self
также указывает на объект верхнего уровня, ноNode
нетself
. -
Node
Внутри находится объект верхнего уровняglobal
, но никакая другая среда не поддерживает его.
ES2020
На уровне языковых стандартов введениеglobalThis
как объект верхнего уровня. То есть при любых обстоятельствахglobalThis
Все существуют, и из них можно получить объект верхнего уровня, указывающий на глобальную средуthis
.
Destructuring
ES6 позволяет извлекать значения из массивов и объектов и присваивать значения переменным по определенному шаблону, который называется деструктурированием
Array Destructuring
let [a, , b, ...c] = [1, 2, 3, 4, 5]
a // 1
b // 3
c // [4,5]
//error
let [a] = 1 //不具备 Iterator 接口
let [a, b = 2, c = 3] = [1, , undefined]
a //1,
b //2,
c //3
let [x = 1, y = x] = []; // x=1; y=1
let [x = y, y = 1] = []; // ReferenceError: y is not defined
//交换位置
let x = 1, y = 2;
[y, x] = [x, y]
x // 2
y // 1
Object Destructuring
Object
деконструкция иArray
Есть важное отличие. Элементы массива расположены по порядку, а значение переменной определяется ее позицией; иObject
изprop
Порядок отсутствует, переменная должна быть такой же, какprop
одно и то же имя, чтобы получить правильноеvalue
.
let { foo, baz } = { foo: 'aaa', bar: 'bbb' };
foo // 'aaa'
baz // undefined
//解构对象方法
let { log, sin, cos } = Math;
const { log } = console;
Как объяснялось выше, присваивание объекта деструктурированию является сокращением для следующей формы
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
foo // error: foo is not defined
let obj = {
p: [
'Hello',
{ y: 'World' }
]
};
let { p: [x, { y }] } = obj;
p // p is not defined // p是模式,不参与赋值
x // "Hello"
y // "World"
let { p, p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]
Tip
: присваивание деструктуризации объекта может извлекать унаследованные свойства.
const obj1 = {};
const obj2 = { foo: 'bar' };
Object.setPrototypeOf(obj1, obj2);
const { foo } = obj1;
foo // "bar"
При установке значения по умолчанию условие для того, чтобы значение по умолчанию вступило в силу, состоит в том, что значение свойства объекта строго равно
undefined
.
var { message: msg = 'Something went wrong', say } = { say() { console.log(`say`) } };
msg // Something went wrong
say // function say(){}
Symbol
Представляет уникальное значение. это
JavaScript
Седьмой тип данных языка.Первые шесть:undefined
,null
, логическое значение(Boolean)
, нить(String)
, стоимость(Number)
, объект(Object)
let sy = Symbol('a')
let sy1 = Symbol('a')
sy === sy1 // false
sy.toString() === sy1.toString() // true
// ES2019 提供 description
sy.description === sy1.description // true
let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');
s1 === s2 // true
Symbol.for()
а такжеSymbol()
Эти два способа письма порождают новыеSymbol
. Разница между ними в том, что первые будут регистрироваться в глобальной среде поиска, вторые — нет.Symbol.for()
не возвращает новый каждый раз, когда он вызываетсяSymbol
значение типа, но сначала проверит данныйkey
Независимо от того, существует ли оно уже, если нет, будет создано новое значение. Например, если вы позвонитеSymbol.for("foo")
30 раз, каждый раз возвращает одно и то жеSymbol
ценность, но вызовSymbol("foo")
30 раз, вернет 30 разныхSymbol
стоимость.
Symbol.iterator
Свойство объекта Symbol.iterator, указывающее на метод итератора объекта по умолчанию. Запомни это
const myIterable = {};
myIterable[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
[...myIterable] // [1, 2, 3] // ...的底层是for...of
возражать против выполнения
for...of
При цикле он будет вызыватьсяSymbol.iterator
метод, который возвращает итератор по умолчанию для этого объекта,
class Collection {
*[Symbol.iterator]() {
let i = 0;
while(this[i] !== undefined) {
yield this[i];
++i;
}
}
}
let myCollection = new Collection();
myCollection[0] = 1;
myCollection[1] = 2;
for(let value of myCollection) {
console.log(value);
}
// 1
// 2
Symbol.toStringTag
объект
Symbol.toStringTag
свойство, указывающее на метод. вызвать этот объектObject.prototype.toString
метод, если это свойство существует, его возвращаемое значение появится вtoString
Строка, возвращаемая методом, представляет тип объекта. То есть это свойство можно использовать для настройки[object Object]
или[object Array]
серединаobject
следующая строка.
({[Symbol.toStringTag]: 'Foo'}.toString())
// "[object Foo]"
class Collection {
get [Symbol.toStringTag]() {
return 'xxx';
}
}
let x = new Collection();
Object.prototype.toString.call(x) // "[object xxx]"
Set
&& Map
ES6
Предоставляет новые структуры данныхSet
,Map
Set
Значение члена уникально, нет повторяющихся значений, элементы в наборе строго типизированы, проверка типов.
let set = new Set([1, true, '1', 'true', 1])
// Set(4) {1, true, "1", "true"}
Set
ручка союза(Union)
, перекресток(Intersect)
сумма и разница(Difference)
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}
// (a 相对于 b 的)差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}
Map
Подобно объектам, это также набор пар ключ-значение, но область действия «ключей» не ограничивается строками, и в качестве ключей могут использоваться различные типы значений (включая объекты).
const map = new Map([
['name', '张三'],
['title', 'Author']
]);
map.size // 2
map.has('name') // true
map.get('name') // "张三"
map.has('title') // true
map.get('title') // "Author"
преобразование между данными
Map To Array
const myMap = new Map()
.set(true, 7)
.set({foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
Array To Map
new Map([
[true, 7],
[{foo: 3}, ['abc']]
])
// Map {
// true => 7,
// Object {foo: 3} => ['abc']
// }
Map To Object
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
const myMap = new Map()
.set('yes', true)
.set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }
Object To Map
let obj = {"a":1, "b":2};
let map = new Map(Object.entries(obj));
Map To JSON
function strMapToJson(strMap) {
return JSON.stringify(strMapToObj(strMap));
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'
JSON To Map
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
jsonToStrMap('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}
WeakSet
&&WeakMap
Все объекты, на которые ссылаются, являются слабыми ссылками, то есть ссылка не учитывается механизмом сборки мусора. Поэтому, как только другие ссылки на указанный объект очищаются, механизм сборки мусора освобождает память, занятую объектом. То есть, когда он больше не нужен,WeakSet
&&WeakMap
Объект имени ключа внутри и соответствующее значение ключа автоматически исчезнут без ручного удаления ссылки.
Proxy
Обзор
Proxy
Можно понять, что уровень «перехвата» устанавливается перед целевым объектом, и внешний доступ к объекту должен сначала пройти этот уровень перехвата, поэтому предусмотрен механизм фильтрации и перезаписи внешнего доступа.Proxy
Первоначальное значение слова - агент, и оно используется здесь для обозначения того, что оно используется для «агента» некоторых операций, что можно перевести как «агент».
а такжеObject.defineProperty
используется ли перехват данных:Определите новое свойство непосредственно в объекте или измените существующее свойство объекта и верните этот объект.
При доступе или изменении свойства объекта используйте фрагмент кода для перехвата этого поведения, выполнения дополнительных операций или изменения возвращаемого результата. Наиболее типичное применение захвата данных -----> двусторонняя привязка данных (распространенный вопрос на собеседовании),
-
Vue 2.x
использоватьObject.defineProperty()
, и отделить внутренности какObserver
,Dep
и использоватьWatcher
связаны -
Vue
существует3.x
После использования версииProxy
Быть достигнутым
Proxy
а такжеObject.defineProperty
контраст
-
Object.defineProperty
- может только слушать объекты (
Object
), не может отслеживать изменения в массиве, не может запускатьpush
,pop
,shift
,unshift
,splice
,sort
,reverse
. - Каждое свойство объекта должно быть пройдено
- Захват имущества может быть только текущим объектом, если вы хотите захватить глубину, необходимо пройти глубоко вложенный объект
"use strict" let obj = {}; let value = 1 Object.defineProperty(obj, 'listenA', { writable: true, //可修改 enumerable: true, // 可枚举 for...in... Object.keys() configurable: true, // 可配置,可删除 get: () => value, set: val => { console.log(`set obj.listenA .. ${val}`); value = val }, }); obj.listenA = 2 //set obj.listenA .. 2 console.log(obj.listenA) // 2
- может только слушать объекты (
-
Proxy
- Вы можете слушать непосредственно объекты, а не свойства
- Вы можете напрямую отслеживать изменения в массиве
// 代理整个对象 let proxyObj = new Proxy({}, { get: (target, key, receiver) => { console.log(`getting ${key}!`); return target[key]; }, set: (target, key, value, receiver) => { console.log(target, key, value, receiver); return target[key] = value; }, }); proxyObj.val = 1; // {} val 1 {} proxyObj.val; // getting val! //代理数组 let proxyArr = new Proxy([], { get: (target, key, receiver) => { console.log(`getting ${key}!`); return target[key]; }, set: (target, key, value, receiver) => { console.log(target, key, value, receiver); return (target[key] = value); }, }); proxyArr[0] = 1; // {} val 1 {} console.log(proxyArr[0]); // getting val! // 1 console.log(proxyArr); // [1]
Reflect
Reflect
Перевод должен означать отражение, сProxy
то же, что объектES6
новое для манипулирования объектамиAPI
. Есть несколько функций
- Буду
Object
Методы объекта, которые явно являются внутренними для языка (например,Object.defineProperty
), вставитьReflect
на объекте. На этом этапе некоторые методыObject
а такжеReflect
объект, будущие новые методы будут развернуты только наReflect
на объекте. То есть изReflect
Объект может получить метод на языке. - Модифицировать некоторые
Object
Возвращаемый результат метода делает его более разумным. Например,Object.defineProperty(obj, name, desc)
Ошибка выдается, когда свойство не может быть определено, иReflect.defineProperty(obj, name, desc)
вернусьfalse
.
// 老写法
try {
Object.defineProperty(target, property, attributes);
// success
} catch (e) {
// failure
}
// 新写法
if (Reflect.defineProperty(target, property, attributes)) { // 成功返回true
// success
} else {
// failure
}
- Позволять
Object
Операции становятся функциональным поведением. немногоObject
Операция — это команда, напримерname in obj
а такжеdelete obj[name]
,а такжеReflect.has(obj, name)
а такжеReflect.deleteProperty(obj, name)
Сделайте их функциональным поведением.
// 老写法
'assign' in Object // true
// 新写法
Reflect.has(Object, 'assign') // true
-
Reflect
методы объекта иProxy
Методы объекта соответствуют один к одному, пока онProxy
методы объекта, вы можетеReflect
Найдите соответствующий метод на объекте. Это позволяет прокси-объекту легко позвонить соответствующемуReflect
метод, который завершает поведение по умолчанию, в качестве основы для изменения поведения. То есть независимо отProxy
Как изменить поведение по умолчанию, вы всегда можетеReflect
чтобы получить поведение по умолчанию.
Proxy(target, {
set: function(target, name, value, receiver) {
var success = Reflect.set(target, name, value, receiver);
if (success) {
console.log('property ' + name + ' on ' + target + ' set to ' + value);
}
return success;
}
});
async function
ES2017
введен стандартasync
функция, делающая асинхронные операции более удобными, потому чтоasync函数
то, что возвращаетсяPromise
предмет, который можно использовать какawait
Параметры команды.
async function timeout(ms) {
await new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value);
}
asyncPrint('hello world', 50);
вернутьPromise
объект
async function f() {
return 'hello world';
}
f().then(v => console.log(v))
// "hello world"
async
Внутри функции возникает ошибка, которая приведет к возвратуPromise
объект становитсяreject
условие. Выброшенный объект ошибки будетcatch
получена функция обратного вызова метода
async function f() {
throw new Error('出错了');
}
f().then(
v => console.log('resolve', v),
e => console.log('reject', e)
)
//reject Error: 出错了
Promise
изменение состояния объекта
async
возвращается функциейPromise
объекта, должен дождаться, пока все внутренниеawait
после командыPromise
После выполнения объекта произойдет изменение состояния, если только он не встретитreturn
заявление или выдать ошибку. То есть толькоasync
Асинхронная операция внутри функции будет выполняться после выполненияthen
Функция обратного вызова, указанная методом.
async function getTitle(url) {
let response = await fetch(url);
let html = await response.text();
return html.match(/<title>([\s\S]+)<\/title>/i)[1];
}
getTitle('http://localhost:8080/').then(console.log(123))
await
Заказ
При нормальных обстоятельствах,
await
За командой следуетPromise
объект, возвращает результат этого объекта. если неPromise
объект, он напрямую возвращает соответствующее значение.
async function f() {
// 等同于
// return 123;
return await 123;
}
f().then(v => console.log(v))
// 123
любой
await
Следующие утвержденияPromise
объект становитсяreject
состояние, то весьasync
функция прервет выполнение.
async function f() {
await Promise.reject('出错了');
await Promise.resolve('hello world'); // 不会执行
}
Если вы хотите не прерывать последующие асинхронные операции, даже если предыдущая не удалась. В это время первый
await
помещатьtry...catch
структуру, чтобы независимо от успеха асинхронной операции второйawait
будет казнен.
async function f() {
try {
await Promise.reject('出错了');
} catch(e) {
}
return await Promise.resolve('hello world');
}
f()
.then(v => console.log(v))
// hello world
async
Как работает функция
БудуФункция генератораи автоисполнитель, завернутый в функцию
async function fn(args) {
// ...
}
// 等同于
function fn(args) {
return spawn(function* () {
// ...
});
}
function spawn(genF) {
return new Promise(function(resolve, reject) {
const gen = genF();
function step(nextF) {
let next;
try {
next = nextF();
} catch(e) {
return reject(e);
}
if(next.done) {
return resolve(next.value);
}
Promise.resolve(next.value).then(function(v) {
step(function() { return gen.next(v); });
}, function(e) {
step(function() { return gen.throw(e); });
});
}
step(function() { return gen.next(undefined); });
});
}
строгий режим
Модули ES6 автоматически используют строгий режим, независимо от того, добавляете ли вы
"use strict"
;
Строгий режим в основном имеет следующие ограничения.
- Переменные должны быть объявлены перед использованием
- Параметры функции не могут иметь атрибуты с одинаковыми именами, иначе будет сообщено об ошибке
- нельзя использовать
with
утверждение - Нельзя присваивать значения свойствам только для чтения, иначе будет сообщено об ошибке
- Вы не можете использовать префикс 0 для представления восьмеричного числа, иначе будет сообщено об ошибке
- Невозможно удалить неудаляемые атрибуты, иначе будет сообщено об ошибке
- Переменная не может быть удалена
delete prop
, будет выдано сообщение об ошибке, удалить можно только атрибутdelete global[prop]
-
eval
не вводит переменные во внешнюю область видимости -
eval
а такжеarguments
нельзя переназначить -
arguments
Изменения параметров функции не отражаются автоматически - нельзя использовать
arguments.callee
- нельзя использовать
arguments.caller
- запретить
this
указывает на глобальный объект - нельзя использовать
fn.caller
а такжеfn.arguments
Получить стек вызовов функций - Добавлены зарезервированные слова (например,
protected、static
а такжеinterface
)
export
&& import
использовать
export
&&import
Для выполнения экспорта импорта модуля.
// 写法一
export var m = 1;
// 写法二
var m = 1;
export {m};
// 写法三
var n = 1;
export {n as m};
// 报错
function f() {}
export f;
// 正确
export function f() {};
// 正确
function f() {}
export {f};
import 'lodash';
import 'lodash'; //加载了两次lodash,但是只会执行一次。
export { foo, bar } from 'my_module'; //当前模块不能直接使用foo和bar
// 接口改名
export { foo as myFoo } from 'my_module';
// 整体输出
export * from 'my_module';
//默认接口
export { default } from 'foo';
export { default as es6 } from './someModule';
заключительные замечания
Вышеизложенное - мой опыт после изучения ES6 г-на Жуана Ифэна, надеюсь, вы меня поправите😜
Рекомендация статьи