你不知道的JavaScript-----强制类型转换

news/2024/4/25 8:48:19/文章来源:https://blog.csdn.net/qq_63358859/article/details/127548316

目录

值类型转换

抽象值的操作

JSON 字符串化

ToNumber: 非数字值到数字值 Number(value)

ToBoolean: 转换为布尔类型 Boolean(value)

强制类型转换

字符串和数字之间的显式强制类型转换

奇特的~运算符

字位截除

显式解析数字字符串

显式转换为布尔值

隐式强制类型转换

字符串与数字之间的隐式强制类型转换

布尔值到数字的隐式强制类型转换

||和&&

 字符串和数字之间的相等比较

其他类型和布尔类型之间的相等比较

null和undefined之间的相等比较

对象和非对象之间的相等比较

比较少见的情况

1、返回其他数字:

2、假值的相等比较

3、极端情况

4、完整性检查

 抽象关系比较

valueOf()和toString()详解


值类型转换

  • 将值从一种类型转换成另一种类型通常称为类型转换,这是显式的情况;隐式的情况称为强制类型转换。
  • 强制类型转换主要将值转换为相应的字符串、数字、布尔值,不会返回对象和函数。
  • 下面两种方式都是将数字转换成字符串
var a = 42;
var b = a + ""; // 隐式强制类型转换
var c = String(a); // 显式强制类型转换

抽象值的操作

JSON 字符串化

对大多数简单的值都可以使用JSON.stingify(...)字符串化。

JSON.stringify(..) 在对象中遇到 undefined、function 和 symbol 时会自动将其忽略,在数组中则会返回 null

var a = {name: 'Tina',age: 20,sayHi: function() {alert('Hi')},height: null,weight: undefined,hobbies: ['swimming','reading','singing',null,undefined,function () { console.log('hobbies') }]
}
JSON.stringify(a)
// "{"name":"Tina","age":20,"height":null,"hobbies":["swimming","reading","singing",null,null,null]}"

如果要对含有非法 JSON 值的对象做字符串化,或者对象中的某些值无法被序列化时,就需要定义 toJSON() 方法来返回一个安全的 JSON 值。
如果对象中定义了 toJSON() 方法,JSON 字符串化时会首先调用该方法,然后用它的返回值来进行序列化。

图中循环引用会产生错误

 小技巧

JSON.stringify(value[, replacer [, space]])

replacer表示要字符化的属性
space用于美化输出

ToNumber: 非数字值到数字值 Number(value)

非数字值到数字值转化规则:

值类型转换规则
null0
undefinedundefined
true1
false, null0
转换出错NaN

ToBoolean: 转换为布尔类型 Boolean(value)

JavaScript 中的值可以分为以下两类:

  • (1)  假值:可以被强制类型转换为 false 的值  undefined   +0, -0, NaN   false  null    ""
  • (2)  真值 :其他(被强制类型转换为 true 的值)  假值列表之外的值

假值对象

虽然 JavaScript 代码中会出现假值对象,但它实际上并不属于 JavaScript 语言的范畴。

var a = new Boolean(false)
var b = new Number(0)
var c = new String("")

强制类型转换


字符串和数字之间的显式强制类型转换

  • 字符串与数字是通过 String(..) 和 Number(..) 这两个内建函数(比较常用)
  • .toString()
  • +(比较少用)
var a = 42;
var b = a.toString();var c = '66.6'
var d = +c

日期显式转换为数字

var d = +new Date; // 可直接转换为时间戳, 不建议这么用,知道可以这么用就可以了
var timestamp = Date.now();  // 获取时间戳

奇特的~运算符

0 | -0; // 0
0 | NaN; // 0
0 | Infinity; // 0
0 | -Infinity; // 0

indexOf(..)不仅能够得到子字符串的位置,还可以用来检查字符串中是否包含指定的子字符串,相当于一个条件判断。例如:

