предисловие
Некоторое время назад было телефонное интервью. Я помню, что в нем был контент. Меня спрашивали о вещах, связанных с http. Я тайно почувствовал облегчение. Я дважды прочитал http-диаграмму, и знания в ней были в основном уточнены и записаны. .http?Это не так просто?
balabala много говорил, от http до https до http2, и добавил некоторые http3 вещи.Балабала много говорил, полный уверенности.Кто знает вопрос может задать мне.
Интервьюер: http2 реализует мультиплексирование, почему нельзя мультиплексировать http1.x?
Я: Я сказал, потому что http1.x должен прийти по порядку.
Интервьюер: Да, но почему http1.x следовать за заказ?
Я: Эм... я не знаю об этом...
Интервьюер: HTTP/1.1 — это протокол, основанный на сегментации и разборе текста, и в нем нет порядкового номера. При мультиплексировании последовательность будет беспорядочной. HTTP2 использует метод кадра, что эквивалентно разрезанию на части. соответствующий серийный номер, поэтому возможно мультиплексирование.
Дело не в том, как этот вопрос, а в том, что этот вопрос заставил меня осознать, что мое исследование недостаточно глубоко, я должен знать, что это такое и почему это так. вчерашнее интервью. Подводя небольшой итог
текст
что это такое?
Подать заявку, вызов, связывание - все встроенные API для функций в JS. Вызов их может указать выполнение этого для функции, а также может передавать параметры.
как использовать?
//apply
func.apply(thisArg, [argsArray])
//call
fun.call(thisArg, arg1, arg2, ...)
//bind
const newFun = fun.bind(thisArg, arg1, arg2, ...)
newFun()
Apply и call отличаются передачей параметров, но обе являются функциями, которые будут вызываться одновременно при вызове, но bind вернет функцию, связанную с this.
Нам нужно знать еще одну вещь, которая является указателем на this.
указатель на это
Направление this определяется при вызове функции, и его можно условно разделить на пять типов.
1. Привязка по умолчанию
Привязка по умолчанию обычно происходит в функции обратного вызова, и функция вызывается напрямую;
function test() {
//严格模式下是undefined
//非严格模式下是window
console.log(this);
}
setTimeout(function () {
//setTimeout的比较特殊
//严格模式和非严格模式下都是window
console.log(this);
});
arr.forEach(function () {
//严格模式下是undefined
//非严格模式下是window
console.log(this);
});
2. Неявное связывание
Эту популярную мысль можно выразить одним предложением: тот, кто это называет, указывает на кого.
const obj = {
name:'joy',
getName(){
console.log(this); //obj
console.log(this.name); //joy
}
};
obj.getName();
3. Показать вызов привязки, применить, привязать
const obj1 = {
name: 'joy',
getName() {
console.log(this);
console.log(this.name);
}
};
const obj2 = {
name: 'sam'
};
obj1.getName.call(obj2); //obj2 sam
obj1.getName.apply(obj2); //obj2 sam
const fn = obj1.getName.bind(obj2);
fn();//obj2 sam
4. новая привязка
function Vehicle() {
this.a = 2
console.log(this);
}
new Vehicle(); //this指向Vehicle这个new出来的对象
5. Функция стрелки es6
Стрелочная функция es6 особенная.Этот стрелочной функции-это это родительской области, а не это вызова.Вы должны знать, что все первые четыре метода определяются во время вызова, то есть динамический, в то время как this стрелочной функции является статическим. Он определяется при объявлении. Это больше соответствует лексической области видимости js.
window.name = 'win';
const obj = {
name: 'joy',
age: 12,
getName: () => {
console.log(this); //其父作用域this是window,所以就是window
console.log(this.name); //win
},
getAge: function () {
//通过obj.getAge调用,这里面this是指向obj
setTimeout(() => {
//所以这里this也是指向obj 所以结果是12
console.log(this.age);
});
}
};
obj.getName();
obj.getAge();
Поскольку есть 5 способов привязки этого, должен быть приоритетный порядок
Стрелочная функция -> новая привязка -> явный вызов привязки/привязка/применение -> неявная привязка -> привязка по умолчанию
Вывод прямо дан здесь, а заинтересованные друзья могут убедиться в этом сами
применить применить
Сначала реализуем применение
- Сначала расширьте метод на прототипе функции и получите 2 параметра,
Function.prototype.myApply = function (context, args) {
}
- Потому что если контекст не передать, this будет указывать на окно, и аргументы тоже будут отказоустойчивыми.
Function.prototype.myApply = function (context, args) {
//这里默认不传就是给window,也可以用es6给参数设置默认参数
context = context || window
args = args ? args : []
}
- Вам нужно вспомнить пять способов привязки this Теперь пришло время привязать this к вызываемой функции. Привязка по умолчанию и new здесь определенно не используются, здесь неявная привязка используется для достижения явной привязки.
Function.prototype.myApply = function (context, args) {
//这里默认不传就是给window,也可以用es6给参数设置默认参数
context = context || window
args = args ? args : []
//给context新增一个独一无二的属性以免覆盖原有属性
const key = Symbol()
context[key] = this
//通过隐式绑定的方式调用函数
context[key](...args)
}
- Последний шаг — вернуть возвращаемое значение вызова функции и удалить атрибут в контексте, чтобы он не повлиял
Function.prototype.myApply = function (context, args) {
//这里默认不传就是给window,也可以用es6给参数设置默认参数
context = context || window
args = args ? args : []
//给context新增一个独一无二的属性以免覆盖原有属性
const key = Symbol()
context[key] = this
//通过隐式绑定的方式调用函数
const result = context[key](...args)
//删除添加的属性
delete context[key]
//返回函数调用的返回值
return result
}
Такое простое применение реализовано, могут быть какие-то граничные проблемы и неверные суждения, которые нужно дорабатывать, поэтому здесь мы не будем продолжать оптимизацию.
Теперь, когда применение реализовано, вызов также очень прост, в основном потому, что параметры не совпадают.
реализовать вызов
Просто перейдите к коду здесь
//传递参数从一个数组变成逐个传参了,不用...扩展运算符的也可以用arguments代替
Function.prototype.myCall = function (context, ...args) {
//这里默认不传就是给window,也可以用es6给参数设置默认参数
context = context || window
args = args ? args : []
//给context新增一个独一无二的属性以免覆盖原有属性
const key = Symbol()
context[key] = this
//通过隐式绑定的方式调用函数
const result = context[key](...args)
//删除添加的属性
delete context[key]
//返回函数调用的返回值
return result
}
реализовать привязку
Разница между bind и apply в том, что bind это функция связывания.Apply вызывается напрямую.На самом деле я хочу реализовать его тоже очень просто,то есть возвращает функцию,которая выполняет вышеуказанную операцию.Однако есть нужно судить о Point, потому что он возвращает новую функцию, учитывать использование New, а NEW имеет более высокий приоритет, поэтому необходимо судить о вызове New, и одна особенность заключается в том, что вызывается Bind, и новое поколение вновь созданной функции также может быть передано, эффект тот же, поэтому этот кусок должен быть обработан Поскольку приложение уже достигнуто, оно будет заимствовано здесь, а не заимствовано.
Function.prototype.myBind = function (context, ...args) {
const fn = this
args = args ? args : []
return function newFn(...newFnArgs) {
if (this instanceof newFn) {
return new fn(...args, ...newFnArgs)
}
return fn.apply(context, [...args,...newFnArgs])
}
}
Обо всех вышеприведенных реализациях можно судить немного больше, например, если вызов не является функцией, то она вернет или выкинет ошибку, я не буду здесь этим заниматься.
Выше приведена реализация apply, call, bind
конец
"Я споткнулся и столкнулся на пути обучения. Я надеюсь становиться все лучше и лучше и как можно скорее стать большой коровой. Думайте больше, обобщайте больше и больше практикуйтесь. Выработайте привычку учиться на протяжении всей жизни. Давай