JavaScript 内置对象(built-in objects)是 JavaScript 语言提供的预定义对象,它们提供了基本的功能和方法,可以直接在代码中使用。
关于JavaScript内置对象更多情况可见 MDN文档Standard built-in objects - JavaScript | MDN
其开端部分,不太好理解,特地节选补注:
This chapter documents all of JavaScript's standard, built-in objects, including their methods and properties.
本章介绍和说明了 JavaScript 中所有的标准内置对象、以及它们的方法和属性。
The term "global objects" (or standard built-in objects) here is not to be confused with the global object. Here, "global objects" refer to objects in the global scope.
这里的术语“全局对象”(或标准内置对象)不应与 global 对象混淆。这里的“全局对象”指的是处在全局作用域里的多个对象。
【译注:全局对象通常指的是 JavaScript 环境中的顶级对象,如在浏览器中的 window 对象。而这里的“全局对象”(或“标准内置对象”)指的是像 Array、Date、Math 等无需创建实例就可以使用的对象。】
The global object itself can be accessed using the this operator in the global scope. In fact, the global scope consists of the properties of the global object, including inherited properties, if any.
global 对象可以在全局作用域里通过使用 this 访问到【译注:但只有在 ECMAScript 5 的非严格模式下才可以,在严格模式下得到的是 undefined】。其实,全局作用域包含全局对象中的属性,包括它可能继承来的属性(如果有的话)。
Other objects in the global scope are either created by the user script or provided by the host application. The host objects available in browser contexts are documented in the API reference.
全局作用域中的其他对象则可由用户的脚本创建,或由宿主程序提供。浏览器环境中所提供的宿主对象的说明可以在这里找到:API 参考。
【译注:用户脚本创建,例如,用户定义的变量或函数,以及浏览器提供的 Document 对象都属于这个范畴。宿主对象是由浏览器提供的,与 JavaScript 语言核心分开的对象,如 Document、Window 等。】
For more information about the distinction between the DOM and core JavaScript, see JavaScript technologies overview.
要了解关于 DOM 和核心 JavaScript 之间区别的更多信息,可参阅 JavaScript 技术概述。
内置对象是 JavaScript 语言的核心部分,它们提供了丰富的方法和属性,使得开发者可以更加高效地编写代码。这些内置对象扩展了 JavaScript 的能力,使其能够处理各种常见的编程任务。随着 JavaScript 语言的发展,可能还会有更多的内置对象加入到标准中。
以下是JavaScript的一些主要内置对象:
下面选取几个JavaScript内置对象具体介绍
JavaScript 的 Array 是一种内置对象(有时也称为全局对象),用于构造数组,是灵活的数据结构,可以存储不同类型的数据,并提供了丰富的方法来操作这些数据。
JavaScript 的 Array 是一种全局对象,用于构造数组,它是高级的、类似列表的对象。
特点
创建数组
创建数组的方法有几种:
let fruits = ['Apple', 'Banana', 'Cherry'];
let fruits = new Array('Apple', 'Banana', 'Cherry');
let fruits = Array.of('Apple', 'Banana', 'Cherry');
使用数组
一旦创建了数组,就可以使用多种方法来操作数组:
console.log(fruits[0]); // 输出: Apple
fruits[1] = 'Blackberry'; // 将第二个元素更改为 'Blackberry'
fruits.push('Dragonfruit'); // 在数组的末尾添加新元素
let firstFruit = fruits.shift(); // 移除数组的第一个元素并返回它
fruits.sort(); // 对数组的元素进行排序
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
// 或者使用 forEach 方法
fruits.forEach(fruit => console.log(fruit));
let [first, second] = fruits;
console.log(first); // 输出: Apple
console.log(second); // 输出: Blackberry
JavaScript 中的函数是核心概念,它们提供了强大的编程能力。函数的灵活性和一等公民的特性使得 JavaScript 成为一个功能丰富的、表达性强的语言。
特点
创建函数
创建函数的方法有几种:
function greet(name) {
return `Hello, ${name}!`;
}
const greet = function(name) {
return `Hello, ${name}!`;
};
const greet = name => `Hello, ${name}!`;
const greet = new Function('name', 'return `Hello, ${name}!`;');
使用函数
console.log(greet('Alice')); // 输出: Hello, Alice!
const person = { name: 'Bob' };
const greetBob = greet.bind(person);
console.log(greetBob()); // 输出: Hello, Bob!
function processUserInput(callback) {
const name = prompt('Please enter your name.');
console.log(callback(name));
}
processUserInput(greet);
function createGreeting(greeting) {
return function(name) {
return `${greeting}, ${name}!`;
};
}
const sayHello = createGreeting('Hello');
console.log(sayHello('Alice')); // 输出: Hello, Alice!
JavaScript 的 Math 对象提供了一系列的属性和方法,用于执行常见的数学运算。Math 是一个内置对象,它具有数学常数和函数的属性和方法。不像其他全局对象,Math 不是一个构造函数。所有在 Math 对象中的属性和方法都是静态的。
Math 对象的属性
Math 对象包含了多个数学常数的属性,例如:
数学常数使用示例:
// 圆周率 PI
console.log(Math.PI); // 输出: 3.141592653589793
// 自然对数的底数 E
console.log(Math.E); // 输出: 2.718281828459045
// 2 的平方根
console.log(Math.SQRT2); // 输出: 1.4142135623730951
Math 对象的方法
Math 对象提供了大量的方法来执行数学运算:
四舍五入和取整
幂和根
对数
三角函数
随机数
最大值和最小值
绝对值
符号
三角函数的超越亲戚
其他
常用方法的使用示例
以下是一些如何使用 Math 对象的方法的示例:
// 四舍五入
console.log(Math.round(4.7)); // 输出: 5
// 幂运算
console.log(Math.pow(2, 3)); // 输出: 8
// 平方根
console.log(Math.sqrt(16)); // 输出: 4
// 随机数
console.log(Math.random()); // 输出: 0.123456789 (示例值)
// 最大值和最小值
console.log(Math.max(1, 3, 2)); // 输出: 3
console.log(Math.min(1, 3, 2)); // 输出: 1
// 三角函数
console.log(Math.sin(Math.PI / 2)); // 输出: 1
console.log(Math.cos(Math.PI)); // 输出: -1
// 绝对值
console.log(Math.abs(-10)); // 输出: 10
// 符号
console.log(Math.sign(-10)); // 输出: -1
Math 对象的方法是非常有用的工具,可以帮助你在 JavaScript 中执行各种数学运算。由于它们是静态方法,你可以直接在 Math 对对象上调用它们,而不需要创建 Math 的实例。
数学计算的注意事项
在使用 JavaScript 进行数学计算时,需要注意浮点数的精度问题。由于 JavaScript 使用 IEEE 754 双精度浮点数表示法,这可能导致一些不精确的结果。例如:
console.log(0.1 + 0.2); // 输出: 0.30000000000000004
在处理金融或其他需要高精度的计算时,可能需要使用特定的库来避免这种精度问题。
JavaScript 的 Number 对象是一个包装对象,允许你处理数值数据。它可以用来表示整数或浮点数。Number 对象还提供了一系列的属性和方法,用于执行数值相关的操作。
Number 对象的属性
Number 对象提供了以下一些有用的静态属性:
Number 对象的方法
Number 对象还包含了一系列的方法,用于数值的转换和处理:
全局 Number 函数
JavaScript 还提供了一些全局 Number 函数,可以用来处理数值:
使用 Number 对象的示例
let num = new Number(123.456);
// 转换为字符串
console.log(num.toString()); // 输出: '123.456'
console.log(num.toString(16)); // 输出: '7b.74bc6a7ef9db22d'
// 格式化为固定小数位数
console.log(num.toFixed(2)); // 输出: '123.46'
// 转换为指数形式
console.log(num.toExponential(1)); // 输出: '1.2e+2'
// 格式化为指定长度
console.log(num.toPrecision(3)); // 输出: '123'
// 获取原始数值
console.log(num.valueOf()); // 输出: 123.456
// 使用全局函数:
创建 Number 对象
通常,我们不需要显式创建一个 Number 对象,因为 JavaScript 会自动将数字字面量转换为 Number 类型。但如果需要创建一个 Number 对象,可以使用 new 关键字:
let numObj = new Number(10);
console.log(typeof numObj); // 输出: 'object'
然而,在实际开发中,直接使用数字字面量更为常见和方便:
let num = 10;
console.log(typeof num); // 输出: 'number'
类型转换
JavaScript 在需要的时候会自动将 Number 对象转换为原始数字值,通常不需要手动调用 valueOf 方法。此外,当你尝试进行数学运算或者比较时,Number 对象会被当作普通数字处理。
注意事项
使用 Number 对象和方法时,了解这些属性和行为将帮助你更好地处理 JavaScript 中的数值。
JavaScript 中的 String 对象用于处理文本(字符串)数据。字符串可以由双引号("...")、单引号('...')或反引号(`...`)包围,反引号还允许字符串插值和多行字符串。
创建 String 对象
虽然通常直接使用字符串字面量,但也可以使用 new 关键字来创建 String 对象:
let stringObj = new String("Hello, World!");
console.log(typeof stringObj); // 输出: 'object'
然而,大多数情况下,我们会直接使用字符串字面量,因为它们更简洁:
let str = "Hello, World!";
console.log(typeof str); // 输出: 'string'
String 属性和方法
String 对象和字面量都可以访问许多有用的属性和方法:
模板字符串
ES6 引入了模板字符串,提供了创建包含变量和表达式的字符串的简便语法。模板字符串使用反引号包围,并通过 ${expression} 插入变量或表达式:
let name = "Alice";
let greeting = `Hello, ${name}!`;
console.log(greeting); // 输出: 'Hello, Alice!'
模板字符串还支持多行文本,无需使用连接符或特殊字符:
let multiLineString = `This is a string
that spans multiple
lines.`;
console.log(multiLineString);
字符串不可变性
在 JavaScript 中,字符串是不可变的,这意味着一旦创建,字符串的内容就不能被改变。任何看似修改字符串的操作实际上都是创建了一个新的字符串。
类型转换
通常,当你使用字符串方法时,如果你对一个字符串字面量(而不是 String 对象)使用方法,JavaScript 会自动将字面量转换为 String 对象,以便可以调用相应的方法。完成方法调用后,结果通常是一个原始字符串,而不是 String 对象。这是因为 JavaScript 在内部进行了自动装箱和拆箱操作。
字符串比较
在 JavaScript 中,可以使用比较运算符(==、===、!=、!==、<、> 等)来比较字符串。这些比较是基于标准的字典顺序,使用字符的 Unicode 值来进行比较。
console.log("a" < "b"); // 输出: true
console.log("hello" === "hello"); // 输出: true
字符串和数组之间的转换
let str = "apple,banana,cherry";
let fruits = str.split(","); // ['apple', 'banana', 'cherry']
let fruitsString = fruits.join(", "); // 'apple, banana, cherry'
字符串编码
JavaScript 使用 Unicode 字符集。.charCodeAt(index) 和 .codePointAt(index) 方法可以用来获取字符串中特定位置字符的 Unicode 编码。相对的,String.fromCharCode(code) 和 String.fromCodePoint(code) 可以将 Unicode 编码转换回字符串。
国际化
Intl 对象和 String.prototype.localeCompare() 方法提供了基于语言环境的字符串比较、数字格式化和日期时间格式化。
console.log("ä".localeCompare("z", "de")); // 输出: -1,因为在德语中 'ä' 在 'z' 之前
正则表达式
字符串可以与正则表达式一起使用,以执行复杂的搜索和替换操作。例如,.match(regexp) 方法可以找到字符串中与正则表达式匹配的所有子串。
let text = "The rain in SPAIN stays mainly in the plain";
let result = text.match(/ain/g); // 输出: ['ain', 'ain', 'ain']
安全性
当处理来自用户的输入时,应该注意避免安全漏洞,如跨站脚本攻击(XSS)。在将用户输入插入到页面之前,应该对其进行适当的转义。
性能
对于大量的字符串操作,如拼接,使用数组的 .join() 方法通常比使用 + 或 += 操作符更高效。这是因为字符串的不可变性意味着每次使用 + 或 += 时,实际上都会创建一个新的字符串,这可能导致不必要的内存消耗和性能损失。
JavaScript 中的 Object 对象是一个基础构造函数,几乎所有的 JavaScript 对象都是 Object 的实例或继承自 Object。以下是关于 Object 对象的一些重要方面:
创建对象
在 JavaScript 中,有几种方式可以创建对象:
Object 属性和方法
Object 提供了多种静态方法来处理对象:
原型链
JavaScript 对象有一个称为原型的内部属性,对象从其原型继承属性和方法。原型本身也是一个对象,因此原型可能也有自己的原型,这样就形成了一个原型链。当访问对象的属性时,如果对象本身没有这个属性,JavaScript会沿着原型链向上查找,直到找到该属性或达到原型链的顶端(通常是 Object.prototype),如果在原型链中没有找到该属性,则返回 undefined。
原型继承
在 JavaScript 中,继承是通过原型链实现的。当一个函数被创建时,JavaScript 引擎会为这个函数添加一个 prototype 属性,指向一个原型对象。当使用 new 关键字创建一个新对象时,这个新对象内部的 [[Prototype]] 隐藏属性会被赋值为构造函数的 prototype 属性。这样,新对象就可以访问原型对象上的属性和方法。
例如:
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a noise.`);
};
function Dog(name) {
Animal.call(this, name); // 调用父构造函数,并将 this 绑定到当前对象
}
Dog.prototype = Object.create(Animal.prototype); // 设置 Dog 的原型为 Animal 的实例
Dog.prototype.constructor = Dog; // 设置构造函数为 Dog
Dog.prototype.bark = function() {
console.log(`${this.name} barks.`);
};
let dog = new Dog('Rex');
dog.speak(); // Rex makes a noise.
dog.bark(); // Rex barks.
在这个例子中,Dog 继承了 Animal。通过设置 Dog.prototype 为 Animal.prototype 的实例,Dog 的实例就可以访问 Animal 原型上的 speak 方法。同时,我们也给 Dog 添加了一个新的方法 bark。
属性描述符
在 JavaScript 中,对象的属性有一些内部特性,这些特性定义了属性的行为。这些特性可以通过属性描述符来控制。属性描述符有两种类型:数据描述符和存取描述符。
属性描述符还有两个通用键:
例如,可以使用 Object.defineProperty() 来定义或修改属性及其描述符:
let obj = {};
Object.defineProperty(obj, 'property1', {
value: 42,
writable: false,
enumerable: true,
configurable: true
});
在这个例子中,obj 对象有一个名为 property1 的属性,其值为 42,不可写(即不可修改),可枚举,且可配置。
不可变性
在 JavaScript 中,不可变性是指对象的状态无法被改变。虽然 JavaScript 中的原始数据类型(如数字、字符串、布尔值等)是不可变的,但对象和数组默认是可变的。不过,你可以采取一些措施来模拟不可变性。
Object.freeze()
Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象之后,不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、或者可写性,以及不能修改已有属性的值。此外,冻结一个对象的原型也不能被修改。Object.freeze() 返回和传入的参数相同的对象。
const obj = {
prop: 42
};
Object.freeze(obj);
obj.prop = 33;
// 尝试修改冻结对象的属性不会有任何效果
console.log(obj.prop); // 输出 42
Object.seal()
Object.seal() 方法可以封闭一个对象,阻止添加新属性同时将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以被改变。
const obj = {
prop: 42
};
Object.seal(obj);
obj.prop = 33;
obj.newProp = 'test';
// 可以修改现有属性的值,但不能添加新属性
console.log(obj.prop); // 输出 33
console.log(obj.newProp); // undefined,因为添加新属性无效
Object.preventExtensions()
Object.preventExtensions() 方法可以让一个对象变得不可扩展,也就是永远不能再添加新的属性。
const obj = {
prop: 42
};
Object.preventExtensions(obj);
obj.prop = 33;
obj.newProp = 'test';
// 可以修改现有属性的值,但不能添加新属性
console.log(obj.prop); // 输出 33
console.log(obj.newProp); // undefined,因为添加新属性无效
对象控制方法
除了上述的 Object.freeze(), Object.seal(), 和 Object.preventExtensions(),JavaScript 还提供了一些方法来检查对象的不可变性状态:
这些方法可以帮助你了解对象的当前状态,并根据需要进行相应的操作。不过,需要注意的是,这些不可变性方法并不是深度的,它们只影响对象本身的直接属性。如果对象的属性值是另一个对象,那么这个嵌套的对象的属性是可以被修改的,除非它也被冻结或封闭。