var a = "Hello World";
if (a.indexOf("lo") >= 0) { // true// 找到匹配!
}
if (a.indexOf("lo") != -1) { // true// 找到匹配!
}
if (a.indexOf("ol") < 0) { // true// 没有找到匹配!
}
if (a.indexOf("ol") == -1) { // true// 没有找到匹配!
}

= 0 和== -1这样的写法不是很好,称为“抽象渗漏”,意思是在代码中暴露了底层的实现细节,这里是指用-1作为失败时的返回值,这些细节应该被屏蔽掉。
现在我们终于明白有什么用处了!和indexOf()一起可以将结果强制类型转换(实际上仅仅是转换)为真/假值:

var a = "Hello World";
~a.indexOf("lo"); // -4 <-- 真值!
if (~a.indexOf("lo")) { // true// 找到匹配!
}
~a.indexOf("ol"); // 0 <-- 假值!
!~a.indexOf("ol"); // true
if (!~a.indexOf("ol")) { // true// 没有找到匹配!
}

如果 indexOf(..) 返回 -1, ~ 将其转换为假值 0,其他情况一律转换为真值。
从技术角度来说, if (~a.indexOf(..)) 仍然是对 indexOf(..) 的返回结果进行隐式强制类型转换, 0 转换为 false,其他情况转换为 true。但我觉得 ~ 更像显式强制类型转换,前提是我对它有充分的理解。

字位截除


Math.floor(x) => 找到小于 x,而且离 x 最近的整数

~~ 后面接正数的时候与 Math.floor() 相同, 负数时是找到离 x 最近的大于 x 的整数

Math.floor(4.5)  // 4
Math.floor(-4.5)  // -5~~4.5  // 4
~~-4.5  // -4

显式解析数字字符串

解析字符串中的数字和将字符串强制类型转换为数字的返回结果都是数字。但解析和转换两者之间还是有明显的差别。

解析允许字符串中含有非数字字符,解析按从左到右的顺序,如果遇到非数字字符就停止。而转换不允许出现非数字字符,否则会失败并返回 NaN。

解析和转换之间不是相互替代的关系。它们虽然类似,但各有各的用途。如果字符串右边的非数字字符不影响结果,就可以使用解析。而转换要求字符串中所有的字符都是数字,像 "42px" 这样的字符串就不行。

var a = '42'
var b = '42px'parseInt(a)  // 解析字符串 42
Number(a)  // 显式强制类型转换 42parseInt(b)  // 42
Number(b)  // 转换失败,返回 NaN

parseInt(s, ?radix) -- 第一个参数是要解析的字符串,第二个参数是转变之后的数字基底(2进制、10进制),默认十进制
从 ES5 开始 parseInt(..) 默认转换为十进制数,除非另外指定。如果你的代码需要在 ES5 之前的环境运行,请记得将第二个参数设置为 10。

注:parseInt(..) 先将参数强制类型转换为字符串再进行解析,这样做没有任何问题。因为传递错误的参数而得到错误的结果,并不能归咎于函数本身。

parseFloat() 解析浮点数

显式转换为布尔值

使用 Boolean(x)

Boolean(undefined)  // false
Boolean(null)  // falseBoolean({})  // true
Boolean([])  // true

一元运算符 ! 显式的将值转换为其自身布尔类型的相反的值,根据这个特性,使用 !! 显式的将值转换为对应的布尔值。

if(xxx) {} 背后的原理:

在 if(..).. 这样的布尔值上下文中,如果没有使用 Boolean(..) 和 !!,就会自动隐式地进行 ToBoolean 转换。建议使用 Boolean(..) 和 !! 来进行显式转换以便让代码更清晰易读。

JSON.stringify()

var arr = [1, function () {}, 3]
JSON.stringify(arr)  // "[1,null,3]"

显式 ToBoolean 的另外一个用处,是在 JSON 序列化过程中将值强制类型转换为 true 或false,而不是只显示 null

显式转换布尔值在三元运算符中的应用:

var a = 42
var b = a ? true : false  // true
// 更简便的写法
var b = !!a
var b = Boolean(a)

