Heim  >  Artikel  >  Web-Frontend  >  Probleme damit, dass JavaScript leicht auszutricksen ist

Probleme damit, dass JavaScript leicht auszutricksen ist

hzc
hzcnach vorne
2020-06-28 09:50:232212Durchsuche

Vorwort

Zusammenfassung: Dies ist das Verständnis und die Erfahrung einiger JavaScript-Themen, die ich gesammelt habe und die ich interessanter oder schwieriger finde und die noch lange auf dem Laufenden gehalten werden.

Lebe nicht als Frau, und dein Glück und dein Leiden werden hundert Jahre lang anderen überlassen.

Text

1. Detailliertes Verständnis von setTimeout und setInterval

Im detaillierten Verständnis von setTimeout und setInterval hat der Autor eine Zusammenfassung erstellt In diesem Blog wissen wir, dass die beiden Funktionen von JavaScript-Testversionen die Methode des Einfügens von Code verwenden, um eine Pseudoasynchronität zu erreichen, was eigentlich das gleiche Prinzip wie AJAX ist. Schauen wir uns dieses Beispiel an:

console.log("1");
setTimeout(function(){        
    console.log("3")
},0);    console.log("2");

Ergebnis: Die Konsole gibt 1, 2, 3 nacheinander aus;

function fn() {
    setTimeout(function(){alert('can you see me?');},1000);
    while(true) {}
}

Was ist Ihrer Meinung nach das Ausführungsergebnis dieses Codes? Die Antwort ist, dass die Warnung nie erscheint.
Warum ist das so? Da der While-Code nicht ausgeführt wurde, wird der später eingefügte Code niemals ausgeführt.
Zusammenfassend lässt sich sagen, dass JS tatsächlich ein Single-Threaded-Produkt ist. Egal wie „asynchron“ es ist, es ist unmöglich, die Single-Thread-Barriere zu durchbrechen. Daher sind viele „asynchrone Aufrufe“ (einschließlich Ajax) eigentlich nur „pseudoasynchron“. Solange Sie ein solches Konzept verstehen, ist es möglicherweise nicht schwierig, setTimeout und setInterval zu verstehen.

2. Vorläufige Erkundung von Schließungen

Wir haben in diesem Blog eine vorläufige Erkundung von JavaScript-Verschlüssen durchgeführt. Es gibt mehrere Themen, die ich persönlich für sehr interessant halte:

  var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
  alert(object.getNameFunc()());//The Window
   var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };  
  alert(object.getNameFunc()());//My Object
function fun(n,o) {
  console.log(o)
  return {
    fun:function(m){
      return fun(m,n);
    }
  };
}
var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);//undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1);  c.fun(2);  c.fun(3);//undefined,?,?,?

//F: Was sind die Ausgaben der drei Zeilen a, b und c?

Dies ist ein sehr typisches JS-Schließungsproblem. Darin sind drei Ebenen mit Spaßfunktionen verschachtelt. Es ist besonders wichtig herauszufinden, um welche Spaßfunktion es sich bei der jeweiligen Ebene handelt.

//Antwort:
//a: undefiniert,0,0,0
//b: undefiniert,0,1,2
//c : undefiniert,0,1,1

3. Array/map,Number/parseInt

["1", "2", "3"].map(parseInt)//求输出结果复制代码

Zuerst akzeptiert Map zwei Parameter, eine Callback-Funktion callback und eine Callback-Funktion this value
Die Callback-Funktion akzeptiert drei Parameter currentValue, index, arrary; und in der Frage übergibt map nur die Callback-Funktion --parseInt akzeptiert nur zwei Parameter string, radix (radix). radix ist 2-36. Der Standardwert ist also 10. Diese Frage lautet also:

rrree

Die Antwort lautet also: [1, NaN, NaN]; 🎜>4. 0,1+0,2!=0,3 und 9999999999999999 == 10000000000000000;

