Résumé de l'entretien JavaScript 2021, vérification des erreurs et examen

Introduction: J'ai récemment passé en revue les questions d'entrevue, j'ai compris la portée et la fréquence des questions, passé en revue certains points sujets aux erreurs et les partager en même temps.J'espère vous aider un peu!

1、点(.) Priorité des = opérateurs VS 

    let a = {n : 1};
    let b = a;
    a.x = a = {n: 2};    
    console.log(a.x);
    console.log(b.x);

Quelle est la sortie?

indéfini
{n: 2}

La priorité de point (.) Et = est impliquée ici, car dot (.) A une priorité plus élevée que =, ce code peut également être écrit comme ceci:

    let a = {n : 1};
    let b = a;
    //a.x = a = {n: 2};    
    a.x ={n: 2}
    a = {n: 2};
    console.log(a.x);
    console.log(b.x);

Résumé: En raison de problèmes de priorité, ax doit être attribué en premier, puis a est attribué. Dans le développement quotidien, ce type de continuité est également très courant. Généralement, a = b = c = 0 s'écrit comme ceci, bien sûr. Il n'y aura pas d'ambiguïtés ni de défauts d'écriture, mais comme dans le cas de l'exemple ci-dessus, il y aura des effets inattendus (on estime que cet effet n'est pas ce que nous voulons), et le code doit être aussi simple et clair que possible, alors utilisez et attendez Soyez prudent lorsque vous l'utilisez, il est facile à utiliser et il n'est pas abusé.

 

2. Portée


    var a = 0,b = 0;
    function A(a) {
        A = function (b) {
            console.log(a + b++)
        }
        console.log(a++)
    }
    A(1)
    A(2)

Analyse

var a = 0,b = 0;
    function A(a) {
        //A(1)调用运行情况:
        /*
            1.A函数被重置为:
                function (b) {
                    console.log(a + b++)
                }
            2.执行打印console.log(a++),因为此时的a是形参,形参的值是传入的1,所以打印1,而且形参a执行了++,此时值为2
        */
        A = function (b) {
            //A(2)调用情况
            /*
                这个a是采用的闭包,所以是2,b是形参也是2,所以打印的是4
            */
            console.log(a + b++)
        }
        console.log(a++)
    }
    A(1)//A(1)调用
    A(2)//A(2)调用

 

3. Promotion variable

Thème 1:

var a = 10;
(function a(){
    console.log(a)
    a = 20;
    console.log(window.a)
    var a = 30
    console.log(a)
})()

Équivalent à

var a = 10;
(function a(){
	//内部作用域
	var a;//var a = 30 中的声明被提升
    console.log(a)//undefined
    a = 20;//内部作用域的a赋值20
    console.log(window.a)//window中的a依然是10 
    a = 30//内部作用域的a赋值30
    console.log(a)//打印内部作用域中的a 30
})()

Thème 2:

var name = '张三';
function fn() {
    if (typeof name === 'undefined') {
        var name = '李四';
        console.log('辛苦了: ' + name);
    } else {
        console.log('吃饭没: ' + name);
    }
}
fn();

Équivalent à

var name = '张三';
function fn() {
	var name ;// var name = '李四'; 中的声明被提前到函数作用域里面
    if (typeof name === 'undefined') {//此时成立
        name = '李四';
        console.log('辛苦了: ' + name);
    } else {
        console.log('吃饭没: ' + name);
    }
}
fn();

Question 3:

var a=10,b=20,c=30;
function fn(a){
	a=1;
	var b=2;
	c=3
}
fn(100)
console.log(a,b,c);

Équivalent à

var a=10,b=20,c=30;
function fn(a){
	//函数调用,形成局部作用域,形参a在内部局部作用域 a=100
	var b;//b在内部变量提升
	a=1;//内部局部作用域 a设置为1
	b=2;//内部局部作用域 b设置为2
	c=3;//全局作用与c被设置值3
}
fn(100)
//可以看到只有c被局部作用域修改了
console.log(a,b,c);//10 20 3

