JavaScript操作符与表达式详解:从基础语法到高级用法
本文系统讲解JavaScript中的核心操作符与表达式。涵盖一元操作符(delete、typeof、void)、关系操作符(in、instanceof)及关键表达式(this、super、new、展开语法、各类函数定义)。深入解析各语法的执行机制、返回值及实际应用场景,帮助开发者准确掌握JS底层逻辑。
一元操作符详解
一、一元操作符
1.delete操作符
delete 操作符用于移除对象中的指定属性;若该属性不再被任何引用指向,其占用的内存最终将被释放
语法:delete expression
delete 操作符旨在从指定对象中移除目标属性。若删除操作成功执行则返回 true,否则返回 false
let Employee = {
age: 28,
name: 'abc',
designation: 'developer'
};
console.log(delete Employee.name); // returns true
console.log(delete Employee.age); // returns true
console.log(Employee); //{designation: "developer"}
2.typeof操作符
typeof 操作符返回一个字符串,该字符串表示未经计算的操作数所属的数据类型
语法:typeof operand; typeof (operand);
typeof NaN === 'number';
typeof Number(1) === 'number';
typeof "" === 'string';
typeof true === 'boolean';
typeof Symbol('foo') === 'symbol';
typeof undefined === 'undefined';
typeof null === 'object'
typeof [1, 2, 4] === 'object';
typeof new Boolean(true) === 'object';
typeof new Number(1) === 'object';
typeof new String("abc") === 'object';
typeof function(){} === 'function';
3.void运算符
void 运算符对给定的表达式进行求值计算,随后返回 undefined
语法:void expression
<a href="javascript:void(0);" rel="external nofollow" >
这个链接点击之后不会做任何事情,如果去掉 void(),
点击之后整个页面会被替换成一个字符 0。
</a>
<p> chrome中即使<a href="javascript:0;" rel="external nofollow" >也没变化,firefox中会变成一个字符串0 </p>
<a href="javascript:void(document.body.style.backgroundColor='green');" rel="external nofollow" >
点击这个链接会让页面背景变成绿色。
</a>
关系操作符解析
二、关系操作符
1.in运算符
若指定的属性存在于指定对象或其原型链中,则 in 运算符返回 true
语法:prop in object
let trees = new Array("redwood", "bay", "cedar", "oak", "maple");
console.log(0 in trees); // 返回true
console.log(3 in trees); // 返回true
console.log(6 in trees); // 返回false
console.log("bay" in trees); // 返回false (必须使用索引号,而不是数组元素的值)
console.log("length" in trees); // 返回true (length是一个数组属性)
2.instanceof运算符
instanceof 运算符用于测试对象在其原型链中是否存在对应构造函数的 prototype 属性
语法:object instanceof constructor
let simpleStr = "This is a simple string";
let myString = new String();
let newStr = new String("String created with constructor");
let myDate = new Date();
let myObj = {};
simpleStr instanceof String; // 返回 false, 检查原型链会找到 undefined
myString instanceof String; // 返回 true
newStr instanceof String; // 返回 true
myString instanceof Object; // 返回 true
myDate instanceof Date; // 返回 true
myObj instanceof Object; // 返回 true, 尽管原型没有定义
关键表达式与语法
三、表达式
1.this
在函数内部,this 的值由函数的调用方式决定。在严格模式下,this 保持其进入执行上下文时的值,因此下文中的 this 将默认为 undefined
function f2(){
"use strict"; // 这里是严格模式
return this;
}
f2() === undefined; // true
当函数主体中使用 this 关键字时,可通过调用继承自 Function.prototype 的 call 或 apply 方法,将 this 值绑定至调用时的特定对象
function add(c, d) {
return this.a + this.b + c + d;
}
let o = {a: 1, b: 3};
// 第一个参数是作为‘this'使用的对象
// 后续参数作为参数传递给函数调用
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
调用 f.bind(someObject) 会生成一个与原函数 f 具有相同函数体和作用域的新函数,但在此新函数中,this 将永久绑定至 bind 方法的第一个参数,无论该函数如何被调用
function f(){
return this.a;
}
let g = f.bind({a:"azerty"});
console.log(g()); // azerty
let h = g.bind({a:'yoo'}); // bind只生效一次!
console.log(h()); // azerty
在箭头函数中,this 与封闭词法上下文中的 this 保持一致。在全局代码中,它将被设置为全局对象
let globalObject = this;
let foo = (() => this);
console.log(foo() === globalObject); // true
2.super
语法:
super([arguments]); // 调用 父对象/父类 的构造函数
super.functionOnParent([arguments]); // 调用 父对象/父类 上的方法
在构造函数中使用 super 关键字时,其必须单独出现,且需在使用 this 关键字之前调用。super 关键字也可用于调用父对象上的函数
class Human {
constructor() {}
static ping() {
return 'ping';
}
}
class Computer extends Human {
constructor() {}
static pingpong() {
return super.ping() + ' pong';
}
}
Computer.pingpong(); // 'ping pong'
3.new
new 运算符用于创建用户定义的对象类型的实例,或具有构造函数的内置对象的实例
function Car() {}
car1 = new Car()
console.log(car1.color) // undefined
Car.prototype.color = null
console.log(car1.color) // null
car1.color = "black"
console.log(car1.color) // black
4.展开语法
可在函数调用或数组构造时,将数组表达式或字符串在语法层面展开;也可在构建字面量对象时,将对象表达式按 key-value 形式展开
在函数调用时使用展开语法
function myFunction(x, y, z) { }
let args = [0, 1, 2];
myFunction.apply(null, args);
//展开语法
function myFunction(x, y, z) { }
let args = [0, 1, 2];
myFunction(...args);
构造字面量数组时使用展开语法
let parts = ['shoulders','knees'];
let lyrics = ['head',... parts,'and','toes'];
// ["head", "shoulders", "knees", "and", "toes"]
数组拷贝
let arr = [1, 2, 3];
let arr2 = [...arr]; // like arr.slice()
arr2.push(4);
// arr2 此时变成 [1, 2, 3, 4]
// arr 不受影响
连接多个数组
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
// 将 arr2 中所有元素附加到 arr1 后面并返回
let arr3 = arr1.concat(arr2);
//使用展开语法
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
let arr3 = [...arr1, ...arr2];
5.类表达式
类表达式是定义类的一种语法形式
let Foo = class {
constructor() {}
bar() {
return "Hello World!";
}
};
let instance = new Foo();
instance.bar();
// "Hello World!"
6.函数表达式
function 关键字可用于在表达式中定义函数,亦可使用 Function 构造函数配合函数声明来定义函数 函数声明提升与函数表达式提升:JavaScript 中的函数表达式不会发生提升,与函数声明不同,你在定义函数表达式之前无法使用它
/* 函数声明 */
foo(); // "bar"
function foo() {
console.log("bar");
}
/* 函数表达式 */
baz(); // TypeError: baz is not a function
let baz = function() {
console.log("bar2");
};
7.function*表达式
function 关键字可在表达式内部定义生成器函数,这种声明方式(function 关键字后跟随星号)会定义一个生成器函数(generator function),其返回一个 Generator 对象
语法:function* name([param[, param[, ... param]]]) { statements }
function* idMaker(){
let index = 0;
while(index<3)
yield index++;
}
let gen = idMaker();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // undefined
接收参数
function* idMaker(){
let index = arguments[0] || 0;
while(true)
yield index++;
}
let gen = idMaker(5);
console.log(gen.next().value); // 5
console.log(gen.next().value); // 6
传递参数
function *createIterator() {
let first = yield 1;
let second = yield first + 2; // 4 + 2
// first =4 是next(4)将参数赋给上一条的
yield second + 3; // 5 + 3
}
let iterator = createIterator();
console.log(iterator.next()); // "{ value: 1, done: false }"
console.log(iterator.next(4)); // "{ value: 6, done: false }"
console.log(iterator.next(5)); // "{ value: 8, done: false }"
console.log(iterator.next()); // "{ value: undefined, done: true }"
表达式
let x = function*(y) {
yield y * y;
};
JS语法错误会阻止加载吗?区分SyntaxError与资源加载失败
2026-11-05 16:08:46
JavaScript常见SyntaxError语法错误排查与修复方法
2026-11-05 13:58:44
JS中slice、substring和substr截取字符串的区别
2026-11-05 13:43:47
JS 转 TS 手动迁移最佳实践:从配置 tsconfig 到消除 any 类型
2026-11-05 11:53:32
为什么JS数组push后得到的是数字而不是数组?
2026-11-05 09:59:18
