8
头图

Back-end-oriented front-end technology sharing

Sharing time: 45 minutes + 15 minutes to ask questions

Share two very important but often encountered two points in JS.

思维导图

purpose

  • Share common problems encountered in daily development work
  • Improve work efficiency and write easy-to-maintain code
  • Understand the trend of front-end technology

This

JS keywords: point to the context of the current environment

1. This in the event

In the DOM event, this points to the current DOM element object.

In the HTML event (only addEventListener added), this points to the HTML element that receives the event

<style>
  #box {
    height: 300px;
    line-height: 300px;
    text-align: center;
  }
</style>
<body>
  <div id="box">Hello World</div>
  <script>
    function bluify() {
      console.log(this);
      this.style.backgroundColor = "#00CCFF";
      this.innerHTML =
        this.innerHTML === "Hello World" ? "你好,世界" : "Hello World";
    }
    box.addEventListener("click", bluify, false);
  </script>
</body>

2. Global function, anonymous function, this points to the global object

  • Point to Window
  • Node environment points to Global
function func() {
  console.log(this); // Window or global
}
func();

3. Object method call

this points to the current object

const xiaoming = {
  name: "小明",
  getName() {
    console.log(this.name);
  },
};
xiaoming.getName(); // 小明

4. Called in the constructor, this points to the instance object

function Person(name, sex, age) {
  this.name = name;
  this.sex = sex;
  this.age = age;
}
let xiaoming = new Person("小明", "男", 20);
console.log(xiaoming); // { name: '小明', sex: '男', age: 20 }

5. call/apply/bind call

this points to the first parameter

const xiaoming = {
  name: "小明",
  getName() {
    console.log(this.name);
  },
};
const xiaohong = {
  name: "小红",
};
xiaoming.getName.call(xiaohong); // 小红

this Copy reference

Reason: used to correct this does not reach expectations

application scenario: such as the function setTimeout

Usage: let that = this;

Ordinary function VS arrow function

var name = "window";
let obj = {
  name: "obj",
  outout1() {
    let that = this;
    setTimeout(function() {
      console.log("普通函数", that.name);
    }, 1000);
  },
  outout2() {
    setTimeout(() => {
      console.log("箭头函数", this.name);
    }, 1000);
  },
};
obj.outout1(); // 普通函数 obj
obj.outout2(); // 普通函数 obj

Because the this of the arrow function is determined when it is defined, it can be used to write one step less this , and it is recommended to use it.

Timer

  • setTimeout: Execute in N seconds
  • setInterval: Execute cyclically after specifying N seconds

parameter

  • Function/string, string will trigger eval()
  • Duration in milliseconds (ms)
  • List of parameters passed into the function

incoming function

// setTimeout / setInterval 使用
setTimeout(
  (...args) => {
    let sum = args.reduce((p, c) => p + c);
    console.log(args, sum); //[ 1, 2, 3 ] 6
  },
  1000,
  1,
  2,
  3
);
// 这段代码的意思是:在 1 秒后将这个函数推入执行栈,然后传递参数1,2,3到函数中

After one second, the sum of 1, 2, and 3 will be calculated and output.

incoming string

setTimeout("alert(0)", 2000);

A string can be accepted, and it is executed after parsing eval() eval function is very performance-consuming, and it is not recommended if it is not special.

return value

Returns the ID of the timer, which is used to clear the timer.

clearInterval(n);
clearTimeout(n);

setTimeout

Core logic: Push to the execution stack in N seconds, instead of executing after N seconds,

Usage scenario: When an operation is delayed

problem:

  • Setting 0 seconds will also execute in the next macro task (asynchronous)
  • The timer outputs 1-10 pits in for (forEach cannot jump out of the loop)

asynchronous

// for & setTimout
for (var i = 1; i <= 10; i++) {
  setTimeout(() => {
    console.log(i); // ??
  }, 1000);
}

Due to asynchronous reasons, setTimeout is delayed until the next event loop execution.

forEach

forEach cannot break out of the loop

let arr = [1, 2, 3];
arr.forEach((e) => {
  console.log(e);
  1, 2, 3;
  e += 1;
  if (e === 2) {
    // break !X
    // return !X
  }
});
console.log(arr); // [1, 2, 3];

In forEach use break , return so not out of the loop.

The above operations can be converted to for operations

for (let i = 0; i < arr.length; i++) {
  if (arr[i] === 2) {
    break;
  }
  arr[i] += 1;
}
console.log(arr); // [ 2, 2, 3 ]

setInterval

usage scenario

  • Time saving of video learning
  • Polling for scan code login

problem

timer

  • Push to the execution stack after N seconds, instead of executing after N seconds
  • It will shorten the time due to the previous code being executed

case code:

Suppose there is an HTTP poll, and the data is queried every second.

let startTime = new Date().getTime();
let count = 0;
setInterval(() => {
  let i = 0;
  while (i++ < 10000000); // 假设这里是查询数据带来的网络延迟,用来增加每次函数执行的时间
  count++;
  console.log(
    "与原设定的间隔时差了:",
    new Date().getTime() - (startTime + count * 1000),
    "毫秒"
  );
}, 1000);

After the code is executed many times, the timer will become inaccurate and cause errors.

timer is not clear in time (in the small program)

  • If it is not clear , it will always be stored in the memory, causing a memory leak.
  • Use scenarios: save hours, face recognition, countdown to exams, etc.
  • Multiple page stack sharing timer

Solution

timer

Solution: Use settimeout simulate setinterval

// 自定义一个定时器
let timer = null;
function interval(func, wait) {
  let interv = function() {
    func.call(null);
    timer = setTimeout(interv, wait);
  };
  timer = setTimeout(interv, wait);
}

// 使用定时器
interval(() => {
  let date = new Date();
  console.log("log..", `${date.getMinutes()}: ${date.getSeconds()}`);
}, 1000);

// 清楚定时器
setTimeout(() => {
  clearTimeout(timer);
}, 1000 * 6);

Too many timers can not be clear, causing memory leak

Solution: batch clear timer

// 清楚当前页面的所有定时器
for (let i = 1; i < 100000; i++) {
  clearInterval(i);
  clearTimeout(i);
}

It is recommended to save the timer id in time for clearing.


九旬
1.1k 声望1.2k 粉丝