Question 4:

if(!("a" in window)){
	var a = 10
}
console.log(a);

Équivalent à

var a;//变量提升了
if(!("a" in window)){//"a" in window 成立了,所以这个条件不执行
	a = 10
}
console.log(a);//'undefined

Question 5:

var fn = 'hello';
(function(fn){
	console.log(fn);
	var fn=fn||'world';
	console.log(fn)
})(fn)
console.log(fn);

Équivalent à

var fn = 'hello';
(function(fn){
	//内部作用域
	//形参先被定义 所以fn=hello
	//var fn;//var fn=fn||'world';变量提升到这里,但是会被忽略,因为形参的fn先被定义
	console.log(fn);//打印hello
	fn=fn||'world';//这句fn还是等于hello
	console.log(fn)//打印hello
})(fn)//hello作为实参传入
console.log(fn);//打印hello
//最终结果是:hello hello hello

Question 6:

var n=10;
function fn(n){
     console.log(n);
     var n= 20;
     console.log(n);
     function n(){
     	
     }
     console.log(n);
}
 fn(n);
 console.log(n);

Équivalent à

var n=10;
function fn(n){
	//局部作用域
	//n根据形参首先定义 n=10
	//函数会提升,覆盖了n,此时n为函数
	 function n(){
     	
     }
     //var n;//var n =20中的var n 被提升到此处,但是会被忽略
     console.log(n);//打印函数
      n= 20;//n被赋值为20
     console.log(n);//打印20
    	//函数已经提升
     console.log(n);//打印20
}
 fn(n);//实参n=10传入调用
 console.log(n);//打印10

Question 7:

 function fn(fn){
     console.log(fn);
     var fn = 20;
     console.log(fn);
     function fn(){
     	console.log(fn);
     }
}
fn(30);
var fn = 10;
console.log(fn);

Équivalent à

 function fn(fn){
 	//局部作用域 fn被形参设置 fn为30
 	 function fn(){//函数被提升到此次,并且fn设置为函数
     	console.log(fn);
     }
     var fn ;//var fn = 20;中的var变量提升到这里,但是会被忽略
     console.log(fn);//打印函数
     fn = 20;//赋值20
     console.log(fn);//打印20
}
var fn;//var fn = 10;这句中的var变量提升到这里,但是会被忽略,因为已经存在函数 fn 了
fn(30);//执行函数
fn = 10;//赋值fn为10
console.log(fn);//打印10

Finalement, il sera imprimé à son tour: fonction fn 20 10

4. Lié à la fermeture

Sujet 1: valeur de retour (la plus couramment utilisée)

	function fn(){
			var name="hello";
			return function(){
				return name;
			}
		}
		var fnc = fn();
		console.log(fnc())//hello

C'est facile à comprendre, c'est de renvoyer le nom sous la forme d'une fermeture.

Thème 2: Affectation des fonctions

 var fn2;
		function fn(){
			var name="hello";
			//将函数赋值给fn2
			fn2 = function(){
				return name;
			}
		}
		fn()//要先执行进行赋值,
		console.log(fn2())//执行输出fn2

Définissez la valeur de la fonction fn2 dans la fermeture. L'attribut name est mémorisé sous la forme de la fermeture, et l'exécution sortira bonjour.

Thème 3: Paramètres de fonction

        function fn(){
			var name="hello";
			return function callback(){
				return name;
			}
		}
		var fn1 = fn()//执行函数将返回值(callback函数)赋值给fn1,
		
		function fn2(f){
			//将函数作为参数传入
			console.log(f());//执行函数,并输出
		}
		fn2(fn1)//执行输出fn2

Utilisez une fermeture pour renvoyer une fonction, utilisez cette fonction comme paramètre d'une autre fonction, exécutez cette fonction dans une autre fonction, et enfin sortez bonjour

Thème 4: IIFE (fonction auto-exécutable)

        (function(){
			var name="hello";
			var fn1= function(){
				return name;
			}
			//直接在自执行函数里面调用fn2,将fn1作为参数传入
			fn2(fn1);
		})()
		function fn2(f){
			//将函数作为参数传入
			console.log(f());//执行函数,并输出
		}

