Js中按位操作符的有趣应用入门基础_运算菜鸟教程网

JavaScript提供了几种运算符,可以对一些简单的值进行基本操作,比如算术操作、赋值操作、逻辑操作、按位操作等。我们经常可以看到混合了赋值操作,算术操作和逻辑操作的JavaScript代码。但是,按位操作的代码就不是那么常见了。JavaScript的按位操作符~ — 按位非& — 按位与| — 按位或^ — 按位异或<> — 有符号右移>>

Js中按位操作符的有趣应用入门基础

JavaScript提供了几种运算符,可以对一些简单的值进行基本操作,比如算术操作、赋值操作、逻辑操作、按位操作等。我们经常可以看到混合了赋值操作,算术操作和逻辑操作的JavaScript代码。但是,按位操作的代码就不是那么常见了。

Js中按位操作符的有趣应用入门基础_运算菜鸟教程网

JavaScript的按位操作符

  1. ~ — 按位非
  2. & — 按位与
  3. | — 按位或
  4. ^ — 按位异或
  5. << — 左移
  6. >> — 有符号右移
  7. >>> — 无符号右移

在本文中,我们将过一遍所有的按位操作符并且试着理解他们是怎么工作的。同时,我们会编写简单的JavaScript的代码,来看一看一些有趣的按位操作符运用。这需要我们了解一下javascript位操作符如何将其操作数表示为有符号的32位整数。让我们开始吧。

按位非(~)

~运算符是一元运算符;因此,它只需要一个操作数。~运算符对其操作数的每一位执行NOT操作。非运算的结果称为补码。整数的补码是通过将整数的每一位倒转而形成的。

对于给定的整数(例如170),可以使用~运算符计算补码,如下所示:

// 170 => 00000000000000000000000010101010
// --------------------------------------
//  ~ 00000000000000000000000010101010
// --------------------------------------
//  = 11111111111111111111111101010101
// --------------------------------------
//  = -171 (decimal)

console.log(~170); // -171

javascript按位运算符将其操作数转换为二进制补码格式的32位有符号整数。因此,当对整数使用~运算符时,得到的值是整数的补码。整数A的补码的结果为 – (A+1) 。

~170 => -(170 + 1) => -171

下面是一些需要注意的关于32位有符号整数的要点,这些整数由javascript位运算符使用:

  • 最有意义(最左边)的位称为符号位。正整数的符号位总是0,负整数的符号位总是1。
  • 除符号位之外的其余31位用于表示整数。因此,可以表示的最大32位整数是(2^32-1),它是2147483647,而最小整数是(2^31),它是-2147483648。
  • 对于不在32位有符号整数范围内的整数,最有效位将被丢弃,直到整数在该范围内。

以下是一些重要数字的32位序列表示:

0 => 00000000000000000000000000000000
-1 => 11111111111111111111111111111111
2147483647 => 01111111111111111111111111111111
-2147483648 => 10000000000000000000000000000000

从上面的描述可以很容易得出:

                  ~0 => -1
         ~-1 => 0
 ~2147483647 => -2147483648
~-2147483648 => 2147483647

找到索引

大多数JavaScript内置对象(如数组和字符串)都有一些有用的方法,可用于检查数组中是否存在项或字符串中是否存在子字符串。以下是一些方法:

  • Array.indexOf()
  • Array.lastIndexOf()
  • Array.findIndex()
  • String.indexOf()
  • String.lastIndexOf()
  • String.search()

这些方法都返回某一项或子字符串的从零开始的索引(如果找到);否则,它们返回-1。例如:

const numbers = [1, 3, 5, 7, 9];

console.log(numbers.indexOf(5)); // 2
console.log(numbers.indexOf(8)); // -1

如果我们对么某一项或者子字符串的索引位置不感兴趣,我们可以选择使用布尔值。当未找到的项或者子字符串时,返回-1,我们可以认为是false,返回其他的值都是true。

function foundIndex (index) {
  return Boolean(~index);
}

在上面的代码片段中,~运算符在-1上使用时的值为0。使用boolean()将值强制转换为boolean,返回false。对于其他每个索引值,返回true。因此,以前的代码段可以修改如下:

const numbers = [1, 3, 5, 7, 9];

console.log(foundIndex(numbers.indexOf(5))); // true
console.log(foundIndex(numbers.indexOf(8))); // false

按位与(&)