这里涉及隐式强制类型转换,因为 a 要首先被强制类型转换为布尔值才能进行条件判断。这种情况称为“显式的隐式”,有百害而无一益,我们应彻底杜绝。
所以在使用三元运算符的时候尽量使用显式强制类型转换对待判断值做显式处理,更容易让人理解(!!a Boolean(a))。

隐式强制类型转换

隐式强制类型转换指的是那些隐蔽的强制类型转换,副作用也不是很明显。换句话说,你自己觉得不够明显的强制类型转换都可以算作隐式强制类型转换。
显式强制类型转换旨在让代码更加清晰易读,而隐式强制类型转换看起来就像是它的对立面,会让代码变得晦涩难懂。

字符串与数字之间的隐式强制类型转换

  • 操作符规则
    如果两个操作数都是数字,将执行加法操作;
    如果有一个操作数是字符串(或者说能被转换成字符串),将执行字符串拼接操作;

根据 ES5 规范 11.6.1 节,如果某个操作数是字符串或者能够通过以下步骤转换为字符串的话, + 将进行拼接操作。如果其中一个操作数是对象(包括数组),则首先对其调用 ToPrimitive 抽象操作(规范 9.1 节),该抽象操作再调用 [[DefaultValue]](规范 8.12.8节),以数字作为上下文。

var a = 42
var b = '42'var c = [4, 2]
var d = [2]a + 0  // 42
b + 0  // '420'c + d  // "4,22"

对于两个数组或者一个数组和一个对象相加,会执行以下操作:

  • c.toString() // "4,2"
  • d.toString() // "2"
  • "4,2" + "2" // "4,22"
  • 数字减法运算符
    为了执行减法运算,左右两边的数都要转换成数字,它们首先被转换为字符串(通过强制类型转换toString()),然后再转换为数字。

布尔值到数字的隐式强制类型转换

隐式强制类型转换为布尔值

发生布尔值隐式强制类型转换的情况:

  • if (..) 语句中的条件判断表达式。
  • for ( .. ; .. ; .. ) 语句中的条件判断表达式(第二个)。
  • while (..) 和 do..while(..) 循环中的条件判断表达式。
  • ? : 中的条件判断表达式。
  • 逻辑运算符 ||(逻辑或)和 &&(逻辑与)左边的操作数(作为条件判断表达式)。

||和&&


&&和||运算符的返回值并不一定是布尔类型,而是两个操作数其中一个的值。

var a = 42;
var b = "abc";
var c = null;
a || b; // 42
a && b; // "abc"
c || b; // "abc"
c && b; // null

下面是一个十分常见的||的用法:

function foo(a, b) {a = a || "hello";b = b || "world";console.log(a + " " + b);
}
foo(); // "hello world"
foo("yeah", "yeah!"); // "yeah yeah!"

有一种用法对开发人员不常见,然而JavaScript代码压缩工具常用。就是如果第一个操作数为真值,则&&运算符“选择”第二个操作数作为返回值,这也叫做“守护运算符”,即前面的表达式为后面的表达式“把关”:

function foo() {console.log(a);
}
var a = 42;
a && foo(); // 42

foo()只有在条件判断a通过时才会被调用。如果条件判断未通过,a&&foo()就会悄然终止(也叫做“短路”),foo()不会被调用。这样的用法对开发人员不太常见,开发人员通常使用if(a){foo();}

var a = 42;
var b = null;
var c = "foo";
if (a && (b || c)) {console.log("yep");
}

这里a&&(b||c)的结果实际上是“foo”而非true,然后再由if将foo强制类型转换为布尔值,所以最后结果为true。
现在明白了吧,这里发生了隐式强制类型转换。如果要避免隐式强制类型转换就得这样:

if (!!a && (!!b || !!c)) {console.log("yep");
}

 字符串和数字之间的相等比较

var a = 42;
var b = "42";
a === b; // false
a == b; // true