Passez la fonction encapsulée fn1 à fn2 directement dans la fonction auto-exécutable, et appelez-la comme paramètre pour obtenir le résultat bonjour

Thème 5: Affectation des boucles

//每秒执行1次,分别输出1-10
	for(var i=1;i<=10;i++){
		(function(j){
			//j来接收
			setTimeout(function(){
				console.log(j);
			},j*1000);
		})(i)//i作为实参传入
	}

Thème 6: Getters et setters

    function fn(){
		var name='hello'
		setName=function(n){
			name = n;
		}
		getName=function(){
			return name;
		}
		
		//将setName,getName作为对象的属性返回
		return {
			setName:setName,
			getName:getName
		}
	}
	var fn1 = fn();//返回对象,属性setName和getName是两个函数
	console.log(fn1.getName());//getter
		fn1.setName('world');//setter修改闭包里面的name
	console.log(fn1.getName());//getter

Lors de la sortie de Hello pour la première fois, utilisez setter pour afficher le monde. Cela peut être encapsulé dans une méthode publique pour éviter que des propriétés et des fonctions indésirables ne soient exposées à l'extérieur.

Sujet 7: Itérateur (exécuter une fonction pour prendre une valeur vers le bas)

        var arr =['aa','bb','cc'];
		function incre(arr){
			var i=0;
			return function(){
				//这个函数每次被执行都返回数组arr中 i下标对应的元素
				 return arr[i++] || '数组值已经遍历完';
			}
		}
		var next = incre(arr);
		console.log(next());//aa
		console.log(next());//bb
		console.log(next());//cc
		console.log(next());//数组值已经遍历完

Sujet 8: Distinguer pour la première fois (le même paramètre, la fonction ne sera pas exécutée à plusieurs reprises)

         var fn = (function(){
				var arr=[];//用来缓存的数组
					return function(val){
						if(arr.indexOf(val)==-1){//缓存中没有则表示需要执行
							arr.push(val);//将参数push到缓存数组中
							console.log('函数被执行了',arr);
							//这里写想要执行的函数
						}else{
							console.log('此次函数不需要执行');
						}
						console.log('函数调用完打印一下,方便查看已缓存的数组:',arr);
					}
				})();
		
		fn(10);
		fn(10);
		fn(1000);
		fn(200);
		fn(1000);

Résultats de la

On voit clairement que la première exécution sera sauvegardée et que l'exécution sera à nouveau directement récupérée.

Sujet 9: Mise en cache

//比如求和操作,如果没有缓存,每次调用都要重复计算,采用缓存已经执行过的去查找,查找到了就直接返回,不需要重新计算
	 
	 var fn=(function(){
	 	var cache={};//缓存对象
	 	var calc=function(arr){//计算函数
	 		var sum=0;
	 		//求和
	 		for(var i=0;i<arr.length;i++){
		 		sum+=arr[i];
		 	}
		 	return sum;
	 	}
	 	
	 	return function(){
	 		var args = Array.prototype.slice.call(arguments,0);//arguments转换成数组
	 		var key=args.join(",");//将args用逗号连接成字符串
		 	var result , tSum = cache[key];
		 	if(tSum){//如果缓存有	
		 		console.log('从缓存中取:',cache)//打印方便查看
		 		result = tSum;
		 	}else{
		 		//重新计算,并存入缓存同时赋值给result
			 	result = cache[key]=calc(args);
			 	console.log('存入缓存:',cache)//打印方便查看
		 	}
		 	return result;
	 	}
	 })();
	fn(1,2,3,4,5);
	fn(1,2,3,4,5);
	fn(1,2,3,4,5,6);
	fn(1,2,3,4,5,8);
	fn(1,2,3,4,5,6);

Résultat de sortie:

Sujet 10: Fonction d'étranglement