& 操作符对其操作数的每一对对应位执行一个和运算。& 操作符仅当两个位都为1时返回1;否则返回0。因此,与运算的结果等于将每一对对应的位相乘。

下面是与操作的可能值:

(0 & 0) === 0     // 0 x 0 = 0
(0 & 1) === 0     // 0 x 1 = 0
(1 & 0) === 0     // 1 x 0 = 0
(1 & 1) === 1     // 1 x 1 = 1

‘关闭’某些位

&操作符通常用于位屏蔽应用,以确保为给定的位序列关闭某些位。这是基于这样一个事实,即对于任何位A:

  • (A & 0 = 0) — 和0进行与运算,位总是会变成0。
  • (A & 1 = A) — 和1进行与运算,位总是保持不变。

举个例子,假设我们有一个8位的整数,我们希望确保前面的4位被关闭(置为0)。我们可以用&操作符来实现:

  • 首先,创建一个位掩码,其效果是关闭8位整数的前4位。该位掩码将为0B111110000。请注意,位掩码的前4位设置为0,而其他每一位设置为1。
  • 接下来,使用8位整数和创建的位掩码进行 &操作。
const mask = 0b11110000;

// 222 => 11011110

// (222 & mask)
// ------------
// 11011110
// & 11110000
// ------------
// = 11010000
// ------------
// = 208 (decimal)

console.log(222 & mask); // 208

检查设定位

&操作符还有一些其他有用的位屏蔽应用。一个这样的应用是确定给定的位序列是否设置了一个或多个位。例如,假设我们要检查是否为给定的十进制数设置了第五位。以下是我们如何使用&运算符来执行此操作:

  • 首先,创建一个位掩码,用于检查目标位(在本例中为第五位)是否设置为1。位掩码上的每个位都设置为0,但目标位置的位除外,目标位置的位设置为1。二进制数文字可用于轻松实现这一点:

    const mask = 0b10000;
  • 接下来,使用十进制数和位掩码作为操作数执行&操作,并将结果与位掩码进行比较。如果所有目标位都设置为十进制数,&操作的结果将等于位掩码。请注意,位掩码中的0位将有效地关闭十进制数中的相应位,因为a&0=0。

    // 34 => 100010
    // (34 & mask) => (100010 & 010000) = 000000
    console.log((34 & mask) === mask); // false
    
    // 50 => 110010
    // (50 & mask) => (110010 & 010000) = 010000
    console.log((50 & mask) === mask); // true

奇数或偶数

使用&运算符检查十进制数的设定位可以扩展到检查给定的十进制数是偶数还是奇数。为了实现这一点,使用1作为位掩码(以确定是否设置了第一位或最右边的位)。

对于整数,可以使用最低有效位(第一位或最右边的位)来确定数字是偶数还是奇数。如果启用最低有效位(设置为1),则数字为奇数;否则,数字为偶数。

function isOdd (int) {
  return (int & 1) === 1;
}

function isEven (int) {
  return (int & 1) === 0;
}

console.log(isOdd(34)); // false
console.log(isOdd(-63)); // true
console.log(isEven(-12)); // true
console.log(isEven(199)); // false

有用的标识

在继续下一个运算符之前,这里有一些&操作符的有用标识(对于任何带符号的32位整数A):

(A & 0) === 0
(A & ~A) === 0
(A & A) === A
(A & -1) === A

按位或(|)

运算符对其操作数的每对对应位执行“或”运算。运算符仅当两个位都为0时返回0;否则返回1。

对于一对位,这里是或操作的可能值:

(0 | 0) === 0
(0 | 1) === 1
(1 | 0) === 1
(1 | 1) === 1

‘打开’位

在位屏蔽应用中,可以使用运算符来确保位序列中的某些位被打开(设置为1)。这是基于这样一个事实:对于任何给定的位A:

  • (A | 0 = A) — 和0进行或运算,位总是会保持不变。
  • (A | 1 = 1) — 和1进行或运算,位总是为1。

例如,假设我们有一个8位整数,我们希望确保所有偶数位(第二、第四、第六、第八)都打开(设置为1)。| 运算符可用于实现以下目的:

  • 首先,创建一个位掩码,其效果是打开8位整数的每个偶数位。该位掩码将是0B101010。请注意,位掩码的偶数位设置为1,而其他位设置为0。
  • 接下来,使用8位整数和创建的位掩码执行或操作:
const mask = 0b10101010;

