Alcance y cierre
- tema
- Puntos de conocimiento
- responder
tema
¿Cómo valorar esto en diferentes escenarios de aplicación?
Clasificación: 1: Cuando se llama como una función normal, el objeto al que apunta es el puntero de la ventana, generalmente se entiende como quién llama y a quién apunta.
Por ejemplo:
a () aquí es equivalente a window.a ();
function a(){
var user = "candy";
console.log(this,user); // undefined
console.log(this); // window
};
a();
Siguiente ejemplo:
var o = {
user:"candy:,
fn:function(){
console.log(this.user); // candy
},
};
0.fn();
La fn aquí es llamada por el objeto 0, por lo que en este momento apunta al objeto o
Ejemplo 3:
var o = {
a:1,
b:{
a:2,
fn:function(){
console.log(this.a); // 2
}
}
};
o.b.fn();
Este ejemplo imprime 2, lo que significa que
si hay esto en una función, pero la llamada contiene varias capas, esto apunta solo al objeto que llama en el nivel anterior.
Aunque no hay un atributo a en el objeto b, esto también apunta al objeto b, porque este solo apuntará a su objeto padre, independientemente de si hay algo que quiere en este objeto.
Ejemplo 4: más especial
var o = {
a:1,
b:{
a:2,
function(){
console.log(this,a); // undefined
console.log(this); // window
}
}
};
var j = o.b.fn;
j();
Aquí esto apunta a la ventana, ¿es un poco confuso? De hecho, es porque no entendiste una oración, lo cual también es muy importante.
esto siempre apunta a la última de sus llamadas a objetos , también es para ver cuando se ejecuta quien invocó el ejemplo 4 Aunque la función fn es el objeto b referenciado, pero no se ejecutó cuando la fn asignó a la variable j entonces El punto final es window, que es diferente del ejemplo 3, que ejecuta fn directamente.
2: Use call, apply, bind, el objeto al que apunta este es el objeto entrante. El
método bind () es principalmente para vincular la función a un objeto,
bind () creará una función y el valor de este objeto en el cuerpo de la función será Bind al valor del primer parámetro pasado en bind (),
por ejemplo, fn.bind (obj), en realidad puede entenderse como obj.fn (), en este momento, el this en el fn el cuerpo de la función apunta naturalmente a obj
function fn1(a,b,c){
console.log('this',this);
console.log(a,b,c);
return 'this is fn1';
}
const fn2 = fn1.bind({
x:100},10,20,30);
const res = fn2();
console.log(res);
El resultado impreso es:
3: Cuando se llama al método como un objeto, este devuelve el objeto llamado
4: en el método de clase
5: Llamado en la función de flecha, refiriéndose al alcance superior de la función de flecha
6: esto en el constructor
function FU(){
this.user = "candy";
};
var a = new Fu();
console.log(a.user); // candy
Aquí es porque se usa la nueva palabra clave. La nueva palabra clave
es para crear una instancia de objeto, apuntando al this de su constructor
Pero tenga en cuenta que hay un caso especial
de ☝️ cuando el constructor y el retorno se encuentran:
si el valor de retorno es un objeto, entonces esto apunta al objeto devuelto, y si el valor de retorno no es un objeto, entonces esto apunta a una instancia de la función.
Función de encuadernación manuscrita
Polyfill estándar en MDN
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {
},
fBound = function() {
// this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用
return fToBind.apply(this instanceof fBound ? this : oThis,
// 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
aArgs.concat(Array.prototype.slice.call(arguments)));
};
// 维护原型关系
if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype;
}
// 下行的代码使fBound.prototype是fNOP的实例,因此
// 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
fBound.prototype = new fNOP();
return fBound;
};
}
Escenarios de aplicación de cierres en desarrollo real, con ejemplos
La aplicación práctica de los cierres se utiliza principalmente para encapsular variables. Es decir, las variables se ocultan al exterior para obtenerlas y modificarlas.
function isFirstLoad() {
var _list = []
return function (id) {
if (_list.indexOf(id) >= 0) {
return false
} else {
_list.push(id)
return true
}
}
}
// 使用
var firstLoad = isFirstLoad()
firstLoad(10) // true
firstLoad(10) // false
firstLoad(20) // true
Puntos de conocimiento
- Alcance y variables libres
- Cierre
- esta
Alcance
- Alcance global
- Alcance de la función
- Alcance a nivel de bloque (nuevo en ES6)
Alcance de JavaScript
El alcance es una colección de variables accesibles.
Alcance de JavaScript
En JavaScript, los objetos y las funciones también son variables.
En JavaScript, el alcance es una colección de variables, objetos y funciones accesibles.
Alcance de la función de JavaScript: el alcance se modifica dentro de la función.
Alcance local de JavaScript
Las variables se declaran en funciones y las variables son de ámbito local.
Variables locales: solo se puede acceder dentro de la función.
Ejemplos:
// 此处不能调用 carName 变量
function myFunction() {
var carName = "Volvo";
// 函数内可调用 carName 变量
}
Debido a que las variables locales solo funcionan dentro de funciones, diferentes funciones pueden usar variables con el mismo nombre.
Las variables locales se crean cuando la función comienza a ejecutarse y las variables locales se destruyen automáticamente después de que se ejecuta la función.
Variables globales de JavaScript
Las variables definidas fuera de la función son variables globales.
Las variables globales tienen un alcance global: se pueden utilizar todos los scripts y funciones de la página web.
Ejemplos:
var carName = " Volvo";
// 此处可调用 carName 变量
function myFunction() {
// 函数内可调用 carName 变量
}
Si la variable no está declarada en la función (no se usa la palabra clave var), la variable es una variable global.
En el siguiente ejemplo, carName está en la función, pero es una variable global.
Ejemplos:
// 此处可调用 carName 变量
function myFunction() {
carName = "Volvo";
// 此处可调用 carName 变量
}
Ciclo de vida variable de JavaScript
El ciclo de vida de la variable JavaScript se inicializa cuando se declara.
Las variables locales se destruyen después de que se ejecuta la función.
Las variables globales se destruyen después de que se cierra la página.
Parámetros de función
Los parámetros de función solo funcionan dentro de la función y son variables locales.
Variables globales en HTML
En HTML, las variables globales son objetos de ventana: todas las variables de datos pertenecen a objetos de ventana.
Ejemplos:
//此处可使用 window.carName
function myFunction() {
carName = "Volvo";
}
Variable libre
- Una variable no está definida en el alcance actual, pero se usa
- Vaya al alcance de nivel superior, busque una capa a la vez, hasta que la encuentre
- Si no se encuentra el alcance global, se informará el error xx no definido
Cierre
- Hay dos tipos de manifestaciones para la situación especial de la aplicación.
- La función se pasa como parámetro
- La función se devuelve
como valor de retorno La función se devuelve como valor de retorno
function create(){
const a = 100
return function (){
console.log(a)
}
}
const fn = create()
const a = 200
fn() // 100
La función se pasa como parámetro
function print (fn){
const a = 200
fn()
}
const a = 100
function fn(){
console.olg(a)
}
print(fn) // 100
Por lo tanto, la búsqueda de variables libres está en el lugar donde se define la función, y se busca en el alcance superior, ¡no en el lugar de ejecución! ! ! !
esta
- Como función normal
- Usar llamada aplicar enlace
- Se llama como método de objeto.
- Llamado en el método de clase
- Llamado en función de flecha
Aplicación de cierres en desarrollo real
- Ocultar datos
- Por ejemplo, una herramienta de caché simple
que oculta datos en cierres, solo proporciona API
function craeteCache(){
const data = {
} // 闭包中的数据,被隐藏,不被外界访问
return {
set:function (key,val){
data[key] = val
},
get:function (key){
return data[key]
}
}
}
const c = craeteCache()
c.set('a',100)
console.log(c.get('a'))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js 基础知识 演示</title>
</head>
<body>
<p>一段文字 1</p>
<p>一段文字 2</p>
<p>一段文字 3</p>
</body>
<script>
let a
// for(i=0; i<10;i++){
for(let i=0; i<10;i++){
a = document.createElement('a')
a.innerHTML = i + '<br>'
a.addEventListener('click',function(e){
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
}
</script>
</html >
resumen
- Actuando sobre variables libres
- Cierres: dos formas comunes y reglas de búsqueda de variables gratuitas
- esta