каталог
Чем отличается передок без закидывания от соленой рыбы?
2 Предисловие
Сначала запомните одно предложение:
this
всегда указывает на объект, который последним вызвал его
Запомните еще 2 предложения:
- в нормальном режиме
this
указывая, являетсяthis
при исполненииконтекст - в стрелочной функции
this
указывая, являетсяthis
когда определеноконтекст
цепочка объемов иthis
Это две разные системы, между которыми мало связи.
this
Он привязан к контексту выполнения, то есть каждый контекст выполнения имеетthis
.
Существует 3 типа контекстов выполнения:
- глобальный контекст выполнения
- контекст выполнения функции
-
eval
контекст выполнения
Обратите внимание, что это браузер
this
, а в узлеthis
разные.
Три this в глобальном контексте выполнения
В консоли Chrome введите:this
, вы увидите ответ:
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
в глобальном контексте выполненияthis
указывает наWindow
из.
function foo() {
console.log(this);
}
foo();
Этот код также выводитWindow
,Зачем?
запомнитьthis
То есть тот, кто его называет, указывает на.
Мы вызываем глобальный объектfoo
, что на самом деле эквивалентноwindow.foo()
, то он указывает наWindow
.
Фактически, после выполнения приведенного выше кода небольшие партнеры могут войти в консоль Chrome.
window
, вы увидите, что естьfoo()
метод.
Обратите внимание, что это нестрогий режим. Глобальный объект в строгом режиме
undefined
, он сообщит об ошибкеUncaught TypeError: Cannot read property 'name' of undefined
Четыре this в контексте выполнения функции
Выше мы знаем, что общий метод вызова состоит в том, чтобы вызватьwindow
способ выше.
Как получить текущую функциюthis
Шерстяная ткань?
4.1 Измените это через call/bind/apply
this.myName = 'jsliang';
let foo = function() {
this.myName = 'zhazhaliang';
}
foo();
console.log(window.myName); // 输出啥?
console.log(foo.myName); // 输出啥?
В настоящее времяthis
направлениеwindow
, поэтому выходной результат:
- zhazhaliang
- undefined
пройти черезcall
После привязки:
this.myName = 'jsliang';
let foo = function() {
this.myName = 'zhazhaliang';
}
foo.call(foo);
console.log(window.myName); // 输出啥?
console.log(foo.myName); // 输出啥?
Результат:
- jsliang
- zhazhaliang
Конечно, вы также можете заменитьapply
а такжеbind
, чтобы не быть исчерпаны здесь.
4.2 Вызов настроек метода через объекты
Используйте объект для вызова метода внутри него, методthis
относится к самому объекту.
- Дело 1
let myObj = {
name: 'jsliang',
showThis: function() {
console.log(this.name);
},
};
myObj.showThis(); // 输出啥?
Ответ: выводjsliang
.
Мы всегда должны помнить:кто кому звонит. вот черезmyObj
делает вызов, поэтому в данный моментthis
направлениеmyObj
. а такжеmyObj
естьname: jsliang
, поэтому выводjsliang
.
Конечно, мы должны осознавать себя:
- Случай 2
let myObj = {
myName: 'jsliang',
showThis: function() {
console.log(this.myName);
},
};
let foo = myObj.showThis;
foo(); // 输出啥?
Тогда это становитсяwindow
указал, на данный моментlet foo = myObj.showThis
Просто определение, реальная реализация находится вfoo()
. тогда в этот моментfoo()
Что он делает?window.foo()
какие! вывод без сомненийundefined
.
- Случай 3
let myObj = {
name: 'jsliang',
showThis: function() {
console.log(this.name);
},
};
let foo = myObj.showThis;
foo(); // 输出啥?
В общем, вывод этого кода должен бытьundefined
.
Однако здесь следует отметить, что,window.name
актуаленwindow
имя, этоwindow.open()
Значение второго параметра этого метода для открытия новой веб-страницы.
Итак, вот результатwindow.name
является нулевым значением''
или существующий в настоящее времяwindow
Имя.
jsliangДавайте посмотрим, как это произошло, на примере:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>jsliang</title>
</head>
<body>
<button class="btn">打开新网页</button>
<script>
(function() {
const btn = document.querySelector('.btn');
btn.onclick = function() {
window.open('index.html', 'jsliang 的网页');
}
})()
</script>
</body>
</html>
В консоли только что открытой веб-страницы введитеwindow.name
,Получатьjsliang 的网页
.
В заключение:
- Чтобы вызвать функцию в глобальной среде, внутри функции
this
указывает на глобальную переменнуюwindow
. - Чтобы вызвать метод внутри объекта, контекст выполнения метода
this
указывает на сам объект.
4.3 Установка в конструкторе
this.name = 'jsliang';
let Foo = function() {
this.name = 'zhazhaliang';
}
let foo = new Foo();
console.log(foo.name); // 输出啥?
console.log(window.name); // 输出啥?
ответ:
- zhazhaliang
- jsliang
Прежде чем поставить этот ответ, давайте посмотрим наnew Foo()
Что вы сделали в движке JavaScript:
- Сначала создайте пустой объект
tempObj = {}
. - Тогда позвони
Foo.apply
метод, будетtempObj
так какapply
параметры метода, чтобы приFoo
Когда создается контекст выполнения, егоthis
просто укажите наtempObj
объект. - затем выполнить
Foo
функция, в это времяFoo
в контексте выполнения функцииthis
указал наtempObj
объект. - последнее возвращение
tempObj
объект.
function myNew(func, ...args) {
const tempObj = {};
func.apply(tempObj, args);
return tempObj;
}
this.name = 'jsliang';
let Foo = function(name, age) {
this.name = name;
this.age = age;
}
let foo = myNew(Foo, 'zhazhaliang', 25);
console.log(foo.name); // 输出啥?
console.log(foo.age); // 输出啥?
console.log(window.name); // 输出啥?
Как и выше, мы можем видеть, чтоthis
принадлежатьtempObj
, привязанный кfoo
Поднимитесь, чтобы получить:
- zhazhaliang
- 25
- jsliang
Конечно, зная это, нам еще нужно улучшитьnew
Этот метод рукописного ввода, чтобы не вводить друзей в заблуждениеnew
Просто сделал что-то вроде этого:
function myNew(func, ...args) {
// 1. 判断方法体
if (typeof func !== 'function') {
throw '第一个参数必须是方法体';
}
// 2. 创建新对象
const obj = {};
// 3. 这个对象的 __proto__ 指向 func 这个类的原型对象
// 即实例可以访问构造函数原型(constructor.prototype)所在原型链上的属性
obj.__proto__ = Object.create(func.prototype);
// 为了兼容 IE 可以让步骤 2 和 步骤 3 合并
// const obj = Object.create(func.prototype);
// 4. 通过 apply 绑定 this 执行并且获取运行后的结果
let result = func.apply(obj, args);
// 5. 如果构造函数返回的结果是引用数据类型,则返回运行后的结果
// 否则返回新创建的 obj
const isObject = typeof result === 'object' && result !== null;
const isFunction = typeof result === 'function';
return isObject || isFunction ? result : obj;
}
// 测试
function Person(name) {
this.name = name;
return function() { // 用来测试第 5 点
console.log('返回引用数据类型');
};
}
// 用来测试第 2 点和第 3 点
Person.prototype.sayName = function() {
console.log(`My name is ${this.name}`);
}
const me = myNew(Person, 'jsliang'); // 用来测试第 4 点
me.sayName(); // My name is jsliang
console.log(me); // Person {name: 'jsliang'}
// 用来测试第 1 点
// const you = myNew({ name: 'jsliang' }, 'jsliang'); // 报错:第一个参数必须是方法体
Таким образом, мы знаем, что в конструктореnew
В чем дело.
Пять недостатков этой конструкции и решения
5.1 это во вложенной функции не будет унаследовано от внешней функции
var myObj = {
myName: "jsliang",
showThis: function(){
console.log(this.myName); // 输出啥?
function bar(){
console.log(this.myName); // 输出啥?
}
bar();
},
};
myObj.showThis();
ответ:
- jsliang
- undefined
Решение 1: пройтиthat
контрольthis
направление
var myObj = {
myName: "jsliang",
showThis: function(){
console.log(this.myName); // 输出啥?
let that = this;
function bar(){
console.log(that.myName); // 输出啥?
}
bar();
},
};
myObj.showThis();
Это выводитjsliang
.
Решение 2. Решите проблему со стрелочными функциями ES6.
var myObj = {
myName: "jsliang",
showThis: function(){
console.log(this.myName); // 输出啥?
const bar = () => {
console.log(this.myName); // 输出啥?
}
bar();
},
};
myObj.showThis();
Это связано с тем, что стрелочные функции в ES6 не создают собственного контекста выполнения, поэтомуthis
зависит от его внешней функции, т. е. от того, кто его называетthis
от кого.
5.2 В обычных функциях это указывает на окно глобального объекта
На практике нам не нужен контекст выполнения функции.this
По умолчанию указывается на глобальный объект, потому что это нарушит границу данных и вызовет некоторые неверные операции.
Если вы хотите, чтобы функция выполняла контекстthis
указать на объект, лучший способ - передатьcall
способ отображения вызова.
Эту проблему можно решить, установив JavaScriptстрогий режимрешать. В строгом режиме выполняет функцию по умолчанию, чей контекст выполнения функцииthis
значениеundefined
Это решает вышеуказанную проблему.
6. Это указывает на в React
Источник:this.handleClik = this.handleClick.bind(this);
почему ты хочешь сделать это?
Давайте сначала посмотрим на сравнение кода:
Код 1: это в поле вызова объекта
const test = {
myName: 'jsliang',
getName: function() {
console.log(this.myName); // 输出 jsliang
}
};
test.getName();
Код 2: хранится в глобальной переменной
const test = {
myName: 'jsliang',
getName: function() {
console.log(this.myName); // 输出 undefined
}
};
const func = test.getName;
func();
Поэтому метод в React если и не обязывающий, тоthis
будет испорчено указание на глобальный объектwindow
.
Итак, как решить эту проблему?
Примечание: пользователи сети отметили:Сравнение следующих четырех методов на самом деле неверно, а обычные объекты нельзя сравнивать с классами.
Конечно,jsliangЯ все еще хочу перечислить здесь
конкретные выводы, поверьте
202X
Когда мы будем проводить повторный обзор в 2019 году, мы постепенно ответим на наши внутренние сомнения, когда у нас будет возможность.
Поэтому во избежание конфликтов друзья могут пропустить эту главу.
6.1 Решение 1: привяжите это заранее
const test = {
myName: 'jsliang',
getName: function() {
console.log(this.myName); // 输出 jsliang
}
};
test.getName = test.getName.bind(test);
const func = test.getName;
func();
Соответствует React в:
constructor (props) {
this.handleClick = this.handleClick.bind(this);
}
<button onClick={this.handleClick}>btn 1</button>
6.2 Решение 2: привязать привязать это при вызове
const test = {
myName: 'jsliang',
getName: function() {
console.log(this.myName); // 输出 jsliang
}
};
const func = test.getName.bind(test);
func();
Соответствует React в:
<button onClick={this.handleClick.bind(this)}>btn 2</button>
6.3 Решение 3. Возврат стрелочной функции
const test = {
myName: 'jsliang',
getName: function() {
console.log(this.myName); // 输出 jsliang
}
};
const func = () => test.getName();
func();
Соответствует React в:
<button onClick={() => this.handleClick()}>btn 3</button>
6.4 Решение 4. Превратите вызывающий метод в стрелочную функцию (сбой)
const test = {
myName: 'jsliang',
getName: () => {
console.log(this.myName);
}
};
const func = test.getName;
func();
Соответствует React в:
handleClick2 = () => {
console.log('jsliang 2021');
}
<button onClick={this.handleClick2}>btn 4</button>
Однако этот метод терпит неудачу, возвращаяundefined
, какова причина?
Пользователи сети отметили:
- Сравнение этих четырех методов на самом деле неверно, а обычные объекты нельзя сравнивать с классами.
Конечно,jsliangЯ все еще хочу перечислить их, с конкретными выводами.Я верю, что у меня будет возможность шаг за шагом ответить на мои внутренние сомнения.
6.5 React this указывает на фактическое содержимое
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// 为了在回调中使用 `this`,这个绑定是必不可少的
// this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log(this);
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
Зная вышеуказанный метод, после компиляции он становится:
"use strict";
// ...代码省略
var Toggle = /*#__PURE__*/function (_React$Component) {
_inherits(Toggle, _React$Component);
var _super = _createSuper(Toggle);
function Toggle(props) {
var _this;
_classCallCheck(this, Toggle);
_this = _super.call(this, props);
_this.state = {
isToggleOn: true
}; // 为了在回调中使用 `this`,这个绑定是必不可少的
// this.handleClick = this.handleClick.bind(this);
return _this;
}
_createClass(Toggle, [{
key: "handleClick",
value: function handleClick() {
console.log(this); // 输出是 undefined
}
}, {
key: "render",
value: function render() {
return /*#__PURE__*/React.createElement("button", {
onClick: this.handleClick
}, this.state.isToggleOn ? 'ON' : 'OFF');
}
}]);
return Toggle;
}(React.Component);
В основном см._createClass
метод, первый параметр — созданный класс, второй параметр — массив, массив — метод в созданном классе.
Очевидно, в кодеhandleClick
выходthis
, Определенно естьundefined
.
а такжеrender
метод возвращаетReact.createElement
, в этом методеthis
указал на_createClass
Первый параметр метода, которыйToggle
.
На данный момент, если этот метод становится функцией стрелки:
handleClick = () => {
console.log(this);
}
Теперь функция стрелкиthis
Контекст, в котором он был определен.
Когда мы нажмем кнопку, она будет вызванаhandleClick
метод для обработки события, в то время какhandleClick
вToggle
метод, поэтомуthis
Относится кToggle
этот класс.
6.6 React это указывает на решение
import React, { Component } from 'react'
class App extends Component {
constructor (props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick () {
console.log('jsliang 2020');
}
handleClick2 = () => {
console.log('jsliang 2021');
}
render () {
// 四种绑定方法
return (
<div className='App'>
{/* 方法一:通过 constructor 中进行 bind 绑定 */}
<button onClick={this.handleClick}>btn 1</button>
{/* 方法二:在里边绑定 this */}
<button onClick={this.handleClick.bind(this)}>btn 2</button>
{/* 方法三:通过箭头函数返回事件 */}
<button onClick={() => this.handleClick()}>btn 3</button>
{/* 方法四:让方法变成箭头函数 */}
<button onClick={this.handleClick2}>btn 4</button>
{/* 额外:直接调用不需要绑定 this */}
{this.handleClick()}
</div>
)
}
}
export default App;
Семь Резюме
Сначала запомните одно предложение:
this
всегда указывает на объект, который последним вызвал его
Запомните еще 2 предложения:
- в нормальном режиме
this
указывая, являетсяthis
при исполненииконтекст - в стрелочной функции
this
указывая, являетсяthis
когда определеноконтекст
Восемь тем
8.1 Анализ этой темы 5 шагов
- Первый вопрос
var name = 'window name';
function a() {
var name = 'jsliang';
console.log(this.name); // 输出啥?
console.log('inner:' + this); // 输出啥?
}
a();
console.log('outer:' + this); // 输出啥?
Что выводит приведенный выше код?
Отвечать:
window name
inner:window name
outer:window name
Анализ: здесьa()
можно рассматривать какwindow.a()
, так что оба указывают наwindow
внутри.
- вопрос 2
var name = 'window name';
var a = {
name: 'jsliang',
fn: function () {
console.log(this.name); // 输出啥?
}
}
a.fn();
Что выводит приведенный выше код?
Ответ: джслянг
Анализ: это сейчасa.fn()
, так что это указывает наa
, поэтому выводjsliang
- Вопрос 3
var name = 'window name';
var a = {
// name: 'jsliang',
fn: function () {
console.log(this.name); // 输出啥?
}
}
a.fn();
Что выводит приведенный выше код?
Ответ: неопределенный
Анализ: Очевидно,a
здесь нетname
метод, поэтомуa.fn()
не могу найтиa
объект имеетname
, поэтому выводundefined
- Вопрос 4
var name = 'window name';
var a = {
name: 'jsliang',
fn: function () {
console.log(this.name); // 输出啥?
}
}
var f = a.fn;
f();
Что выводит приведенный выше код?
Отвечать:window name
Разбор: кодvar f = a.fn
не звонилa.fn
, а определение. существуетf()
был вызван, когдаfn()
даwindow.fn()
, поэтому он указывает наwindow
, поэтому выводwindow name
- Вопрос 5
var name = 'window name';
function fn() {
var name = 'jsliang';
function innerFn() {
console.log(this.name);
};
innerFn();
}
fn();
Отвечать:window name
Анализ: Маленькие друзья понимают и понимают
8.2 это let/const
let a = 10;
const b = 20;
function foo() {
console.log(this.a);
console.log(this.b);
}
foo();
console.log(window.a);
Что выводит приведенный выше код?
Отвечать:undefined
,undefined
,undefined
Анализ: еслиvar
изменился наlet
илиconst
, переменная не привязана кwindow
, поэтому он распечатает триundefined
.
8.3 это стрелочные функции
var name = 'window name';
var a = {
name: 'jsliang',
func1: function () {
console.log(this.name);
},
func2: function () {
setTimeout(() => {
this.func1();
}, 100);
},
};
a.func1(); // 输出啥?
a.func2(); // 输出啥?
Что выводит приведенный выше код?
Отвечать:
jsliang
jsliang
Анализ: стрелочные функцииthis
указывает на определение функцииthis
, а не во время выполнения. Стрелочные функции не имеютthis
привязка, значение которой должно быть определено путем поиска по цепочке областей видимости, если стрелочная функция содержится в нестрелочной функции, тоthis
Привязка — ближайший слой нестрелочных функцийthis
,иначе,this
дляundefined
.
8.4 Найдите выходной результат
function foo () {
console.log(this.a)
};
var obj = { a: 1, foo };
var a = 2;
var foo2 = obj.foo;
var obj2 = { a: 3, foo2: obj.foo }
obj.foo(); // 输出啥?
foo2(); // 输出啥?
obj2.foo2(); // 输出啥?
Что выводит приведенный выше код?
отвечать:
1
2
3
Разобрать:
-
obj.foo()
:obj
передачаfoo()
, поэтому укажитеobj
, выход1
-
foo2()
:в реальностиwindow.foo2()
,направлениеwindow
, выход2
-
obj2.foo2()
:obj2
передачаfoo2()
,направлениеobj2
, выход3
8.5 Проблема потери неявной привязки
8.5.1 Найдите выходной результат
function foo() {
console.log(this.a);
}
function doFoo(fn) {
console.log(this);
fn();
}
var obj = { a: 1, foo };
var a = 2;
doFoo(obj.foo); // 输出啥?
Что выводит приведенный выше код?
Отвечать:Window {...}
,2
Разобрать:Проблема потери неявной привязки.deFoo
передать параметрыobj.foo
когда, в этот моментfoo
не реализовано, поэтому вdoFoo
серединаfn()
эквивалентноwindow.fn()
, поэтому указывает наwindow
Ла!
Обратите внимание, что при звонке в этот раз искомый
fn
даwindow
Вверхfn
, вместоdoFoo
внутренний,doFoo
не установленfn
Сюда.
8.5.2 Найдите выходной результат
function foo() {
console.log(this.a);
}
function doFoo(fn) {
console.log(this);
fn();
}
var obj = { a: 1, foo };
var a = 2;
var obj2 = { a: 3, doFoo };
obj2.doFoo(obj.foo); // 输出啥?
Что выводит приведенный выше код?
Отвечать:{ a: 3, doFoo: f }
,2
Разобрать:
- В данный момент
fn()
звоните, найденное место по-прежнемуwindow.foo()
, поэтому при вызове он будет указывать наwindow
. - здесь
fn()
Он приходит путем передачи параметров, а неdoFoo
существует в нем, поэтому при выполненииthis
найденоfoo
Определенное местоположение, или фактическиwindow.fn()
- Как исправить эту проблему?
function foo() {
console.log(this.a);
}
function doFoo(fn) {
console.log(this);
fn.call(this);
}
var obj = { a: 1, foo };
var a = 2;
var obj2 = { a: 3, doFoo };
obj2.doFoo(obj.foo);
8.6 Проблемы с привязкой дисплея
8.6.1 Найдите выходной результат
function foo() {
console.log(this.a);
}
var obj = { a: 1 };
var a = 2;
foo(); // 输出啥?
foo.call(obj); // 输出啥?
foo().call(obj); // 输出啥?
Что выводит приведенный выше код?
Отвечать:
2
1
2
Uncaught TypeError: Cannot read property 'call' of undefined
Разобрать:
-
foo()
:направлениеwindow
-
foo.call(obj)
:Будуfoo
изthis
указал наobj
-
foo().call(obj)
: выполнить первымfoo()
, выход2
, то он безвозвратный, эквивалентныйundefined.call(obj)
, сообщить об ошибке напрямую
8.6.2 Найдите выходной результат
function foo() {
console.log(this.a);
return function () {
console.log(this.a);
};
}
var obj = { a: 1 };
var a = 2;
foo(); // 输出啥?
foo.call(obj); // 输出啥?
foo().call(obj); // 输出啥?
Что выводит приведенный выше код?
Отвечать:
2
1
2
1
Анализ: Излишне говорить, что первые три вопроса такие же, как и в предыдущем вопросе.
последнийreturn function { this.a }
Поэтому этот метод статьcall(obj)
, поэтому выводobj
серединаa
, то есть,1
.
8.7 Найдите выходной результат
function Foo() {
'use strict'
console.log(this.location);
}
Foo();
пожалуйста, выберите:
- A: Текущее окно
Location
объект - Б:
undefined
- С:
null
- Д:
TypeError
Ответ: Д
Разобрать: если нетuse strict
, затем выберите A; если это строгий режим, это D, запрещенный в строгом режимеthis
Ключевое слово указывает на глобальный объект.
8.8 Уточняющие вопросы
let userInfo = {
name: 'jsliang',
age: 25,
sex: 'male',
updateInfo: function(){
// 模拟 XMLHttpRequest 请求延时
setTimeout(function(){
this.name = "zhazhaliang"
this.age = 30;
this.sex = 'female';
}, 1000);
},
};
userInfo.updateInfo();
решить здесьthis
Укажите на проблему и получите конечный результат:
{
name: "zhazhaliang",
age: 30,
sex: "female",
updateInfo: function(),
}
Отвечать:setTimeout(() => {})
Вот и все.
9 ссылок
- Еще 40 вопросов к этому интервью, кислых и крутых, продолжение[Рекомендация по прочтению: 1 час]
- это, это, обсудите это еще раз в javascript, очень подробно【Рекомендация по прочтению: 10 минут】
- это в JavaScript【Рекомендация по прочтению: 10 минут】
- Углубленная интерпретация JavaScript из спецификации ECMAScript.【Рекомендация по прочтению: 20 минут】
- Продвинутые основы интерфейса (7): исчерпывающая интерпретация этого【Рекомендация по прочтению: 20 минут】
- Основной менталитет JavaScript - это【Рекомендация по прочтению: 20 минут】
- 11 | this: Сделайте это понятным с точки зрения контекста выполнения JavaScript.【Рекомендация по прочтению: 2 часа】
- Говоря об этом, указывая на реакцию【Рекомендация по прочтению: 10 минут】
- Оптимизация производительности реакции【Рекомендация по прочтению: 5 минут】
- Почему обработчики событий React должны использовать bind(this)【Рекомендация по прочтению: 10 минут】
- Это вызвано привязкой в конструкторе React для понимания (почему метод компонента React должен использовать привязку для привязки этого)【Рекомендация по прочтению: 20 минут】
- Это в this.handleClick = this.handleClick.bind(this) в React указывает на проблему【Рекомендация по прочтению: 10 минут】
репозиторий документации jsliang предоставляетсяЛян ЦзюньронгиспользоватьCreative Commons Attribution-NonCommercial-ShareAlike 4.0 Международная лицензияЛицензия.
на основеGitHub.com/l ian Jun Ron…Создание работ выше.
Права на использование, отличные от разрешенных в настоящем Лицензионном соглашении, могут быть получены отCreative Commons.org/licenses/не…получено в.