// 208 => 11010000

// (208 | mask)
// ------------
// 11010000
// | 10101010
// ------------
// = 11111010
// ------------
// = 250 (decimal)

console.log(208 | mask); // 250

有用的标识

在继续下一个运算符之前,这里有一些 | 操作符的有用标识(对于任何带符号的32位整数A):

(A | 0) === A
(A | ~A) === -1
(A | A) === A
(A | -1) === -1

按位异或(^)

^运算符对其操作数的每对对应位执行异或(异或)运算。如果两个位相同(0或1),则^运算符返回0;否则,它返回1。

对于一对位,下面是可能的值:

(0 ^ 0) === 0
(0 ^ 1) === 1
(1 ^ 0) === 1
(1 ^ 1) === 0

切换位

在位屏蔽应用程序中,^ 运算符通常用于切换或翻转位序列中的某些位。这是基于这样一个事实:对于任何给定的位A:

  • 和0进行异或运算,位总是会保持不变。

    (A ^ 0 = A)

  • 当与相应的1位配对时,该位总是被切换。

    (A ^ 1 = 1) — if A is 0
    (A ^ 1 = 0) — if A is 1

例如,假设我们有一个8位整数,我们希望确保除了最低有效位(第一位)和最高有效位(第八位)之外,每个位都被切换。可以使用^运算符实现以下目的:

  • 首先,创建一个位掩码,其效果是切换8位整数的每个位,除了最低有效位和最高有效位。该位掩码将为0b0111110。请注意,要切换的位设置为1,而其他位设置为0。
  • 接下来,使用8位整数和创建的位掩码执行^操作:

    const mask = 0b01111110;
    
    // 208 => 11010000
    
    // (208 ^ mask)
    // ------------
    // 11010000
    // ^ 01111110
    // ------------
    // = 10101110
    // ------------
    // = 174 (decimal)
    
    console.log(208 ^ mask); // 174

有用的标识

在继续下一个运算符之前,以下是^操作的一些有用标识(对于任何有符号的32位整数A):

(A ^ 0) === A
(A ^ ~A) === -1
(A ^ A) === 0
(A ^ -1) === ~A

从上面列出的标识中可以明显看出,-1上的xor操作等同于a上的按位非操作。因此,上面的foundIndex()函数也可以这样编写:

function foundIndex (index) {
  return Boolean(index ^ -1);
}

左移(<<)

左移位(<<)运算符接受两个操作数。第一个操作数是整数,而第二个操作数是要向左移动的第一个操作数的位数。零(0)位从右边移入,而从左边移入的多余位被丢弃。

例如,考虑整数170。假设我们要向左移动三位。我们可以使用<<运算符,如下所示:

// 170 => 00000000000000000000000010101010

// 170 << 3
// --------------------------------------------
//    (000)00000000000000000000010101010(***)
// --------------------------------------------
//  = (***)00000000000000000000010101010(000)
// --------------------------------------------
//  = 00000000000000000000010101010000
// --------------------------------------------
//  = 1360 (decimal)

console.log(170 << 3); // 1360

左移位位运算符(<<)可以使用以下javascript表达式定义:

(A << B) => A * (2 ** B) => A * Math.pow(2, B)

因此,回顾前面的示例:

(170 << 3) => 170 * (2 ** 3) => 170 * 8 => 1360

颜色转换:RGB到十六进制

左移位(<)运算符的一个非常有用的应用程序是将颜色从RGB表示转换为十六进制表示。

RGB颜色的每个组件的颜色值在0-255之间。简单地说,每个颜色值可以用8位完美地表示。

 0 => 0b00000000 (2进制) => 0x00 (16进制)
255 => 0b11111111 (2进制) => 0xff (16进制)

因此,颜色本身可以完美地用24位来表示(红色、绿色和蓝色分量各8位)。从右边开始的前8位表示蓝色分量,接下来的8位表示绿色分量,之后的8位表示红色分量。

(binary) => 11111111 00100011 00010100

   (red) => 11111111 => ff => 255
 (green) => 00100011 => 23 => 35
  (blue) => 00010100 => 14 => 20

   (hex) => ff2314

既然我们已经了解了如何将颜色表示为24位序列,那么让我们来看看如何从颜色的各个组件的值组成颜色的24位。假设我们有一个用RGB(255、35、20)表示的颜色。以下是我们如何组合这些位:

(red) => 255 => 00000000 00000000 00000000 11111111
(green) =>  35 => 00000000 00000000 00000000 00100011
 (blue) =>  20 => 00000000 00000000 00000000 00010100

// Rearrange the component bits and pad with zeroes as necessary
// Use the left shift operator

  (red << 16) => 00000000 11111111 00000000 00000000
 (green << 8) => 00000000 00000000 00100011 00000000
       (blue) => 00000000 00000000 00000000 00010100

// Combine the component bits together using the OR (|) operator
// ( red << 16 | green << 8 | blue )

      00000000 11111111 00000000 00000000
    | 00000000 00000000 00100011 00000000
    | 00000000 00000000 00000000 00010100
// -----------------------------------------
      00000000 11111111 00100011 00010100
// -----------------------------------------

既然过程非常清楚,下面是一个简单的函数,它将颜色的RGB值作为输入数组,并基于上述过程返回颜色的相应十六进制表示:

function rgbToHex ([red = 0, green = 0, blue = 0] = []) {
  return `#${(red << 16 | green << 8 | blue).toString(16)}`;
}

有符号右移(>>)

有符号右移(>>)运算符的符号接受两个操作数。第一个操作数是整数,而第二个操作数是要右移的第一个操作数的位数。

已移到右边的多余位将被丢弃,而符号位(最左边的位)的副本将从左边移入。所以,整数的符号位会一直保留。所以这种运算叫做有符号右移。

例如,考虑整数170和-170。假设我们想把三位移到右边。我们可以使用>>运算符,如下所示:

//  170 => 00000000000000000000000010101010
// -170 => 11111111111111111111111101010110

// 170 >> 3
// --------------------------------------------
//    (***)00000000000000000000000010101(010)
// --------------------------------------------
//  = (000)00000000000000000000000010101(***)
// --------------------------------------------
//  = 00000000000000000000000000010101
// --------------------------------------------
//  = 21 (decimal)

// -170 >> 3
// --------------------------------------------
//    (***)11111111111111111111111101010(110)
// --------------------------------------------
//  = (111)11111111111111111111111101010(***)
// --------------------------------------------
//  = 11111111111111111111111111101010
// --------------------------------------------
//  = -22 (decimal)

console.log(170 >> 3); // 21
console.log(-170 >> 3); // -22

通过以下javascript表达式可以描述有符号右移:

(A >> B) => Math.floor(A / (2 ** B)) => Math.floor(A / Math.pow(2, B))

因此,之前的那个例子可以如下表示:

(170 >> 3) => Math.floor(170 / (2 ** 3)) => Math.floor(170 / 8) => 21
(-170 >> 3) => Math.floor(-170 / (2 ** 3)) => Math.floor(-170 / 8) => -22

颜色提取

有符号右移(>>)运算符的一个非常好的应用是从颜色中提取RGB颜色值。当颜色以RGB表示时,很容易区分红色、绿色和蓝色颜色分量值。但是,对于以十六进制表示的颜色,这将花费更多的精力。

在上一节中,我们看到了从颜色的各个组成部分(红色、绿色和蓝色)的位组成颜色的过程。如果我们反向执行这个过程,我们将能够提取颜色的各个组成部分的值。让我们试一试。

假设我们有一个用十六进制表示法ff2314表示的颜色。下面是颜色的有符号32位表示:

(color) => ff2314 (hexadecimal) => 11111111 00100011 00010100 (binary)

// 32-bit representation of color
00000000 11111111 00100011 00010100

为了获得单个部分,我们将根据需要将颜色位按8的倍数右移,直到从右边得到目标组件位作为前8位。由于颜色的32位中的符号标志位是0,因此我们可以安全地使用符号传播右移位(>>)运算符。

color => 00000000 11111111 00100011 00010100

// Right shift the color bits by multiples of 8
// Until the target component bits are the first 8 bits from the right

  red => color >> 16
      => 00000000 11111111 00100011 00010100 >> 16
      => 00000000 00000000 00000000 11111111

green => color >> 8
      => 00000000 11111111 00100011 00010100 >> 8
      => 00000000 00000000 11111111 00100011

 blue => color >> 0 => color
      => 00000000 11111111 00100011 00010100

现在我们将目标颜色位作为右前8位,我们需要一种方法来屏蔽除前8位之外的所有其他位。这使我们回到和(&)运算符。请记住,&运算符可用于确保关闭某些位。