La fonction de la fonction de limitation est d'exécuter la fonction une seule fois dans un temps limité, tel que:

1. Soumettre le bouton (peut éviter une soumission répétée, bien sûr, non seulement cette méthode, il est également possible de définir le bouton comme indisponible).

2. Lorsque la fréquence de déclenchement du défilement, du survol de la souris, de la souris est élevée.

Le principe principal est de définir un indicateur dans la fermeture. L'indicateur est défini sur true dans un laps de temps limité et la fonction ne sera pas exécutée s'il est à nouveau cliqué. Une fois la fonction setTimeout exécutée, l'indicateur est défini sur flase, et l'exécution peut continuer. 

 
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=GBK">
        <style>
        *{
        	margin:0;padding:0;
        }
        </style>
        </head>
        <body>
       		<div class="box" id="div_box" >
       			<button onclick="fn1()">test</button>
       		</div>
        </body>
        
<script>
//节流函数
function throttle(fn,delay){
	var flag=false;
	var timer=null;
	return function(){
		var args=[].slice.call(arguments,0);//将参数转成数组
		var context=this;
		if(flag){//如果在限定的时间内 flag是true 则直接返回,不让执行
			return;
		}
		flag=true; //函数正在控制中
		//执行函数
		fn.apply(context,args);
		clearTimeout(timer);//清除定时器
		timer =setTimeout(function(){
			flag=false;//延时时间过了以后,放开函数控制
		},delay)
		
	}	
}
function fn(){
	console.log(123);
}
 
var fn1 = throttle(fn,2000);//绑定节流函数 
 
 
</script>
</html>

Le temps de clic du bouton est limité ici. Seule la première fois sera exécutée dans les 2000 millisecondes et sera invalide si vous cliquez plusieurs fois.

Résumé: On peut dire que les fermetures sont omniprésentes, de sorte que ces scénarios de fermetures méritent toujours d'être étudiés.

5. Prototype et chaîne de prototypes

Thème 1:

function F() {
  this.a = 1;
}
var obj = new F();
console.log(obj.prototype);//打印undefined   对象只有 __proto__属性没有prototype属性,函数才有

Thème 2:

Object.prototype.a = 1;
var obj = {
    b: 2
};
for(var i in obj) {
    console.log(i); //能迭代出原型链里面的属性,所以会打印出 b和a
}

Question 3:

Object.prototype.a = 1; 
var obj = {
    b: undefined
};
 
console.log(obj.a);//1
console.log('b' in obj);//true  //能找到处于原型链里面的bar属性
 
console.log(obj.hasOwnProperty('a'));//false 不是自身的属性
console.log(obj.hasOwnProperty('b'));//true  是自身的属性

Question 4:

function A(){
}
function B(a){
  this.a = a;
}
function C(a){
  if(a){
		this.a = a;
  }
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
 //实例对象都能访问构造函数的原型对象,可以明确的是以上3个都是能拿到a的
 
console.log(new A().a);//1   拿到的是原型上的a=1
console.log(new B().a);//undefined  this.a = a;将new B()这个实例对象的a属性这是为undefined,所以拿到的是undefined
console.log(new C(2).a);//2   将new C(2)这个实例对象的a属性这是为2,所以拿到的是2

Question 5:

function A () {
}
A.prototype.n = 1;
 
var b = new A();//b实例对象已经建立原型连接
 
//原型对象指向被改变,不会切断b实例对象的
A.prototype = {
    n: 2,
    m: 3
}
var c = new A();//c实例对象将根据新的原型建立连接
 
console.log(b.n, b.m); //1 undefined  这里拿到是改变prototype之前的
console.log(c.n, c.m); //2 3		这里拿到是改变prototype之后的

Question 6:

var F = function(){};
Object.prototype.a = function(){
    console.log('a')
}
Function.prototype.b = function(){
    console.log('b')
}
var f = new F();
 
F.a();  //打印a  对象都能访问Object.prototype中的属性和方法
F.b();  //打印b  F是函数,原型链  F => F.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
 
f.a();  //打印a  对象都能访问Object.prototype中的属性和方法
f.b();  //报错f.b is not a function   因f是F实例对象,原型链 f=>f.__proto__=>F.prototype=>F.prototype.__proto__ => Object.prototype

Résumé: En JavaScript, les objets ont des attributs __proto__ (prototypes implicites), qui pointent vers le prototype de la fonction constructeur qui construit l'objet. La fonction est spéciale. En plus d'avoir des attributs __proto__ comme les autres objets, elle possède également ses propres attributs L'attribut unique ---- prototype est appelé objet prototype, et l'objet prototype a un attribut constructeur, qui pointe vers la fonction.

 

6, la compréhension de ce

Exemple 1 (nouveau):

function person(name){
	this.name=name;
}
 
var p = new person("张三")
	console.log(p);
var p1 = new person("李四")
	console.log(p1);

Pour les objets créés par new, regardez leur ceci, et vous pouvez voir sur la figure ci-dessous que de nouveaux objets ont été créés.

Exemple 2 (appel obligatoire, appliquer)

	var person = {
		name:'person',
		sayHi:function(){
			console.log(this)
		}
	}
	var o={name:'o1'};
	person.sayHi.call(o);

Regardez cette impression dans la figure ci-dessous, ceci est lié à l'objet o

 

Exemple 3 (appel d'objet de contexte)

	var person = {
		name:'person',
		sayHi:function(){
			console.log(this)
		}
	}
	var o={name:'o1'};
	person.sayHi();	

ceci est imprimé comme indiqué dans la figure ci-dessous et est directement lié à l'objet personne

Exemple 4 (en utilisant la liaison par défaut)

	var name='person';
	function sayHi(){
		console.log(this)
	}
	sayHi();

L'imprimé c'est la fenêtre

exception

	var person = {
		name:'person',
		sayHi:function(){
			console.log(this)
		}
	}
	var o={name:'o1'};
	person.sayHi.call(null);

Lorsque null ou undefined est passé comme premier paramètre de call and apply, la règle de liaison par défaut sera utilisée, et cela pointera vers window.

Pour résumer:

  • La fonction est-elle appelée avec new? Si tel est le cas, cela lie l'objet nouvellement créé. var p = nouvelle personne ();
  • La fonction est-elle appelée par liaison matérielle via call et apply? Si tel est le cas, cela se lie à l'objet spécifié. var p = sayHi.call (obj);
  • La fonction est-elle appelée par un objet de contexte? Si tel est le cas, il est lié à cet objet de contexte. var p = obj.sayHi ();
  • Si rien de ce qui précède n'est vrai, la liaison par défaut est utilisée. var p = sayHi ();
     

Ceci de la fonction flèche

La fonction de flèche est sélectionnée séparément pour une raison, elle est déterminée en fonction de la portée externe  this et la liaison de la fonction de flèche ne peut pas être modifiée.

var a = 2;
var foo = () => {
  console.log(this.a)
}
var obj = {
  a: 4,
  foo: foo
}
obj.foo() // 2

La fonction de flèche du code ci - dessus  n'est pas affectée par les règles de liaison implicites, le résultat affiché dans la console est donc 2.

 

7. Déduplication des baies

Voie 1:

  var arr=[1,2,3,4,5,3,6,1,0];
   var arr2 = [];  
    for(let i = 0; i < arr.length; i++) {  
        if(arr2.indexOf(arr[i]) == -1) { //不包含某个值则返回-1  
            arr2.push(arr[i]);  
        }  
    }  
    console.log(arr2); 

Cette méthode est probablement la plus simple à laquelle tout le monde pense.

Voie 2:

    var arr=[1,2,3,4,5,3,6,1,0];
    var arrSort = arr.sort();  
    var arr2 = [];  
    for(let i = 0; i< arrSort.length; i++) {  
        if(arrSort[i] != arrSort[i+1]) {  
            arr2.push(arrSort[i]);  
        }  
    }  
    console.log(arr2); 

Cette méthode entraînera le tri du tableau au lieu de conserver l'ordre d'origine.

Utiliser l'épissure:

    var arr=[1,2,3,4,5,3,6,1,0];
    var len = arr.length;  
    for(var i = 0; i < len; i++) {  
        for(var j = i + 1; j < len; j++) {  
            if(arr[i] === arr[j]) {  
                arr.splice(i,1);  
                len--;  
                j--;  
            }  
        }  
    }  
    console.log(arr); 

Ensemble ES6

    var arr=[1,2,3,4,5,3,6,1,0];
    let sortSet = new Set(arr);  
    console.log(Array.from(sortSet));

 

8. Agent d'événement

Consultez cet article

 

9. Promotion variable et promotion de fonction

Promotion variable

a=2;
var a;
console.log(a);

Qu'est-ce que la console imprimera dans ce code? Il est peut-être indéfini, mais il imprimera en fait 2. Parce que ce code sera en fait traité comme ceci:

var a;
a=2;
console.log(a);

Parmi eux: var a; est à compiler, et les deux phrases suivantes sont exécutées.

Regardons un autre paragraphe:

console.log(a);
var a=2;

Il sera traité comme ceci:

var a;
console.log(a);
a=2;

Le même var a; est compilé et les deux phrases suivantes sont exécutées, car l'affectation de a = 2 est après l'impression, donc ce code affichera undefined.

À partir des deux morceaux de code ci-dessus, nous pouvons savoir qu'une variable déclarée comme var sera déplacée vers le haut de la portée actuelle dans la phase de compilation où qu'elle soit placée.

Promotion de la fonction

Les déclarations de fonction seront promues de la même manière que les déclarations de variables. Prenons un exemple de fonction:

hello();//执行
function hello(){//函数声明,这里可以看到声明在后,执行在前,能正常执行吗?
	console.log('hello');
}

Lorsque nous exécutons ce code, nous pouvons voir que la sortie est normale, c'est-à-dire que la déclaration de fonction est promue.

Et si nous utilisons var pour déclarer une fonction?

hello();//执行
var hello = function (){
	console.log('hello');
}

L'exécution signalera une erreur:

Pourquoi? Parce que var hello = function () {     console.log ('hello'); } de cette façon, var hello est une déclaration de variable, et ce qui suit est une opération d'affectation, la variable est promue et l'opération d'affectation n'est pas promue. fait, ce paragraphe est équivalent De cette façon:

var hello;
hello();//执行
hello = function(){
	console.log('hello');
}

Lors de l'exécution, hello est uniquement déclaré et sa valeur n'est pas définie, donc TypeError apparaîtra lorsqu'il est appelé avec (). Modifiez-le comme suit pour qu'il fonctionne normalement. Si vous voulez écrire de cette manière, vous devez le mettre dans la fonction avant d'exécution:

var hello= function(){
	console.log('hello');
}
hello();//执行

La fonction d'abord

hello();//执行
 
var hello;
 
function hello(){
	console.log('log hello');
}
 
hello = function(){
	console.log('log hello1');
}

Ce code s'imprimera: log bonjour

À partir des résultats, nous pouvons voir que log hello est imprimé lorsque la fonction est exécutée. Une fois la fonction exécutée, la variable hello sera remplacée par une instruction d'affectation avec une fonction qui imprime log hello1. Pourquoi? Le code réel sera traité comme ceci

function hello(){
    console.log('log hello');
}
 
hello();//执行
//var hello这句被忽略了
hello = function(){
    console.log('log hello1');
}


La fonction est d'abord promue vers le haut. À ce stade, la déclaration var hello sera ignorée, car hello existe déjà à ce moment, et c'est une fonction. Ensuite, bien sûr, la prochaine exécution de la fonction hello affichera le résultat précédent, puis il sera remplacé.
 

Couverture de la déclaration de fonction

hello();//执行
 
function hello(){
	console.log('log hello');
}
 
function hello(){
	console.log('log hello2');
}
 
 
function hello(){
	console.log('log hello3');
}

Il imprime le journal hello3 et les déclarations de fonction suivantes remplacent les déclarations de fonction précédentes.

Pour résumer:

  1. Les déclarations de fonction et les déclarations de variable seront promues en haut de la portée actuelle, et la fonction en premier, c'est-à-dire partout où nous plaçons l'instruction de déclaration.
  2. Afin de rendre le code beau, facile à maintenir, pour éviter les déclarations répétées et pour éviter les risques inutiles, il est préférable de placer les déclarations en premier.

10 、 typeof vs instanceof

Type de 

typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof 对于对象来说,除了函数都会显示 object
typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function'

exemple de

instanceof est de détecter si la chaîne prototype de l'objet pointe vers l'objet prototype du constructeur

var arr = [1,2,3]; 
console.log(arr instanceof Array);   // true
function B(){}
function A(){}
A.prototype = new B();  // 原型继承

var a = new A();
console.log(a instanceof A)  //true
console.log(a instanceof B)  //true
console.log(a instanceof Object)//true

Tous les contrôles avec instanceof sur la chaîne du prototype retournent true

 

11. Fonction de rappel (rappel)

Tels que l'Ajax de jquery

$ .ajax (url, fonction (données) {

// Logique de traitement

})

La fonction de rappel a une faiblesse fatale, c'est-à-dire qu'il est facile d'écrire un enfer de rappel, comme suit:

$.ajax(url, function(data) {
    // 处理逻辑 
    $.ajax(url_1, function(data) {
        // 处理逻辑 
        $.ajax(url_2, function(data) {
            // 处理逻辑 
            $.ajax(url_3, function(data) {
                // 处理逻辑 
            })
        })
    })
})

Bien que la fonction de rappel soit facile à utiliser, elle présente également ce problème: il est recommandé d'utiliser Promise pour le gérer.

 

12 、 Promesse 

La promesse a trois états, à savoir:

1. En attente (en attente)

2. Terminé (résolu)

3. Rejeté

Une fois que vous passez de l'état d'attente à un autre état, vous ne pouvez jamais changer l'état

new Promise((resolve,reject) => {
    resolve('success')
    // 无效
    reject('reject')
})

Promise résout également le problème de l'enfer des rappels. Le code suivant:

let p = new Promise((resolve, reject) => {
    setTimeout(resolve, 2000, 'success');
});
p.then(
    res => {
        console.log(res);
        return `${res} again`;
    }
)
    .then(
        res => console.log(res)
    );

// success
// success again

 

13, appeler, appliquer et lier des fonctions

Similitudes:

Modifiez le point de ceci dans le corps de la fonction.


       la différence:

La différence entre call et apply: la manière d'accepter les paramètres est différente.

bind: ne pas exécuter immédiatement. Pendant que l'application et l'appel sont exécutés immédiatement.

function Person(name){
  this.name = name;
}
Person.prototype.getName=function(){
    console.log(this.name);
}

var p = new Person('张三');
p.getName();//直接执行

var p1={name:'李四'};

p.getName.call(p1);//this被改变,获取的是p1中的name
p.getName.apply(p1);//this被改变,获取的是p1中的name
p.getName.bind(p1)();//this被改变,获取的是p1中的name,不会立即执行,需要()来执行

 Production:

 

14. La différence entre == et ===

En termes simples: == signifie la même chose, === signifie strictement la même chose; 

 Lors de la comparaison ==: vérifiez d'abord les types de données des deux opérandes, s'ils sont identiques, puis effectuez une comparaison ===, s'ils sont différents, puis effectuez une conversion de type, puis effectuez une comparaison après la conversion vers le même type, et === comparaison, si les types sont différents, c'est directement faux, et il n'y aura pas de conversion.

 

Je les ai inclus pour le moment, j'espère que cela sera utile à tout le monde, et me donner trois entreprises pour me soutenir, mes frères! !

 

Je suppose que tu aimes

Origine blog.csdn.net/dkm123456/article/details/114939677
conseillé
Classement