具体是怎么转换?是a从42转换为字符串,还是b从“42”转换为数字?
ES5规范这样定义:

  • (1) 如果Type(x) 是数字,Type(y) 是字符串,则返回x == ToNumber(y) 的结果。
  • (2) 如果Type(x) 是字符串,Type(y) 是数字,则返回ToNumber(x) == y 的结果。

其他类型和布尔类型之间的相等比较


==最容易出错的一个地方是true和false与其他类型之间的相等比较。

var a = "42";
var b = true;
a == b; // false

我们都知道“42”是一个真值,为什么==的结果不是true呢?
规范是这样说的:

  • (1) 如果Type(x) 是布尔类型,则返回ToNumber(x) == y 的结果;
  • (2) 如果Type(y) 是布尔类型,则返回x == ToNumber(y) 的结果。

所以建议,无论什么情况下都不要使用==true和==false。请注意,这里说的只是==,===true和===false不允许强制类型转换,所以并不涉及ToNumber。

var a = "42";
// 不要这样用,条件判断不成立:
if (a == true) {// ..
}
// 也不要这样用,条件判断不成立:
if (a === true) {// ..
}
// 这样的显式用法没问题:
if (a) {// ..
}
// 这样的显式用法更好:
if (!!a) {// ..
}
// 这样的显式用法也很好:
if (Boolean(a)) {// ..
}

null和undefined之间的相等比较


null和undefined之间的==也涉及隐式强制类型转换:

  • (1) 如果x 为null,y 为undefined,则结果为true。
  • (2) 如果x 为undefined,y 为null,则结果为true。

在==中null和undefined相等(它们也与其自身相等),除此之外其他值都不存在这种情况。
也就是说在==中null和undefined是一回事,可以相互进行隐式强制类型转换:

var a = null;
var b;
a == b; // true
a == null; // true
b == null; // true
a == false; // false
b == false; // false
a == ""; // false
b == ""; // false
a == 0; // false
b == 0; // false

下面是显式的做法,其中不涉及强制类型转换,个人觉得更繁琐一些(大概执行效率也会更低):

var a = doSomething();
if (a === undefined || a === null) {// ..
}

对象和非对象之间的相等比较


ES5规定:

  • (1) 如果Type(x) 是字符串或数字,Type(y) 是对象,则返回x == ToPrimitive(y) 的结果;
  • (2) 如果Type(x) 是对象,Type(y) 是字符串或数字,则返回ToPrimitive(x) == y 的结果。
var a = 42;
var b = [ 42 ];
a == b; // true

[42]首先调用ToPrimitive抽象操作,返回“42”,变成“42”==42,然后又变成42==42,最后二者相等。

之前介绍过的ToPrimitive抽象操作的所有特性(如toString()、valueOf())在这里都适用。

之前我们介绍过“拆封”,即“打开”封装对象,返回其中的基本数据类型值。==中的ToPromitive强制类型转换也会发生这样的情况:

var a = "abc";
var b = Object( a ); // 和new String( a )一样
a === b; // false
a == b; // true

但有一些值不这样,原因是==算法中其他优先级更高的规则:

var a = null;
var b = Object( a ); // 和Object()一样
a == b; // false
var c = undefined;
var d = Object( c ); // 和Object()一样
c == d; // false
var e = NaN;
var f = Object( e ); // 和new Number( e )一样
e == f; // false

因为没有对应的封装对象,所以null和undefined不能够被封装,Object(null)和Object()均返回一个常规对象。
NaN能够被封装为数字封装对象,但拆封之后NaN==NaN返回false,因为NaN不等于NaN。

比较少见的情况


首先来看看更改内置原生原型会导致哪些奇怪的结果:


1、返回其他数字:

Number.prototype.valueOf = function () {return 3;
};
new Number(2) == 3; // true

2==3不会有这个问题,因为2和3都是数字基本类型值,不会调用Number.prototype.valueOf()方法。而Number(2)涉及ToPrimitive强制类型转换,因此会调用valueOf()。

还有更奇怪的情况:

if (a == 2 && a == 3) {// ..
}

你也许觉得这不可能,因为a不会同时等于2和3,但“同时”一词并不准确,因为a==2在a==3之前执行。
如果让a.valueOf()每次调用都产生副作用,比如第一次返回2,第二次返回3,就会出现这样的情况。这实现起来很简单:

var i = 2;
Number.prototype.valueOf = function () {return i++;
};
var a = new Number(42);
if (a == 2 && a == 3) {console.log("Yep, this happened.");
}

2、假值的相等比较

"0" == null; // false
"0" == undefined; // false
"0" == false; // true -- 晕!
"0" == NaN; // false
"0" == 0; // true
"0" == ""; // false
false == null; // false
false == undefined; // false
false == NaN; // false
false == 0; // true -- 晕!
false == ""; // true -- 晕!
false == []; // true -- 晕!
false == {}; // false
"" == null; // false
"" == undefined; // false
"" == NaN; // false
"" == 0; // true -- 晕!
"" == []; // true -- 晕!
"" == {}; // false
0 == null; // false
0 == undefined; // false
0 == NaN; // false
0 == []; // true -- 晕!
0 == {}; // false

3、极端情况

[] == ![] // true

让我们看看!运算符都做了些什么?根据ToBoolean规则,它会进行布尔值的显式强制类型转换(同时反转奇偶校验位)。所以[]==![]变成了[]==false。前面我们讲过false==[],最后的结果就顺理成章了。

2 == [2]; // true
"" == [null]; // true
0 == "\n"; // true
42 == "43"; // false
"foo" == 42; // false
"true" == true; // false
42 == "42"; // true
"foo" == [ "foo" ]; // true

4、完整性检查

"0" == false; // true -- 晕!
false == 0; // true -- 晕!
false == ""; // true -- 晕!
false == []; // true -- 晕!
"" == 0; // true -- 晕!
"" == []; // true -- 晕!
0 == []; // true -- 晕!

其中有4中情况涉及==false,之前我们说过应该避免,应该不难掌握。现在剩下后面3种。
正常情况下我们应该不会这样来写代码,我们应该不太可能会用==[]来做条件判断,而是用==""或者==0,如:

function doSomething(a) {if (a == "") {// ..}
}

如果不小心碰到doSomething(0)和doSomething([])这样的情况,结果会让你大吃一惊。
又如:

function doSomething(a,b) {if (a == b) {// ..}
}

doSomething("",0) 和doSomething([],"") 也会如此。

5、安全运用隐式强制类型转换
我们要对==两边的值认真推敲,以下两个原则可以让我们有效地避免出错:

  • 如果两边的值中有true或者false,千万不要使用==。
  • 如果两边的值中有[]、“”或者0,尽量不要使用==。

这时最好用===来避免不经意的强制类型转换。这两个原则可以让我们避开几乎所有强制类型转换的坑。

有一种情况下强制类型转换是绝对安全的,那就是typeof操作。typeof总是返回七个字符串之一,其中没有空字符串。所以在类型检查过程中不会发生隐式强制类型转换。typeof x=="function"是100%安全的,和typeof x==="function"一样。

 抽象关系比较

a<b中涉及的隐式强制类型转换不太引人注意,不过还是很有必要深入了解一下。
比较双方首先调用ToPrimitive,如果结果出现非字符串,就根据ToNumber规则将双方强制类型转换为数字来进行比较。

var a = [ 42 ];
var b = [ "43" ];
a < b; // true
b < a; // false

如果比较双方都是字符串,则按字母顺序来进行比较:

var a = [ "42" ];
var b = [ "043" ];
a < b; // false

a和b并没有被转换为数字,因为ToPrimitive返回的是字符串,所以ToPrimitive返回的是字符串,所以这里比较的是“42”和“043”两个字符串,它们分别以“4”和“0”开头。因为“0”在字母顺序上小于“4”,所以最后结果为false。
同理:

var a = [ 4, 2 ];
var b = [ 0, 4, 3 ];
a < b; // false

a转换为“4,2”,b转换为“0,4,3”,同样是按字母顺序进行比较。
再比如:

var a = { b: 42 };
var b = { b: 43 };
a < b; // ??

结果还是false,因为a是[object Object],b也是[object Object],所以按照字母顺序a<b并不成立。
下面的例子就有些奇怪了:

var a = { b: 42 };
var b = { b: 43 };
a < b; // false
a == b; // false
a > b; // false
a <= b; // true
a >= b; // true

根据规范a<=b被处理为b<a,然后将结果反转。因为b<a的结果是false,所以a<=b的结果是true。
这可能与我们设想的大相径庭,即<=应该是“小于或者等于”。实际上JavaScript中<=是“不大于”的意思(即!(a>b),处理为!(b<a))。同理a>=b处理为b<=a。
相等比较有严格相等,关系比较却没有“严格关系比较”。也就是说如果要避免a>b中发生隐式强制类型转换,我们只能确保a和b为相同的类型,除此之外别无他法。

valueOf()和toString()详解

valueOf()函数用于返回指定对象的原始值

该方法属于Object对象,由于所有的对象都"继承"了Object的对象实例,因此几乎所有的实例对象都可以使用该方法。

所有主流浏览器均支持该函数。

语法

valueOf()函数用于返回指定对象的原始值

该方法属于Object对象,由于所有的对象都"继承"了Object的对象实例,因此几乎所有的实例对象都可以使用该方法。

所有主流浏览器均支持该函数。

语法  object.valueOf( )

JavaScript的许多内置对象都重写了该函数,以实现更适合自身的功能需要。因此,不同类型对象的valueOf()方法的返回值和返回值类型均可能不同。

 

    // 对象在参与运算及比较的时候,js引擎会自动的帮我们去调用这两个方法.// 调用规则://  1. 默认先调用valueOf方法(valueOf 来源于 Object的原型),尝试把对象转成简单数据类型,2. 如果没有得到简单数据类型,再继续去调用toString方法//  作用: 将对象转成原始值(简单数据类型),但是Object原型上的valueOf达不到目的, 把对象自身给返回了/*  var arr = [1,2,3];console.log(arr + 1); // 1,2,31//  arr.valueOf()  ==> arr//  arr.toString() ==> "1,2,3"//  "1,2,3" + 1    ==> "1,2,31"console.log(arr - 0); // NaN  // "1,2,3" - 0console.log(arr + "6班学习好努力"); // 1,2,36班学习好努力*/// var obj = {//     name: "lw"// };// console.log(obj * 1);  // NaN // obj.valueOf() ==> obj// obj.toString() ==> "[object Object]"// "[object Object]" * 1// console.log(obj + "1");  // [object Object]1// console.log([] == ![]);  // true//  [] == false  ==> 都转数值进行比较//  [].valueOf() ==> []//  [].toString()  ==> ""//  +""  ==> 0//  console.log({} == !{});// {} == false   ==> 都转数值进行比较// {}.valueOf()  ==> {}// {}.toString() ==> "[object Object]"// +"[object Object]" ==> NaN (字符串转成数值 ===>  NaN, 不是一个数字)例1:// var obj = {};// console.log(obj.toString()); // "[objectObject]"例2:// var a = {},// b = { key: 'b' };// c = { key: 'c' };// a[b] = 123;// a[c] = 456;// console.log(a[b]);   //456// 给如果对象的属性类型不是一个字符串时,就会去转换.// js会自动让对象去调用这两个方法,默认先valueOf(),如果没有得到简单数据类型,再去调用toString()// 其中对象a中的属性 b ==> "[object,Object]" ,等同于 给对象a,使用[]语法,去添加属性并赋值// 再看对象a中的属性 c ==> "[object,Object]" ,等同于 修改同一个属性的属性值,所以最终的到的结果是456

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_410180.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis查询返回结果类型专题

文章目录一、返回一条信息二、返回List集合三、返回Map集合四、返回多个Map集合五、返回List集合一、返回一条信息 Student selectById(Long id); 不再赘述 二、返回List集合 List< Student> selectAll(); 不再赘述 三、返回Map集合 用map集合去接收返回来的结果 字…

Python-- list(列表)的使用

目录 1.合并两个有序序列构成一个有序列表 2.编写程序判断列表是否为升序 3.输入一个十进制转换为二进制输出 4.将列表中的前p个元素到尾列表 1.合并两个有序序列构成一个有序列表 代码如下&#xff1a; list1 list(eval(input("请输入有序列表list1:"))) list…

【飞桨PaddleSpeech语音技术课程】— 一句话语音合成全流程实践

(以下内容搬运自飞桨PaddleSpeech语音技术课程&#xff0c;点击链接可直接运行源码) 一句话语音合成全流程实践 点击播放视频 1 声音克隆介绍 & 语音合成基本概念回顾 语音合成&#xff08;Speech Sysnthesis&#xff09;&#xff0c;又称文本转语音&#xff08;Text-t…

Web前端:angular对比React——选择2022年Web开发的理想框架

Javascript世界中的框架列表不断增长和变化&#xff0c;但有两个框架从其他框架中脱颖而出。Angular和React是市场上最受欢迎的框架之一&#xff0c;代表了创建web应用程序和网站的两种不同方法。 试图利用web开发框架的开发人员和企业家现在正在分析Angular和React——这两种方…

软考下午题第2题——E-R图 UML图 逻辑结构设计-示题与解析

下午的第二题主要是找【属性】【主键】【外键】【候选键】之间的关系。 候选键&#xff1a;属性或者是属性组合&#xff0c;其值能够唯一地标识一个元组 主键&#xff1a;在一个关系中可能有多个候选键&#xff0c;从中选择一个作为主键 外键&#xff1a;如果一个关系中的属性或…

微机期末复习指导

目录 位扩展定义字扩展定义1、线选法定义优点缺点2、部分译码法定义3、全译码法定义优点缺点⭐字位扩展定义问题

高压放大器基于声纹影法的声可视化实验的应用

实验名称&#xff1a;高压功率放大器基于声纹影法的声可视化实验应用 研究方向&#xff1a;声学超表面声学隐身斗篷 实验内容&#xff1a;利用声纹影平台&#xff0c;对所设计的声隐身斗篷进行出射平面波的测量&#xff0c;采用安泰放大器来驱动平面超声波阵列&#xff0c;可以…

CSS3专题-[上篇]:过渡、2D转换、动画

目录 CSS3&#xff1a;前置特性 CSS3&#xff1a;盒子模型 CSS3&#xff1a;图片滤镜与模糊处理 blur()&#xff1a;高斯模糊 CSS3&#xff1a;计算盒子宽度calc()函数 CSS3&#xff1a;过渡效果 transition属性 2D转换&#xff1a;transform属性 translate()方法 * t…

Mybatis MappedStatement

MappedStatement MappedStatement 类是 Mybatis 框架的核心类之一&#xff0c;它存储了一个 sql 对应的所有信息 Mybatis 通过解析 XML 和 mapper 接口上的注解&#xff0c;生成 sql 对应的 MappedStatement 实例&#xff0c;并放入 SqlSessionTemplate 中 configuration 类属…

凭此五点 这款信创传输系统解决了传输的迫切需求

早在20世纪80年代&#xff0c;我国政府IT底层基础软硬件的自主创新提出了相关要求&#xff0c;但受制于国外巨头垄断关键技术&#xff0c;诸多系统性风险与安全隐患无力解决。自2018年以来&#xff0c;在中兴和华为等公司供应链危机的催化下&#xff0c;信创产业进入快速发展期…

Verilog设计参数化的译码器与编码器,以及设计4位格雷码计数器

Verilog设计参数化的译码器与编码器&#xff0c;以及设计4位格雷码计数器 使用Quartusmodelsim完成设计 文章目录Verilog设计参数化的译码器与编码器&#xff0c;以及设计4位格雷码计数器1. 参数化的译码器分析代码实现Testbench结果2. 参数化的编码器分析代码Testbench结果3.…

Redis 主从架构数据同步

Redis 主从架构图 主从架构能够很大提升并发能力&#xff0c;master 节点负责写数据&#xff0c;slave 节点负责读数据&#xff0c;这样就涉及到 master 和 slave 数据同步的一个过程 一起来看一下数据是如何同步的吧 redis 的主从同步机制可以确保 master 和 slave 之间的数据…

Kubernetes 架构介绍

目录 一、Kubernetes 架构 1、Kubernetes 是什么&#xff1f; 2、Kubernetes 架构 3、Master 节点 4、Node 节点 5、推荐Add-ons 6、Kubeadm 7、查看组件运行状态 8、Kubeadm 容器化组件 二、namespace 1、命名空间 — namespace 2、常用命名空间命令 1. 查看存在哪…

【操作系统】混合索引分配和链接分配相关练习题

混合索引分配练习题&#xff1a; 比较简单&#xff0c;容易理解 练习1&#xff1a; 在UNIX操作系统中&#xff0c;给文件分配外存空间采用的是混合索引分配方式&#xff0c;如下图所示。UNIX系统中的某个文件的索引结点指示出了为该文件分配的外存的物理块的寻找方法。在该索…

C++ 并行编程

C 并行编程1. 进程和线程1.1 常规解释1.2 总结1.3 具体理解1.4 为什么使用多线程1.5 进程和线程的区别2. 并发与并行2.1 多进程并发2.2 多线程并发3. C中的多线程4. 时间管理4.1 C语言&#xff1a;time.h4.2 C11时间标准库&#xff1a;std::chrono4.2.1 获取时间段 int64_t/dou…

SQL学习十九、使用游标

游标&#xff08;cursor&#xff09;是一个存储在 DBMS 服务器上的数据库查询&#xff0c; 它不是一条 SELECT 语句&#xff0c;而是被该语句检索出来的结果集。在存储了 游标之后&#xff0c;应用程序可以根据需要滚动或浏览其中的数据。 我们通常的检索操作会返回一组称为结…

vue3+antd中使用Dayjs实现输出的日期格式化,和限制自定义日期选择器的可选范围

场景复现 在vue3antd项目中用到了日期选择器&#xff0c;但是默认的日期选择的结果是标准的日期格式&#xff0c;我们往往需要对最后的结果进行一定的格式化输出 一般输出的是这种标准的数据格式 如果我们想对时间进行指定的格式化输出&#xff0c;通常大家会想到moment&…

如何在页面中制作悬浮发布按钮弹窗

效果展示&#xff1a; 前置准备&#xff1a; 1.已搭建好&#xff0c;待添加悬浮层的页面 2.icon素材 具体步骤&#xff1a;&#xff08;3&#xff09; 1.添加悬浮层页面 2.配置悬浮层关闭触发器 3.配置首页发布icon触发器和动画 步骤分解&#xff1a; 1.添加悬浮层页面 1.1…

2022 年跨境电商要尝试的 25 个黑五营销技巧

关键词&#xff1a;黑五营销、黑色星期五活动、跨境电商黑五 我们汇总了以下最佳跨境电商黑五创意清单&#xff1a; 黑五营销技巧分享 如何宣传您的黑色星期五优惠 小型企业的黑五营销创意 黑五营销提示 随意跳到您最感兴趣的部分&#xff0c;或通读它们&#xff0c;看看…

JAVA序列化和反序列化学习笔记

0x01 开始学习JAVA反序列化&#xff0c;参考 《安全漫谈》和feng师傅的文章一步一步来&#xff0c;希望 能赶在这个学期学完java最基础的东西&#xff0c; 笔记做到这里方便自己查阅&#xff0c;也是事先实操了一下 &#xff0c;才写的笔记 概念&#xff1a; JAVA 序列化 就是…