让我们从创建所需的位掩码开始。就像这样:

mask => 00000000 00000000 00000000 11111111
     => 0b11111111 (binary)
     => 0xff (hexadecimal)

准备好位掩码后,我们可以对上一次右移操作的每个结果执行与(&)操作,使用位掩码提取目标颜色。

red => color >> 16 & 0xff
      =>   00000000 00000000 00000000 11111111
      => & 00000000 00000000 00000000 11111111
      => = 00000000 00000000 00000000 11111111
      =>   255 (decimal)

green => color >> 8 & 0xff
      =>   00000000 00000000 11111111 00100011
      => & 00000000 00000000 00000000 11111111
      => = 00000000 00000000 00000000 00100011
      =>   35 (decimal)

 blue => color & 0xff
      =>   00000000 11111111 00100011 00010100
      => & 00000000 00000000 00000000 11111111
      => = 00000000 00000000 00000000 00010100
      =>   20 (decimal)

基于上述过程,这里有一个简单的函数,它以十六进制颜色字符串(带有六个十六进制数字)作为输入,并返回相应的RGB颜色分量值数组。

function hexToRgb (hex) {
  hex = hex.replace(/^#?([0-9a-f]{6})$/i, '$1');
  hex = Number(`0x${hex}`);

  return [
    hex >> 16 & 0xff, // red
    hex >> 8 & 0xff,  // green
    hex & 0xff        // blue
  ];
}

无符号右移(>>>)

无符号右移位(>>>)运算符的行为非常类似于符号传播右移位(>>)运算符。然而,关键区别在于从左边移入的位。

顾名思义,0位总是从左边移入。因此,>>运算符始终返回无符号32位整数,因为结果整数的符号位始终为0。对于正整数,>>和>>>都将始终返回相同的结果。

例如,考虑整数170和-170。假设我们要将3位移到右边,我们可以使用>>>操作符,如下所示:

//  170 => 00000000000000000000000010101010
// -170 => 11111111111111111111111101010110

// 170 >>> 3
// --------------------------------------------
//    (***)00000000000000000000000010101(010)
// --------------------------------------------
//  = (000)00000000000000000000000010101(***)
// --------------------------------------------
//  = 00000000000000000000000000010101
// --------------------------------------------
//  = 21 (decimal)

// -170 >>> 3
// --------------------------------------------
//    (***)11111111111111111111111101010(110)
// --------------------------------------------
//  = (000)11111111111111111111111101010(***)
// --------------------------------------------
//  = 00011111111111111111111111101010
// --------------------------------------------
//  = 536870890 (decimal)

console.log(170 >>> 3); // 21
console.log(-170 >>> 3); // 536870890

配置标志

在总结本教程之前,让我们考虑另一个非常常见的位操作符和位屏蔽应用:配置标志。

假设我们有一个函数,它接受几个布尔选项,这些选项可以用来控制函数的运行方式或返回的值的类型。创建此函数的一种可能方法是将所有选项作为参数传递给该函数,可能使用一些默认值,例如:

function doSomething (optA = true, optB = true, optC = false, optD = true, ...) {
  // something happens here...
}

当然,这不太方便。在以下两种情况下,这种方法开始变得相当有问题:

  • 假设我们有10个以上的布尔选项。我们不能用这么多参数定义函数。
  • 假设我们只想为第五个和第九个选项指定一个不同的值,并让其他选项保留默认值。我们需要调用函数,将默认值作为所有其他选项的参数传递,同时为第五个和第九个选项传递所需的值。

用前面的方法解决问题的一种方法是为配置选项使用一个对象,如下所示:

const defaultOptions = {
  optA: true,
  optB: true,
  optC: false,
  optD: true,
  ...
};

function doSomething (options = defaultOptions) {
  // something happens here...
}

这种方法非常优雅,您很可能已经看到它被使用了,甚至自己在某个地方使用过。然而,使用这种方法时,options参数将始终是一个对象,对于配置选项来说,这可以被认为是多余的。

如果所有选项都采用布尔值,则可以使用整数而不是对象来表示选项。在这种情况下,整数的某些位将映射到指定的选项。如果某个位被打开(设置为1),则指定选项的值为“真”;否则为“假”。

我们可以用一个简单的例子来演示这种方法。假设我们有一个函数,它规范化包含数字的数组列表中的项,并返回规范化的数组。返回的数组可以由三个选项控制,即:

  • fraction:将数组中的每个项除以数组中的最大项
  • unique:从数组中删除重复项
  • sorted:将数组中的项从最低到最高排序

我们可以使用一个3位整数来表示这些选项,每个位都映射到一个选项。以下代码段显示选项标志:

const LIST_FRACTION = 0x1; // (001)
const LIST_UNIQUE = 0x2;   // (010)
const LIST_SORTED = 0x4;   // (100)

要激活一个或多个选项,可以根据需要使用运算符组合相应的标志。例如,我们可以创建一个标志来激活所有选项,如下所示:

const LIST_ALL = LIST_FRACTION | LIST_UNIQUE | LIST_SORTED; // (111)

同样,假设我们只希望默认情况下激活fraction和sorted选项。我们可以再次使用运算符,如下所示:

const LIST_DEFAULT = LIST_FRACTION | LIST_SORTED; // (101)

虽然只使用三个选项看起来并不糟糕,但当有这么多选项时,它往往会变得非常混乱,并且默认情况下需要激活其中的许多选项。在这种情况下,更好的方法是使用^运算符停用不需要的选项:

const LIST_DEFAULT = LIST_ALL ^ LIST_UNIQUE; // (101)

这里,我们有一个列表“所有”标志,可以激活所有选项。然后,我们使用^运算符停用唯一选项,并根据需要保留其他选项。

现在我们已经准备好了选项标志,可以继续定义normalizelist()函数:

function normalizeList (list, flag = LIST_DEFAULT) {
  if (flag & LIST_FRACTION) {
    const max = Math.max(...list);
    list = list.map(value => Number((value / max).toFixed(2)));
  }
  if (flag & LIST_UNIQUE) {
    list = [...new Set(list)];
  }
  if (flag & LIST_SORTED) {
    list = list.sort((a, b) => a - b);
  }
  return list;
}

为了检查某个选项是否被激活,我们使用&运算符来检查该选项的相应位是否被打开(设置为1)。&操作是通过传递给函数的flag参数和选项的对应标志来执行的,如下面的代码段所示:

// Checking if the unique option is activated
// (flag & LIST_UNIQUE) === LIST_UNIQUE (activated)
// (flag & LIST_UNIQUE) === 0 (deactivated)

flag & LIST_UNIQUE

总结

嘿,我真的很高兴你能读完这篇文章,尽管读了很长时间,但我强烈希望你在读的时候学到一两件事。谢谢你的时间。

正如我们在本文中所看到的,虽然使用得很谨慎,但javascript的位操作符有一些非常有趣的用例。我强烈希望您在阅读本文的过程中获得的见解从现在起用在你的日常开发中。

海计划公众号
(0)
上一篇 2020/03/26 23:36
下一篇 2020/03/26 23:36

您可能感兴趣的内容

  • Js如何从字符串中提取数字?使用教程_数字使用说明

    如果想要将一个字符串中的数字给提取出来,这要怎么做? 在JavaScript中可以使用match()方法将字符串中的数字提取到数字数组中。此方法将正则表达式作为参数,并从字符串中提取数字。使用match()方法提取数字分两种情况:1、不考虑小数此时可以使用正则表达式(/\d+/g)来从字符串中提取数字。示例:var str = ‘123sdf

    2020/03/20
  • Snabbt.js小白攻略_一个简约的 JavaScript 动画库

    Snabbt.js小白攻略 官方网址:http://daniel-lundin.github.io/snabbt.js/ GitHub:https://github.com/dan…

    2020/03/06
  • javascript如何获取地址栏的参数?基础知识教程_参数入门基础知识

    JavaScript在web开发中,不同的页面间经常会需要参数的传递,比如新闻列表和新闻详情页面,怎么绑定不同的id给它们,这时候比较简单的方案就是通过地址栏传输对应的参数。javascript获取地址栏的参数的方法:方法一:采用正则表达式获取地址栏参数:

    <script type="text/java

    2020/03/24
  • 快码众包基础知识入门_一个创新的软件开发平台

    快码众包基础知识入门 官方网址:https://www.kuai.ma/ 简介描述:一个创新的软件开发平台 快码是一个创新的软件开发平台。项目方可以更省钱、高效地完成项目的开发;开…

    2020/03/11
  • Flutter异步加载:Future,async/await菜鸟攻略_加载小白指南

    概念Future对象表示异步操作的结果,我们通常通过then()来处理返回的结果async用于标明函数是一个异步函数,其返回值类型是Future对象await用来等待耗时操作的返回结果,这个操作会阻塞到后面的代码三种方式async/awaitFutureFutureBuilderasync/await被async修饰的函数,会返回一个Futured对象

    2020/03/29
  • Less 变量基础指南_less菜鸟教程

    概念使用 @ 符号定义变量,变量分配使用 : 完成。 声明格式:@变量名:变量值 。通常看到很多重复的相同的值,我们可以通过使用变量来避免。Less中的变量和其他编程语言一样,可以实现值的复用,同样的它也有作用域,简单的来说就是变量的作用域就是局部变量和全局变量的概念;变量作用域采用的是就近原则,也就是说我们需要先查找自己本身是否有这个变量,如果有就使用自身

    2020/03/23
  • fontello小白帮助免费Web-font图标字体生成器

    fontello基础入门 官方网址:http://fontello.com/ GitHub:https://github.com/fontello/fontello 简介描述:免费…

    2020/03/05
  • IconMonstr基础入门免费简约素材图标下载站

    IconMonstr基础入门 官方网址:https://iconmonstr.com/ 简介描述:免费简约素材图标下载站  iconmonstr是一个朴实、朴素的图标素材…

    2020/03/05
  • css如何实现保持div等高宽比?菜鸟知识_宽高小白攻略

    那么css如何实现高度height随宽度width变化保持比例不变呢?即给定可变宽度的元素,它将确保其高度以响应的方式保持成比例(即,其宽度与高度的比率保持恒定)。下面以高宽 2:1 为例,通过2种方式来实现这种效果。方式一:利用定位实现.wrapper{position : relative;background: #ccc;width: 10%;padd

    2020/03/21
  • 什么时候不使用箭头函数?新手入门_箭头函数菜鸟教程

    这些年来,ES6 将 JS 的可用性提升到一个新的水平时: 箭头函数、类等等,这些都很棒。箭头函数是最有价值的新功能之一,有很多好文章描述了它的上下文透明性和简短的语法。但每个事务都有两面。通常,新特性会带来一些混乱,其中之一就是箭头函数被误导了。本文将介绍一些场景,在这些场景中,你应该绕过箭头函数,转而使用良好的旧函数表达式或较新的简写语法。并且要注意缩短

    2020/03/29
  • Js函数原型中的 call 和 apply 方法的区别?基础知识入门_区别入门基础

    call, apply都属于Function.prototype的方法它们是在 JavaScript 引擎内在实现的,因为属于Function.prototype,所以每个Function对象实例,也就是每个方法都有call, apply属性。它们的作用一样,只是使用方式不同。call 与 apply 调用参数不同不同之处在于调用apply函数时,参数可以使

    2020/03/29
  • 怎么彻底删除nodejs?菜鸟教程_node入门基础教程

    怎么彻底删除nodejs?菜鸟教程 Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。Node.js是一个事件驱动I/O服务端JavaScript…

    2020/03/20
  • Cube.js菜鸟知识_一款很不错的模块化web 应用分析框架

    Cube.js菜鸟知识 官方网址:https://cube.dev/ GitHub:https://github.com/statsbotco/cube.js 简介描述:一款很不错…

    2020/03/06
  • 解密 Design System入门基础_设计小白攻略

    简介设计系统的产生是为了某领域内产品在不同平台和设备上都保持设计和交互风格的统一。既然是一个系统 ,那必须具有相应的完整性。它为产品设计,产品内容等方面提供相应的指导。总体来看,整个设计系统由Design Principle, Design Language, Code Library 和一些相关的Tools组成。从以下的图可以更直观的看到它的组成部分。主流

    2020/03/30
  • Js的三大组成部分小白常识_语言小白帮助

    JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。JavaScript的三大组成部分是:1、ECMAScript:JavaScript的核心,描述了语言的基本语法(var、for、if、array

    2020/03/29
  • web服务器 Nginx入门教程_服务器小白攻略

    一、web服务器(www服务器)(1)概念Web服务器是一台使用HTTP协议与客户机浏览器进行信息交流(因此又称为HTTP服务器)、为互联网客户提供服务(信息浏览,下载资源等)的主机。发展趋势:从HTML到XML、从有线到无线、从无声到有声1.Linux是架设安全高效Web服务器的操作系统架设Web服务器常见的操作系统:Windows、Linux、Unix。

    2020/03/23