介绍
在数学上,运算是对一个或多个称为操作数映射到输出值的值的计算。的操作者是映射到的操作数的输出值符号或标志。
一元运算是只有一个操作数的运算。该操作数出现在运算符之前或之后。
一元运算符比标准的 JavaScript 函数调用更有效。此外,一元运算符不能被覆盖,因此它们的功能是有保证的。
操作员 | 解释 |
---|---|
一元加 ( + ) |
尝试将操作数转换为数字 |
一元否定 ( - ) |
尝试将操作数转换为数字并在之后取反 |
增量 ( ++ ) |
在其操作数上加一 |
递减 ( -- ) |
从其操作数减一 |
逻辑非 ( ! ) |
转换为布尔值然后否定它 |
按位非 ( ~ ) |
反转操作数中的所有位并返回一个数字 |
typeof |
返回一个字符串,它是操作数的类型 |
delete |
删除数组的特定索引或对象的特定属性 |
void |
丢弃表达式的返回值。 |
在本文中,您将了解 JavaScript 中的所有一元运算符。
先决条件
如果你想跟随这篇文章,你需要:
一元加 ( +
)
一元加号运算符 (
+
) 在其操作数之前并计算其操作数,但如果尚未将其转换为数字,则会尝试将其转换为数字。
它可以将数字、布尔值(true
和false
)的所有字符串表示形式转换null
为数字。数字将包括整数、浮点数、十六进制、科学(指数)表示法和Infinity
.
如果操作数无法转换为数字,则一元加运算符将返回NaN
。
这里有些例子:
手术 | 结果 |
---|---|
+3 |
3 |
+"3" |
3 |
+"-3" |
-3 |
+"3.14" |
3.14 |
+"123e-5" |
0.00123 |
+"0xFF" |
255 |
+true |
1 |
+false |
0 |
+null |
0 |
+"Infinity" |
Infinity |
+"not a number" |
NaN |
+function(val){ return val } |
NaN |
一个对象只有在它有一个键valueOf并且它的函数返回任何上述类型时才能被转换。
+{
valueOf: function() {
return "0xFF"
}
}
这将输出以下内容:
Output255
试验不同的值后,您可以继续下一个一元运算符。
一元否定 ( -
)
一元否定运算符 (
-
) 在其操作数之前并否定它。
一元否定和加号都执行与Number()
非数字函数相同的操作。
这里有些例子:
手术 | 结果 |
---|---|
-3 |
-3 |
-"3" |
-3 |
-"-3" |
3 |
-"3.14" |
-3.14 |
-"123e-5" |
-0.00123 |
-"0xFF" |
-255 |
-true |
-1 |
-false |
-0 |
-null |
-0 |
-"Infinity" |
-Infinity |
-"not a number" |
-NaN |
-function(val){ return val } |
-NaN |
-{ valueOf: function(){ return "0xFF" } } |
-255 |
试验不同的值后,您可以继续下一个一元运算符。
增量 ( ++
)
递增运算符 (
++
) 递增(加一)其操作数并返回一个值。
它可以用作后缀或前缀运算符。
- 后缀:表示运算符在操作数 (
y++
) 之后。这将返回递增之前的值。 - 前缀:运算符位于操作数 (
++y
)之前。使用它作为前缀返回递增后的值。
这是一个后缀示例:
x = 4 // x = 4
y = x++ // y = 4 and x = 5
y
设置为递增前的值,并添加1
到x
.
使用 postfix 时要小心重置值:
var z = 5 // z = 5
z = z++ // z = 5
z
设置为递增前的值。
这是一个前缀示例:
x = 4 // x = 4
y = ++x // y = 5 and x = 5
y
设置为递增后的值,并将 1 添加到x
。
var z = 5 // z = 5
z = ++z // z = 6
z
设置为递增后的值。
试验不同的值后,您可以继续下一个一元运算符。
递减 ( --
)
递减运算符 (
--
) 递减(减去 1)其操作数并返回一个值。
它可以用作后缀或前缀运算符。
- 后缀:表示运算符在操作数 (
y--
) 之后。这将返回递减之前的值。 - 前缀:运算符位于操作数 (
--y
)之前。使用它作为前缀返回递减后的值。
这是一个后缀示例:
x = 4 // x = 4
y = x-- // y = 4 and x = 3
设置y
为递减前的值,并从 中删除 1 x
。
var z = 5 // z = 5
z = z-- // z = 5
z
设置为递减前的值。
这是一个前缀示例:
x = 4 // x = 4
y = --x // y = 3 and x = 3
设置y
为递增后的值,并将 1 添加到x
。
var z = 5 // z = 5
z = --a // z = 4
z
设置为递减后的值。
试验不同的值后,您可以继续下一个一元运算符。
逻辑非 ( !
)
逻辑 NOT (
!
) 运算符(逻辑补码、否定)将真变为假,反之亦然。
这里有些例子:
手术 | 结果 |
---|---|
!false |
true |
!NaN |
true |
!0 |
true |
!null |
true |
!undefined |
true |
!"" |
true |
!true |
false |
!-3 |
false |
!"-3" |
false |
!42 |
false |
!"42" |
false |
!"string" |
false |
!"true" |
false |
!"false" |
false |
!{} |
false |
![] |
false |
!function(){} |
false |
这些示例演示了false
如果操作数可以转换为true
,则逻辑 NOT 如何返回,否则返回false
。
您也可以使用双重否定 ( !!
)。
!!1 === true // returns true
!!0 === false // returns true
!!'hi' === true // returns true
让我们检查最后一个例子。
首先,字符串的否定返回false
:
!'hi' // returns false
然后, , 的否定false
返回true
:
!false // returns true
因此:
true === true // returns true
试验不同的值后,您可以继续下一个一元运算符。
按位非 ( ~
)
按位非运算符 (
~
) 反转其操作数的位。
按位不在数字上的结果是:-(x + 1)
。
一种 | 不是 |
---|---|
0 | 1 |
1 | 0 |
这里有些例子:
手术 | 结果 |
---|---|
~3 |
-4 |
~"3" |
-4 |
~"-3" |
2 |
~"3.14" |
-4 |
~"123e-5" |
-1 |
~"0xFF" |
-256 |
~true |
-2 |
~false |
-1 |
~null |
-1 |
~"Infinity" |
-1 |
~"not a number" |
-1 |
~function(val){ return val } |
-1 |
~{ valueOf: function(){ return "0xFF" } } |
-256 |
下表更深入地了解了此操作是如何执行的。
(基数 10) | (基数 2) | 非(基数 2) | 非(基数 10) |
---|---|---|---|
2 | 00000010 | 11111101 | -3 |
1 | 00000001 | 11111110 | -2 |
0 | 00000000 | 11111111 | -1 |
-1 | 11111111 | 00000000 | 0 |
-2 | 11111110 | 00000001 | 1 |
-3 | 11111101 | 00000010 | 2 |
试验不同的值后,您可以继续下一个一元运算符。
typeof
该
typeof
运算符返回一个字符串,指示未计算的操作数的类型。
这里有些例子:
手术 | 结果 |
---|---|
typeof 3 |
'number' |
typeof '3' |
'string' |
typeof -3 |
'number' |
typeof 3.14 |
'number' |
typeof 123e-5 |
'number' |
typeof 0xFF |
'number' |
typeof true |
'boolean' |
typeof false |
'boolean' |
typof null |
'object' |
typeof Infinity |
'number' |
typeof NaN |
'number' |
typeof function(val){ return val } |
'function' |
typeof { valueOf: function(){ return '0xFF' } } |
object |
typeof [1,2,3] |
'object' |
typeof {hi: "world"} |
'object' |
typeof Date() |
'string' |
typeof new Date() |
'object' |
typeof undefined |
'undefined' |
试验不同的值后,您可以继续下一个一元运算符。
delete
JavaScript
delete
运算符从对象中删除一个属性;如果不再持有对同一属性的引用,它最终会自动释放。
它返回true
如果成功删除属性或者该属性不存在。
false
如果删除项目失败,则返回。
delete
对函数和变量都没有任何影响。
以下是尝试delete
在变量上使用的示例:
var variableExample = 1;
delete variableExample; // returns false
console.log(variableExample); // returns 1
这是尝试delete
在函数上使用的示例:
function functionExample(){};
delete functionExample; // returns false
console.log(functionExample); // returns function functionExample(){}
这是尝试delete
在数组上使用的示例:
var arrayExample = [1,1,2,3,5]
delete arrayExample // returns false
console.log(arrayExample); // [1,1,2,3,5]
这是尝试delete
在对象上使用的示例:
var objectExample = {propertyExample: "1"}
delete objectExample // returns false
console.log(objectExample); // returns Object { propertyExample: "1" }
现在,这是一个使用delete
文字符号的属性的示例:
var inventory = {"apples": 1, "oranges": 2}
delete inventory["apples"] // returns true
console.log(inventory); // returns Object { "oranges": 2 }
console.log(inventory["apples"]); // returns undefined
这是delete
在带有点符号的属性上使用的示例:
var inventory = {"apples": 1}
delete inventory.apples; // returns true
console.log(inventory); // returns {}
console.log(inventory.apples); // returns undefined
以下是尝试delete
在不存在的属性上使用的示例:
var inventory = {"apples": 1};
delete inventory.oranges; // returns true
console.log(inventory.apples); // returns 1
以下是尝试delete
在预定义对象的不可配置属性上使用的示例:
delete Math.PI; // returns false
console.log(Math.PI); // returns 3.141592653589793
delete
对设置为不可配置的对象属性没有影响。它总会回来的false
。
在严格模式下,这将引发SyntaxError
.
以下是尝试delete
在不可配置属性上使用的示例:
var configurableFalseExample = {};
Object.defineProperty(configurableFalseExample, 'name', { value: 'Sammy', configurable: false })
console.log(configurableFalseExample.name); // returns 'Sammy'
delete configurableFalseExample.name // returns false
console.log(configurableFalseExample.name); // returns 'Sammy'
这是delete
在不可配置的属性上使用的示例:
var configurableTrueExample = {};
Object.defineProperty(configurableTrueExample, 'name', { value: 'Sammy', configurable: true })
console.log(configurableTrueExample.name); // returns 'Sammy'
delete configurableTrueExample.name // returns true
console.log(configurableTrueExample.name); // returns undefined
阅读更多关于defineProperty()
.
var
, let
, 和const
创建不能用delete
操作符删除的不可配置的属性:
以下是var
在window
范围(例如,Web 浏览器)中设置 a 的示例:
var num = 1;
Object.getOwnPropertyDescriptor(window, "num")
这将返回:
Output{
value: 1,
writable: true,
enumerable: true,
configurable: false
}
然后尝试delete
变量:
delete num;
这将返回:
Outputfalse
这是var
在global
范围(例如,节点)中设置 a 的示例:
var num = 1;
Object.getOwnPropertyDescriptor(global, "num")
这将返回:
Output{
value: 1,
writable: true,
enumerable: true,
configurable: false
}
现在,这是一个对象的例子:
var inventory = { "apples": 1 };
Object.getOwnPropertyDescriptor(inventory, "apples")
这将返回:
Output{
value: 1,
writable: true,
enumerable: true,
configurable: true
}
请注意,该configurable
属性被标记为true
。
Arrays
Object
在 JavaScript 中被视为类型。因此,这种方法将适用于它们:
var arrayExample = [20,30,40];
console.log(arrayExample.length); // returns 3
delete arrayExample[2] // returns true
console.log(arrayExample); // returns [ 20, 30, <1 empty item> ]
console.log(arrayExample[2]); // returns undefined
console.log(arrayExample.length); // returns 3
该delete
运营商将只删除值,而不是数组的索引。它将将该特定索引的值保留为undefined
。这就是长度不变的原因。
在strict
mode 中,由于使用对变量、函数参数或函数名称的直接引用而delete
引发 a SyntaxError
。
以下是直接引用变量的示例,该变量将导致SyntaxError
:
‘use strict’
var inventory = {"apples": 1, "oranges": 2};
delete inventory;
这将产生:
OutputUncaught SyntaxError: Delete of an unqualified identifier in strict mode.
下面是一个函数参数的例子,它会导致一个SyntaxError
:
‘use strict’
function Person() {
delete name;
var name;
}
下面是一个函数名的例子,它会导致一个SyntaxError
:
‘use strict’
function yo() { }
delete yo;
以下是使用时要始终考虑的一些提示delete
:
- 尝试删除不存在的属性
delete
将返回true
但不会对对象产生影响。 - 删除只影响对象自己的属性。这意味着如果对象的原型链上存在同名属性,则
delete
不会对其产生影响。删除后,对象将使用原型链中的属性。 - 变量声明
var
,let
以及const
不能从全局范围或功能的范围中删除。- 含义:
delete
不能删除全局作用域或函数作用域内的任何函数。 delete
适用于作为对象一部分的函数(除了全局作用域)。
- 含义:
- 无法删除不可配置的属性。
delete
不工作在任何的内置状物体Math
,Array
,Object
被非配置有类似的方法创建或属性Object.defineProperty()
。
试验不同的值后,您可以继续下一个一元运算符。
void
的
void
运算符计算给定表达式,然后返回undefined
。
void
运算符的主要目的是返回undefined
. void 运算符指定要计算的表达式而不返回值。
void 运算符以下列任一方式使用:
void (expression)
或void expression
。
注:该void
操作不是一个函数,因此()
不是必需的,但它是一个良好的作风来使用它们根据MDN
下面是一个例子:
void 0
这将返回:
Outputundefined
下面是一个函数的例子:
var functionExample = function () {
console.log('Example')
return 4;
}
如果您引用该函数:
var result = functionExample()
console.log(result);
这将返回值4
:
Output4
但是,如果您void
的功能:
var voidResult = void (functionExample())
console.log(voidResult);
这将返回值undefined
:
Outputundefined
该void
运算符还可用于将表达式指定为超文本链接。表达式会被计算,但不会代替当前文档加载。
这是void(0)
在链接上使用的示例:
<a href="javascript:void(0)">Link to perform no action.</a>
上面的代码创建了一个当用户点击它时什么都不做的链接。这是因为void(0)
评估为undefined
.
这是void(document.form.submit())
在链接上使用的示例:
<a href="javascript:void(document.form.submit())">Link to submit a form.</a>
该代码创建一个链接,当用户单击它时提交表单。
尝试不同的值。
结论
在本文中,您了解了 JavaScript 中的所有一元运算符。
处理多个运算符时,请始终考虑操作顺序。这是减轻不可预见错误的良好做法。
这是一个简短的表格,显示了使用 Javascript 时操作的优先顺序。同一级别的操作数具有相同的优先顺序。
操作员类型 | 运营商 | 例子 |
---|---|---|
成员 | . [] |
[1,2,3] |
调用/创建实例 | () new |
var vehicle = new Vehicle(); |
否定/增加 | ! ~ + - ++ -- typeof void delete |
typeof [1,2,3] |
乘/除 | * / % |
3 % 3 |
加法/减法 | + - |
3 + 3 |
按位移位 | << >> >>> |
9 << 2 |
关系的 | < <= > >= in instanceof |
[1] instanceof Array |
平等 | == != === !== |
void(0) === undefined |
按位与 | & |
5 & 1 |
按位异或 | ^ |
5 ^ 1 |
按位或 | | | 5 | 1 |
逻辑与 | && |
x < 10 && y > 1 |
逻辑或 | || | x == 5 || y == 5 |
有条件的 | ?: |
(amount < 10) ? "Few" : "Many" |
任务 | = += -= *= = %= <<= >>= >>>= &= ^= |= |
x = 8 |
逗号 | , |
b = 3, c = 4 |
如果您想了解有关 JavaScript 的更多信息,请查看我们的 JavaScript 主题页面以获取练习和编程项目。