JavaScript verwendet gemäß der Sprachspezifikation das „durch den IEEE 754-Standard definierte 64-Bit-Format mit doppelter Genauigkeit“ ( „Werte im 64-Bit-Format mit doppelter Genauigkeit (IEEE 754)“) stellt Zahlen dar. Daraus können wir eine interessante Schlussfolgerung ziehen. Im Gegensatz zu anderen Programmiersprachen (wie C und Java) unterscheidet JavaScript nicht zwischen Ganzzahlwerten und Gleitkommawerten. Seien Sie daher bei der Durchführung numerischer Operationen besonders vorsichtig. Präzisionsverlust Schauen Sie sich das folgende Beispiel an:

parseInt('1', 0);parseInt('2', 1);parseInt('3', 2);复制代码
In bestimmten Implementierungen werden Ganzzahlwerte normalerweise als 32-Bit-Ganzzahlvariablen behandelt, und in einzelnen Implementierungen (z. B. einigen Browser) Wird als 32-Bit-Ganzzahlvariable gespeichert, bis sie zum Ausführen einer Operation verwendet wird, die von 32-Bit-Ganzzahlen nicht unterstützt wird. Dies dient der Erleichterung der Bitmanipulation. Die Genauigkeit großer Ganzzahlen geht innerhalb von 2 bis 53 nicht verloren, was bedeutet, dass der Browser alle Zahlen innerhalb von Math.pow(2,53) genau berechnen kann, wenn die endliche Zahl durch die binäre Darstellung von a dargestellt wird dezimal dezimal ist nicht Wenn es 52 Bit überschreitet, kann es in JavaScript genau gespeichert werden.
Lösung: Math.round( (.1+.2)*100)/100;


5 🎜>Diese Frage lässt die Leute fälschlicherweise denken, dass es sich um 2>1&&2b30e4b38979f09c3563ee579546fe4d7true;truee5dfd1e04a098d470fd53bdae68047611e5dfd1e04a098d470fd53bdae6804761true;325346d3d65c60a4c2739f19f2f21fdd8true;false66a8cecc548e92eefe204758893a9e9e066a8cecc548e92eefe204758893a9e9etrue;复制代码Diese Frage fühlt sich sehr einfallsreich an~ Lassen Sie mich Ihnen zuerst die Antwort sagen: Fehler,'3',Fehler;Aber wenn es

3.toString;3..toString;3...toString;复制代码

ist, aber legal ist, lautet die Antwort '3';

Warum ?
Weil 1.1, 1.,.1 alle gültige Zahlen in JS sind! Handelt es sich beim Parsen von 3.toString um eine Zahl oder einen Methodenaufruf? Der Browser ist verwirrt und kann nur einen Fehler auslösen, daher habe ich das Gefühl, dass diese Frage dem Browser nur einen Streich spielt...

7. Aussageverbesserung

var a=3;
a.toString;复制代码

