网络安全知识总结【二】

一、js函数声明->function

一共有三种方式

第一种

function命令后面是函数名,函数名后面是一对圆括号,里面是传入函数的参数。函数体放在大括号里面。

function print(a){
  console.log(a);
}

上面的代码命名了一个print函数,以后使用print()这种形式,就可以调用相应的代码。

第二种

除了用function命令声明函数,还可以采用变量赋值的写法。这种写法将一个匿名函数赋值给变量。这时,这个匿名函数又称函数表达式,因为赋值语句的等号右侧只能放表达式。

var print = function(s) {
  console.log(s);
};

第三种

Function构造函数。下面构造的两个函数是一样的,只是方式不一样。Function构造函数接受三个参数,除了最后一个参数是add函数的“函数体”,其他参数都是add函数的参数。Function构造函数可以不使用new命令,返回结果完全一样。

var add = new Function(
  'x',
  'y',
  'return x + y'
);
 
 
function add(x, y) {
  return x + y;
}

二、this关键字

1.全局环境

全局环境使用this,它指的就是顶层对象window(全局变量)。
不管是不是在函数内部,只要是在全局环境下运行,this就是指顶层对象window。

this === window // true
 
function f() {
  console.log(this === window);
}
f() // true

2.构造函数

构造函数中的this,指的是实例对象。
这里定义了一个构造函数Obj。由于this指向实例对象,所以在构造函数内部定义this.p,就相当于定义实例对象有一个p属性。

var Obj = function (p) {
  this.p = p;
};

3.对象的方法

如果对象的方法里面包含this,this的指向就是方法运行时所在的对象。该方法赋值给另一个对象,就会改变this的指向。但是,这条规则很不容易把握。请看下面的代码。obj.foo方法执行时,它内部的this指向obj。

var obj ={
  foo: function () {
    console.log(this);
  }
};
 
obj.foo() // obj

避免多层this

由于this的指向是不确定的,所以切勿在函数中包含多层的this。这里代码包含两层this,结果运行后,第一层指向对象o,第二层指向全局对象,因为实际执行的是下面的代码。

var o = {
  f1: function () {
    console.log(this);     // Object
    var f2 = function () {
      console.log(this);   // Window
    }();
  }
}
 
o.f1()

下面代码定义了变量that,固定指向外层的this,然后在内层使用that,就不会发生this指向的改变。事实上,使用一个变量固定this的值,然后内层函数调用这个变量,是非常常见的做法,请务必掌握。JavaScript 提供了严格模式,也可以硬性避免这种问题。严格模式下,如果函数内部的this指向顶层对象,就会报错。

var o = {
  f1: function() {
    console.log(this);
    var that = this;
    var f2 = function() {
      console.log(that);
    }();
  }
}
 
o.f1()
// Object
// Object

三、js的同步与异步

js是一个单线程的语言,学过java、c之类的都知道,其他语言有个叫类继承的东西,就相当于开辟另个一个流水线,是多线程

​ 而javascript就像一条流水线,它无法开辟别的流水线,是一个单线程,也就是说js要么加工,要么包装,不能同时进行多个任务和流程

定时器

JavaScript 提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成。它们向任务队列添加定时任务。

在js中,最基础的异步就是setTimeout和setInterval这两个函数,但是很少人知道这两个人其实是异步,简单介绍一下吧

setTimeout和setInterval

function void(){};
setTimeout(void,1000);//隔1000毫秒后执行一次void,然后就不会在执行了
setInterval(void,1000);//每隔1000毫秒(1秒)执行一次void

同步与异步的例子

用官方一点的话来讲,当一个js被执行的时候,把同步代码全放到一个执行栈里面,异步代码放到一个任务队列中,当栈执行完毕后开始执行任务队列


首先,同步的代码是console.log(1)和log(3),所以先输出了1,3,然后就是异步的地方了。

异步三个代码,setTimeout、setInterval、setTimeout,当我们执行完同步代码(也就是输出1,3)开始执行异步代码对于第一个异步操作,因为我们设置的延迟时间为5秒(这个地方,虽然没有显示出来,但是这个异步操作已经开始执行,也就是说当代码执行到这一步的时候计时就已经开始),然后就是setInterval(add2,1000)也就是4,5,4,4,4,然后此时,设置的第一个延迟5秒到了,就输出一个2。

​同步的入栈顺序是log(1),log(3),然后出栈就是1,3,输出也就是1,3

异步的入队顺序是,add,add2,add3,出来的时候也是add,add2,add3,但由于add的延迟原因,所以add2先输出

所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行

四、宏任务与微任务

宏任务:普通任务,正常执行。正常的异步任务都是宏任务,最常见的就是定时器(setInterval, setImmediate, setTimeout)、IO任务

微任务:优先于宏任务执行(但不会抢断)。微任务出现比较晚,queueMicrotask、ES6、Promise和async属于微任务(当然,async就是promise)

​ 我们可以看出来,微任务的优先级比宏任务高,一个任务结束后,事件循环会找到并执行全部微任务,然后再查找其他任务,那么,怎么分别宏任务和微任务呢?

分辨宏任务与微任务


setTimeout(() => console.log(111), 0);这里的()=>就类似于定义一个函数然后调用

输出的结果是

aaa

bbb

222

111

执行顺序就像我们之前说的,先执行同步的,也就是aaa,bbb,然后在执行异步的,但是这里,setTimeout在queueMicrotask前面,却还是先执行了queueMicrotask,就是因为queueMicrotask是微任务,而setTimeout是宏任务,也就是说在异步中,会先完成所有的微任务,然后再去执行宏任务

这里 每个代码的影响不一样,重要性也不一样,按照官方的设想就是,任务之间的不平等,有些任务对于用户而言更加重要,需要先执行,有些任务(类似定时器)晚点执行也没有什么问题.

你可能感兴趣的:(渗透,javascript,前端,开发语言)