Die Antwort ist Was.. . Als der Autor es zum ersten Mal tat, dachte ich törichterweise, es sei „Hallo, Welt“ … Tatsächlich ist dies nicht der Fall. Die richtige Antwort lautet: „Auf Wiedersehen, Jack“. . Der obige Code entspricht dem folgenden Code:
var name = 'World!';
(function () {
    var name;
    if (typeof name === 'undefined') {
        name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();

8. 坑爹史(1)

var a = [0];
if ([0]) {
  console.log(a == true);
} else {
  console.log("wut");
}

读者们你们觉得此题答案是什么呢?true?因为[0]被看做Boolean是被认为是true,理所当然的推出来[0]==true,控制台输出true...看似没错,然而并不是这样滴~[0]这个玩意儿在单独使用的时候是被认为是true的,但用作比较的时候它是false...所以正确答案是false;不信的话,F12控制台输出[0]==false;看是不是true......

###9. 坑爹史(2)

1 + - + + + - + 1

这题应该是等同于:(倒着看)

1 + (a)  => 2
a = - (b) => 1
b = + (c) => -1
c = + (d) => -1
d = + (e) => -1
e = + (f) => -1
f = - (g) => -1
g = + 1   => 1

答案是2

10. 坑爹史(3)

function sidEffecting(ary) {
  ary[0] = ary[2];
}
function bar(a,b,c) {
  c = 10
  sidEffecting(arguments);  return a + b + c;
}
bar(1,1,1)

此题涉及ES6语法,实在坑的不行...arguments
首先 The arguments object is an Array-like object corresponding to the arguments passed to a function.也就是说 arguments 是一个 object, c 就是 arguments2, 所以对于 c 的修改就是对 arguments2 的修改.
所以答案是 21.
然而!!!!!!
当函数参数涉及到 any rest parameters, any default parameters or any destructured parameters 的时候, 这个 arguments 就不在是一个 mapped arguments object 了.....请看:

function sidEffecting(ary) {
  ary[0] = ary[2];
}
function bar(a,b,c=3) {
  c = 10
  sidEffecting(arguments);  return a + b + c;
}
bar(1,1,1)

答案是12...
请读者细细体会!!

11. 坑爹史(4)

[,,,].join(", ")
[,,,] => [undefined × 3]

因为javascript 在定义数组的时候允许最后一个元素后跟一个,, 所以这是个长度为三的稀疏数组(这是长度为三, 并没有 0, 1, 2三个属性哦)
答案: ", , "

12. 浏览器懵逼史(2)

var a = {class: "Animal", name: 'Fido'};
a.class

这个题比较流氓.. 因为是浏览器相关, class是个保留字(现在是个关键字了);Fuck!
所以答案不重要, 重要的是自己在取属性名称的时候尽量避免保留字. 如果使用的话请加引号 a['class']

13.一道容易被人轻视的面试题

function Foo() {
    getName = function () { alert (1); };
    return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}

//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();

14.闭包小题

for(var i = 0; i < 5; i++) {
    console.log(i);
}

for(var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000 * i);
}

for(var i = 0; i < 5; i++) {
    (function(i) {
        setTimeout(function() {
            console.log(i);
        }, i * 1000);
    })(i);
}

for(var i = 0; i < 5; i++) {
    (function() {
        setTimeout(function() {
            console.log(i);
        }, i * 1000);
    })(i);
}

for(var i = 0; i < 5; i++) {
    setTimeout((function(i) {
        console.log(i);
    })(i), i * 1000);
}

setTimeout(function() {
  console.log(1)
}, 0);
new Promise(function executor(resolve) {
  console.log(2);
  for( var i=0 ; i<10000 ; i++ ) {
    i == 9999 && resolve();
  }
  console.log(3);
}).then(function() {
  console.log(4);
});
console.log(5);

15. 函数的隐式转换

function fn() {
    return 20;
}
console.log(fn + 10); // 输出结果是多少

function fn() {
    return 20;
}

fn.toString = function() {
    return 10;
}

console.log(fn + 10);  // 输出结果是多少?

function fn() {
    return 20;
}

fn.toString = function() {
    return 10;
}

fn.valueOf = function() {
    return 5;
}

console.log(fn + 10); // 输出结果是多少?

16. 函数防抖和函数节流(ES6)

//函数节流
const throttle = (fun, delay) => {
    let last = null;
    return () => {
        const now = + new Date();
        if (now - last > delay) {
            fun();
            last = now;
        }
    }
}
//实例
const throttleExample  = throttle(() => console.log(1), 1000);
//调用
throttleExample();
throttleExample();
throttleExample();
//函数防抖
const debouce = (fun, delay) => {
    let timer = null;
    return () => {
        clearTimeout(timer);
        timer = setTimeout(() => {
            fun();
        }, delay);
    }
}
//实例
const debouceExample = debouce(() => console.log(1), 1000);
//调用
debouceExample();
debouceExample();
debouceExample();

推荐教程:《JS教程

Das obige ist der detaillierte Inhalt vonProbleme damit, dass JavaScript leicht auszutricksen ist. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen