From:https://www.runoob.com/js/js-objects.html
JavaScript 对象
JavaScript 中一切皆对象:字符串、数值、数组、函数 等等。
对象是一种特殊的数据。对象拥有属性和方法。
JS 中一切皆 对象
JavaScript 提供多个内建对象,比如 String、Date、Array 等等。 对象 只是 带有属性和方法 的特殊数据类型。
- 布尔型 可以是一个对象。
- 数字型 可以是一个对象。
- 字符串 也可以是一个对象
- 日期 是一个对象
- 数学 和 正则表达式 也是对象
- 数组 是一个对象
- 甚至 函数 也可以是对象
创建 JavaScript 对象
通过 JavaScript,您能够定义并创建自己的对象。
创建新对象有两种不同的方法:
- 使用 Object 定义并创建对象的实例。
- 使用 字典 创建对象
- 使用函数来定义对象,然后创建新的对象实例。
使用 Object 创建对象
在 JavaScript 中,几乎所有的对象都是 Object 类型的实例,它们都会从 Object.prototype 继承属性和方法。
Object 构造函数创建一个对象包装器。
Object 构造函数,会根据给定的参数创建对象,具体有以下情况:
- 如果给定值是 null 或 undefined,将会创建并返回一个空对象。
- 如果传进去的是一个基本类型的值,则会构造其包装类型的对象。
- 如果传进去的是引用类型的值,仍然会返回这个值,经他们复制的变量保有和源对象相同的引用地址。
- 当以非构造函数形式被调用时,Object 的行为等同于 new Object()。
语法格式:
// 以构造函数形式来调用
new Object([value])
vaule 可以是任何值。
以下实例使用 Object 生成布尔对象:
// 等价于 o = new Boolean(true);
var o = new Object(true);
这个例子创建了对象的一个新实例,并向其添加了5个属性( 包含一个 方法 ):
person = new Object();
person.firstname = "John";
person.lastname = "Doe";
person.age = 50;
person.eyecolor = "blue";
person.getAge = function () { return this.age; }
console.log(person.getAge());
使用 字典 (键值对) 创建对象
也可以使用对象字面量来创建对象,语法格式如下:
{ name1 : value1, name2 : value2,...nameN : valueN }
其实就是大括号里面创建 name:value 对,然后 name:value 对之间以逗号 , 隔开。
person = {firstname: "John", lastname: "Doe", age: 50, eyecolor: "blue"};
JavaScript 对象就是一个 name:value 集合。
使用 function 创建对象
示例:使用 关键字 function 来创建对象,又叫 "对象构造器"。
function person(firstname, lastname, age, eyecolor) {
// this 通常指向的是正在执行的函数本身,或者是指向该函数运行时所属的对象
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
this.eyecolor = eyecolor;
this.eat = function (food) {
console.log(food);
}
this.travel = function (city) {
console.log(city);
}
}
temp_person =new person("John","Doe",50,"blue");
console.log(temp_person.firstname);;
temp_person.eat("苹果")
temp_person.eat("北京")
es6 创建 类(对象)
:https://www.runoob.com/w3cnote/es6-object.html
对象 添加 方法
在 JavaScript 对象中定义函数有以下几种常见的方法:
方法 1:字典形式添加
const obj = {
name: 'Alice',
greet: function() {
console.log(`Hello, ${this.name}!`);
}
};
// 调用方法
obj.greet(); // 输出: Hello, Alice!
方法 2:简写方法(ES6 特性)
const obj = {
name: 'Alice',
greet() {
console.log(`Hello, ${this.name}!`);
}
};
// 调用方法
obj.greet(); // 输出: Hello, Alice!
方法 3:使用 Object.defineProperty
// 通过 Object.defineProperty 添加方法,允许更精细地控制属性(如是否可枚举)。
const obj = { name: 'Alice' };
Object.defineProperty(obj, 'greet', {
value: function() {
// 函数体
console.log(`Hello, ${this.name}!`);
},
writable: true, // 是否可以修改
enumerable: true, // 是否可枚举
configurable: true // 是否可删除或重新定义
});
// 调用方法
obj.greet(); // 输出: Hello, Alice!
方法 4:动态添加方法。
// 在对象创建之后,可以动态添加方法。
const obj = {
name: 'Alice'
};
// 动态添加方法
obj.greet = function() {
console.log(`Hello, ${this.name}!`);
};
// 调用方法
obj.greet(); // 输出: Hello, Alice!
向类的实例添加方法
如果对象是从类创建的,可以在类中定义方法,也可以动态向实例添加方法。
定义在类中:
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, ${this.name}!`);
}
}
const alice = new Person('Alice');
alice.greet(); // 输出: Hello, Alice!
动态添加到实例:
const alice = { name: 'Alice' };
alice.greet = function() {
console.log(`Hello, ${this.name}!`);
};
alice.greet(); // 输出: Hello, Alice!
向对象的原型添加方法
如果多个实例共享一个方法,可以将方法添加到对象的原型中。
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log(`Hello, ${this.name}!`);
};
const alice = new Person('Alice');
alice.greet(); // 输出: Hello, Alice!
总结
- 直接定义方法 和 动态添加方法 是最简单的方式。
- 如果需要更多控制,可以使用
Object.defineProperty
。 - 对于类的实例,最好使用类的方法或原型方法来实现方法共享和代码复用。
访问对象的 "属性、方法"
JavaScript 中定义对象就像定义一个 Python 字典,不过 key 可以用引号(单引号,双引号都可以)包围,也可以不包围。访问对象属性时,可以使用点号,也可以使用键值对字典的形式访问
let temp_obj = {
'name': 'king', // 对象的属性名可以用引号包围,也可以不用包围
'age': 100,
getName: function () {
return this.name;
},
// getAge : () => { return this.age; } // 箭头函数 不能作为 对象的方法
'getAge': function () {
return this.age;
},
'wife': {
name: 'king_wife',
age: 100
}
}
// 访问对象属性时,可以使用点号,也可以使用键值对字典的形式访问
console.log(temp_obj.name);
console.log(temp_obj['age']);
console.log(temp_obj.wife.name);
console.log(temp_obj.wife['age']);
console.log(`name ---> ${temp_obj.getName()}`);
console.log(`age ---> ${temp_obj.getAge()}`);
使用了 String 对象的 length 属性来获得字符串的长度:
var message = "Hello World!";
var x = message.length;
// 在以上代码执行后,x 的值将是: 12
使用 String 对象的 toUpperCase() 方法来将文本转换为大写:
var message = "Hello world!";
var x = message.toUpperCase();
// 在以上代码执行后,x 的值将是:HELLO WORLD!
?. 是可选链操作符
可选链操作符允许您在访问可能为 null
或 undefined
的对象属性时,避免抛出错误。如果对象在链中的某一点为 null
或 undefined
,表达式的求值会立即停止,并返回 undefined
。
const user = { name: { first: 'John' } };
// 传统方式,如果中间部分可能为 undefined,会抛出错误
const lastName = user.name.last;
// 使用可选链,如果中间部分为 undefined,不会抛出错误,而是返回 undefined
const lastNameWithOptionalChaining = user.name?.last;
它使得在处理可能不存在的对象属性时,代码更加简洁和安全。
new Foo.getName() 和 new Foo().getName()
:https://juejin.cn/post/6954263120428662798
new Foo.getName()
先执行Foo.getName
在执行new
new Foo().getName()
先执行 new Foo() 再执行.getName()
创建 对象 的 实例
一旦您有了对象构造器,就可以创建新的对象实例,就像这样:
temp_person = new person("John","Doe",50,"blue");
创建对象的实例时,可以在对象的后面加上小括号,也可以不加。加小括号时可以传递一些参数
下面两种方式都是创建对象的实例,这两种是等价的。
let d1 = new Date; // 创建实例。不加括号
let d2 = new Date() // 创建实例。加上小括号
可以看到,可以正常打印,说明两种方式是等价的。
对象 动态 添加属性
您可以通过为对象赋值,向已有对象添加新属性:
假设 person 对象已存在, 你可以为其添加这些新属性:firstname、lastname、age 以及 eyecolor:
person.firstname = "John";
person.lastname = "Doe";
person.age = 30;
person.eyecolor = "blue";
// x 的值将是:John
x = person.firstname;
对象 动态 添加方法
方法只不过是附加在对象上的函数。
在构造器函数内部定义对象的方法:
function person(firstname, lastname, age, eyecolor) {
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
this.eyecolor = eyecolor;
this.changeName = changeName;
function changeName(name) {
this.lastname = name;
}
}
temp_person = new person("Sally", "Rally", 48, "green");
temp_person.changeName("Doe");
console.log(temp_person.lastname);
changeName() 函数 name 的值赋给 person 的 lastname 属性。
对象 合并
v1 = {'name':'bobo'};
v2 = {'age':30};
//assign:将v2对象的数据合并到v1中。
Object.assign(v1,v2);
console.log(v1);
v1 = {k1: 123}
v2 = {k2: 99, k3: 888}
Object.assign(v1, v2)
console.log(v1) // {k1: 123, k2:99, k3:888}
prototype(原型对象)
- JavaScript 是面向对象的语言,但 JavaScript 不使用类。在 JavaScript 中,不会创建类,也不会通过类来创建对象。
- JavaScript 基于 prototype,而不是基于类的。prototype 是 js 里面给类增加功能扩展的一种模式。所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法。
使用 对象的构造器(constructor)创建对象:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
var person_1 = new Person("John", "Doe", 50, "blue");
var person_2= new Person("Sally", "Rally", 48, "green");
对于已存在的对象构造器,是不能动态的添加新的属性:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
var person_1 = new Person("John", "Doe", 50, "blue");
var person_2 = new Person("Sally", "Rally", 48, "green");
Person.nationality = "English";
console.log(Person.nationality);
console.log(person_1.nationality);
console.log(person_2.nationality);
如果想要添加一个新的属性,则需要在在构造器函数中添加:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
this.nationality = "English";
}
prototype 继承
所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法:
Date
对象从Date.prototype
继承。Array
对象从Array.prototype
继承。Person
对象从Person.prototype
继承。
所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例。
JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
Date
对象、Array
对象、 以及 Person
对象从 Object.prototype
继承。
let arr = [1, 2, 3];
Array.prototype.push.call(arr, 100);
console.log(arr);
添加属性和方法
有的时候我们想要在所有已经存在的对象添加新的属性或方法。
另外,有时候我们想要在对象的构造函数中添加属性或方法。
使用 prototype 属性就可以给对象的构造函数添加新的属性:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
Person.prototype.nationality = "English";
当然我们也可以使用 prototype 属性就可以给对象的构造函数添加新的方法:
function Person(first, last, age, eye) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eye;
}
// 动态添加方法
Person.prototype.name = function() {
return this.firstName + " " + this.lastName
};
var person_1 = new Person("John", "Doe", 50, "blue");
console.log(person_1.name());
总结:
给已有的对象增加属性或者方法
格式:构造函数名.prototype.新属性或者新方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<script>
function Students(name, height, age) {
this.name = name;
this.height = height;
this.age = age;
this.outputInfo = function() {
document.write('name = ' + this.name + '<br\>' + 'height = ' + this.height + '<br\>');
}
}
//增加一个新方法
Students.prototype.newFunction = function() {
document.write('此方法是通过prototype继承后实现的');
}
var stu1 = new Students('zhang', 123, 12);
stu1.outputInfo();
stu1.newFunction();
</script>
</body>
</html>
通常使用构造器(函数体)定义属性,使用原型对象(prototype)定义方法。
如此,构造器只包含属性定义,而方法则分装在不同的代码块,使代码更具可读性:
// 构造器内定义属性
function Fun(a, b) {
this.a = a;
this.b = b;
}
// 原型属性定义方法
Fun.prototype.c = function() {
return this.a + this.b;
}
// etc...
注意,千万不要使用字面量方式来定义属性和方法,否则原有属性和方法会被重写:
function Fn() {};
// 定义属性
Fn.prototype.a = 1;
Fn.prototype.b = 2;
// 字面量定义方法,原型被重写,原有属性和方法被更新
Fn.prototype = {
c : function() {
return this.a + this.b;
}
}
var foo = new Fn();
foo.c(); // NaN
foo.a; // undefined
foo.b; // undefined
三个点(...)
在 JavaScript 中,三个点(...
)有多种用途,常见的有以下几种:
- 展开操作符(Spread Operator):用于数组和对象,可以将一个可迭代对象(如数组)或对象的属性展开。
// 对于数组
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let combined = [...arr1,...arr2];
// combined 将会是 [1, 2, 3, 4, 5, 6]
arr2.push(...arr1); //数组的追加
console.log(arr2);
// 对于对象
let obj1 = {a: 1, b: 2};
let obj2 = {c: 3, d: 4};
let combinedObj = {...obj1,...obj2};
// combinedObj 将会是 {a: 1, b: 2, c: 3, d: 4}
- 剩余参数(Rest Parameters):在函数定义中,用于收集剩余的参数到一个数组中。
function myFunction(a, b,...rest) {
console.log(a);
console.log(b);
console.log(rest);
}
// rest 将会是 [3, 4, 5] 。
myFunction(1, 2, 3, 4, 5);
遍历 数组
JavaScript 中创建数组时,可以使用 [],也可以使用正规军 new Array(),效果都是一样的。
- JavaScript 中数组 === python中的list === java中的list === c语言中的动态数组
- c中的数组是定长的 === java中的数组(也是定长)
// 方法 1:for 循环
let arr = [10, 20, 30, 40];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// 方法 2:forEach 循环。数组的内置方法,接收一个回调函数作为参数。
let arr = [1, 2, 3, 4, 5];
arr.forEach(function(item) {
console.log(item);
});
let arr = [1, 2, 3, 4, 5];
arr.forEach(item => console.log(item));
// 方法 3:for...of 循环。ES6 引入的新循环方式,简洁易用。
for (let value of arr) {
console.log(value);
}
// 方法 4:map 方法 (通常用于创建新数组)
// 对原数组中的每个元素调用一个提供的函数后的返回值
let arr = [1, 2, 3, 4, 5];
let newArray = arr.map(function(item) {
console.log(item);
return item * 2;
});
console.log(newArray);
// 方法 5:while 循环和数组的索引
let arr = [1, 2, 3, 4, 5];
let index = 0;
while (index < arr.length) {
console.log(arr[index]);
index++;
}
遍历 对象
当遍历对象的属性时,使用 hasOwnProperty
方法是一种好习惯,它确保属性是该对象自己的属性,而不是继承自原型链。通常,for...in
循环结合hasOwnProperty
方法是最常见的方式,因为这可以确保仅遍历对象自己的属性,而不包含原型链上的属性。其中,Object.keys
、Object.entries
和Object.values
方法都会忽略对象原型链上的属性。
const init_overload_arg_list = [
['int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom'],
['int', 'java.security.Key', 'java.security.AlgorithmParameters'],
['int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec']
];
// 1. 使用 for 循环遍历二维数组
console.log("使用 for 循环遍历:");
for (let i = 0; i < init_overload_arg_list.length; i++) {
let args = init_overload_arg_list[i];
console.log(`第 ${i + 1} 个参数列表:`, args);
}
// 2. 使用 for...of 循环遍历二维数组
console.log("\n使用 for...of 循环遍历:");
for (let args of init_overload_arg_list) {
console.log(args);
}
// 3. 使用 forEach 遍历二维数组
console.log("\n使用 forEach 遍历:");
init_overload_arg_list.forEach((args, index) => {
console.log(`第 ${index + 1} 个参数列表:`, args);
});
// 4. 使用 map 遍历二维数组并返回新数组(示范如何使用 map)
console.log("\n使用 map 遍历并生成新数组:");
let mappedArgs = init_overload_arg_list.map((args, index) => {
return `第 ${index + 1} 个参数列表: ${args.join(', ')}`;
});
console.log(mappedArgs);
// 5. 使用 while 循环遍历二维数组
console.log("\n使用 while 循环遍历:");
let i = 0;
while (i < init_overload_arg_list.length) {
console.log(`第 ${i + 1} 个参数列表:`, init_overload_arg_list[i]);
i++;
}
// 6. 使用 reduce 方法遍历并汇总数组(示范如何使用 reduce)
console.log("\n使用 reduce 汇总参数列表:");
let combinedArgs = init_overload_arg_list.reduce((acc, args, index) => {
acc.push(`第 ${index + 1} 个参数列表: ${args.join(', ')}`);
return acc;
}, []);
console.log(combinedArgs);
for
循环:经典的传统循环,适合基于索引的遍历,能够精确控制遍历的开始、结束和步长。for...of
循环:用于直接遍历数组的元素,语法简洁,适合用来访问数组中的每个元素。forEach
方法:数组的方法,用于遍历数组的每个元素并执行回调函数。它不返回任何值,只是对每个元素执行操作。map
方法:用于遍历数组并创建一个新的数组,常用于将原数组转换成新数组。while
循环:虽然不常用于数组遍历,但也能用来遍历数组,适合需要在特定条件下停止遍历的情况。reduce
方法:数组方法,用于将数组中的元素“减少”成一个单一的值。它不仅能遍历数组,还能汇总结果。
for...in 循环
for...in
循环会遍历对象自身的以及继承的可枚举属性(不包括Symbol属性)。
let obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key + ': ' + obj[key]);
}
}
JavaScript 中的 for...in 语句循环遍历对象的属性。( 只能 遍历对象的属性 )
语法:( 注意: for...in 循环中的代码块将针对每个属性执行一次。 )
for (variable in object)
{
// 执行的代码……
}
循环遍历对象的属性:
function myFunction() {
var x;
var txt = "";
var person = {fname: "Bill", lname: "Gates", age: 56};
for (x in person) {
txt = txt + person[x];
}
console.log(txt);
}
myFunction();
Object.keys 方法 (配合 forEach)
Object.keys()
方法会返回一个数组,该数组包含对象自身的(不考虑继承的属性)所有可枚举属性的键名。
Object.keys(obj).forEach(function(key) {
console.log(key + ': ' + obj[key]);
});
Object.values 方法 (仅遍历值)
Object.values()
方法返回一个包含对象自身的所有可枚举属性值的数组。
Object.values(obj).forEach(function(value) {
console.log(value);
});
Object.entries 方法 (键值对数组)
Object.entries()
方法返回一个给定对象自身可枚举属性的键值对数组,数组中键值对的顺序和使用for...in
循环是一致的(区别在于for...in
循环还会遍历原型链中的键值对)。
Object.entries(obj).forEach(function([key, value]) {
console.log(key + ': ' + value);
});
Object.getOwnPropertyNames() 方法
Object.getOwnPropertyNames()
方法返回一个数组,该数组包含对象自身的所有属性(无论是否可枚举)的键名,但不包括Symbol值作为名称的属性。
Object.getOwnPropertyNames(object).forEach(key => {
console.log(key, object[key]);
});
遍历 map:forEach、for...of、entries、keys()和values()
在 JavaScript 中,Map 是一种键值对的数据结构,它保持插入的顺序。推荐使用 for...of 或 forEach() 来遍历 Map 简洁且易于理解。虽然 for...in 是一种遍历对象属性的常见方式,但它不适用于 Map 对象,因为 Map 是一个可迭代对象而非普通的 JavaScript 对象。for...in 会遍历对象的可枚举属性,而 Map 本身没有可枚举的属性。所以不推荐使用 for...in 遍历 Map。
- forEach():适用于需要为每个键值对执行回调函数时。Map 的 forEach() 方法允许你为每个键值对执行一个回调函数。它的参数是一个回调函数,回调函数会接收三个参数:值、键和整个 Map 本身。
let myMap = new Map(); myMap.set('a', 1); myMap.set('b', 2); myMap.set('c', 3); // 使用 forEach 遍历 Map myMap.forEach(function(value, key) { console.log(key + " = " + value); });
- for...of:简洁直观,适用于遍历 Map 中的每个 [key, value] 对。Map 对象是可迭代的,所以可以使用 for...of 循环直接遍历它。for...of 循环会返回 [key, value] 的数组,每次迭代时提供一个键值对。
也可以单独获取 key 或 value,例如:let myMap = new Map(); myMap.set('a', 1); myMap.set('b', 2); myMap.set('c', 3); // 使用 for...of 循环遍历 Map for (let [key, value] of myMap) { console.log(key + " = " + value); }
// 获取 Map 中所有的 keys for (let key of myMap.keys()) { console.log(key); } // 获取 Map 中所有的 values for (let value of myMap.values()) { console.log(value); }
- entries():返回一个迭代器,适用于需要获取键值对数组时。Map.prototype.entries() 方法返回一个新的 Iterator 对象,它包含 Map 中每个 [key, value] 对的数组。可以通过 for...of 循环直接遍历这个迭代器。
let myMap = new Map(); myMap.set('a', 1); myMap.set('b', 2); myMap.set('c', 3); // 使用 entries() 获取键值对迭代器 for (let entry of myMap.entries()) { console.log(entry[0] + " = " + entry[1]); }
- Map.prototype.keys() 和 Map.prototype.values()。Map.prototype.keys() 返回一个包含 Map 中所有键的迭代器,而 Map.prototype.values() 返回一个包含所有值的迭代器。可以使用这些方法结合 for...of 来分别遍历 Map 中的键或值。
let myMap = new Map(); myMap.set('a', 1); myMap.set('b', 2); myMap.set('c', 3); // 遍历所有的键 for (let key of myMap.keys()) { console.log(key); } // 遍历所有的值 for (let value of myMap.values()) { console.log(value); }
JavaScript 的对象是可变的
对象是可变的,它们是通过引用来传递的。
以下实例的 person 对象不会创建副本:
var x = person; // 不会创建 person 的副本,是引用
如果修改 x ,person 的属性也会改变:
var person = {firstName: "John", lastName: "Doe", age: 50, eyeColor: "blue"}
var x = person;
x.age = 10; // x.age 和 person.age 都会改变
Number 对象
JavaScript 只有一种数字类型。可以使用也可以不使用小数点来书写数字。
JavaScript 数字
JavaScript 数字可以使用也可以不使用小数点来书写:
var pi=3.14; // 使用小数点
var x=34; // 不使用小数点
极大或极小的数字可通过科学(指数)计数法来写:
var y=123e5; // 12300000
var z=123e-5; // 0.00123
所有 JavaScript 数字均为 64 位
JavaScript 不是类型语言。与许多其他编程语言不同,JavaScript 不定义不同类型的数字,比如整数、短、长、浮点等等。
在JavaScript中,数字不分为整数类型和浮点型类型,所有的数字都是由 浮点型类型。JavaScript 采用 IEEE754 标准定义的 64 位浮点格式表示数字,它能表示最大值为 ±1.7976931348623157e+308,最小值为 ±5e-324。
值 (aka Fraction/Mantissa) | 指数 | Sign |
---|---|---|
52 bits (0 - 51) | 11 bits (50 - 62) | 1 bit (63) |
精度
整数(不使用小数点或指数计数法)最多为 15 位。
var x = 999999999999999; // x 为 999999999999999
var y = 9999999999999999; // y 为 10000000000000000
小数的最大位数是 17,但是浮点运算并不总是 100% 准确:
var x = 0.2 + 0.1; // 输出结果为 0.30000000000000004
八进制 和 十六进制
如果前缀为 0,则 JavaScript 会把数值常量解释为八进制数,如果前缀为 0 和 "x",则解释为十六进制数。
var y = 0377;
var z = 0xFF;
绝不要在数字前面写零,除非您需要进行八进制转换。
默认情况下,JavaScript 数字为十进制显示。但是你可以使用 toString() 方法 输出16进制、8进制、2进制。
var myNumber = 128;
myNumber.toString(16); // 返回 80
myNumber.toString(8); // 返回 200
myNumber.toString(2); // 返回 10000000
无穷大(Infinity)
当数字运算结果超过了JavaScript所能表示的数字上限(溢出),结果为一个特殊的无穷大(infinity)值,在JavaScript中以Infinity表示。同样地,当负数的值超过了JavaScript所能表示的负数范围,结果为负无穷大,在JavaScript中以-Infinity表示。无穷大值的行为特性和我们所期望的是一致的:基于它们的加、减、乘和除运算结果还是无穷大(当然还保留它们的正负号)。
myNumber = 2;
while (myNumber != Infinity) {
myNumber = myNumber * myNumber; // 重复计算直到 myNumber 等于 Infinity
}
除以 0 也产生了无限:
var x = 2/0;
var y = -2/0;
NaN - 非数字值
NaN 属性是代表非数字值的特殊值。该属性用于指示某个值不是数字。可以把 Number 对象设置为该值,来指示其不是数字值。
你可以使用 isNaN() 全局函数来判断一个值是否是 NaN 值。
var x = 1000 / "Apple";
isNaN(x); // 返回 true
var y = 100 / "1000";
isNaN(y); // 返回 false
除以 0 是无穷大,无穷大是一个数字:
var x = 1000 / 0;
isNaN(x); // 返回 false
数字 可以是 数字 或者 对象
数字可以私有数据进行初始化,就像 x = 123;
JavaScript 数字对象初始化数据, var y = new Number(123);
var x = 123;
var y = new Number(123);
typeof (x) // 返回 Number
typeof (y) // 返回 Object
示例:
var x = 123;
var y = new Number(123);
(x === y) // 为 false,因为 x 是一个数字,y 是一个对象
Number 属性
属性 | 描述 |
---|---|
Number.MAX_VALUE | 最大值 |
Number.MIN_VALUE | 最小值 |
Number.NaN | 非数字 |
Number.NEGATIVE_INFINITY | 负无穷,在溢出时返回 |
Number.POSITIVE_INFINITY | 正无穷,在溢出时返回 |
Number.EPSILON | 表示 1 和比最接近 1 且大于 1 的最小 Number 之间的差别 |
Number.MIN_SAFE_INTEGER | 最小安全整数。 |
Number.MAX_SAFE_INTEGER | 最大安全整数。 |
数字方法
方法 | 描述 |
---|---|
Number.parseFloat() | 将字符串转换成浮点数,和全局方法 parseFloat() 作用一致。 |
Number.parseInt() | 将字符串转换成整型数字,和全局方法 parseInt() 作用一致。 |
Number.isFinite() | 判断传递的参数是否为有限数字。 |
Number.isInteger() | 判断传递的参数是否为整数。 |
Number.isNaN() | 判断传递的参数是否为 isNaN()。 |
Number.isSafeInteger() | 判断传递的参数是否为安全整数。 |
数字类型原型上的一些方法
方法 | 描述 |
---|---|
toExponential() | 返回一个数字的指数形式的字符串,如:1.23e+2 |
toFixed() | 返回指定小数位数的表示形式。 var a=123; b=a.toFixed(2); // b="123.00" |
toPrecision() | 返回一个指定精度的数字。如下例子中,a=123 中,3会由于精度限制消失:var a=123; b=a.toPrecision(2); // b="1.2e+2" |
字符串(String) 对象
String 对象用于处理已有的字符块。
JavaScript 字符串
一个字符串用于存储一系列字符就像 "John Doe".
一个字符串可以使用单引号或双引号。
var carname = "Volvo XC60";
var carname = 'Volvo XC60';
你使用位置(索引)可以访问字符串中任何的字符:
var character = carname[7];
字符串的索引从零开始,所以字符串第一字符为 [0],第二个字符为 [1], 等等。
你可以在字符串中使用引号,如下实例:
var answer = "It's alright";
var answer = "He is called 'Johnny'";
var answer = 'He is called "Johnny"';
或者你可以在字符串中使用转义字符(\)使用引号:
var answer = 'It\'s alright';
var answer = "He is called \"Johnny\"";
字符串(String)
字符串(String)使用长度属性length来计算字符串的长度:
var txt = "Hello World!";
console.log(txt.length);
var txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
console.log(txt.length);
在字符串中查找字符串
字符串使用 indexOf() 来定位字符串中某一个指定的字符首次出现的位置:
var str = "Hello world, welcome to the universe.";
var n = str.indexOf("welcome");
如果没找到对应的字符函数返回 -1
lastIndexOf() 方法在字符串末尾开始查找字符串出现的位置。
内容匹配
match() 函数用来查找字符串中特定的字符,并且如果找到的话,则返回这个字符。
var str="Hello world!";
document.write(str.match("world") + "<br>");
document.write(str.match("World") + "<br>");
document.write(str.match("world!"));
替换内容
replace() 方法在字符串中用某些字符替换另一些字符。
str = "Please visit Microsoft!"
var n = str.replace("Microsoft", "Runoob");
字符串大小写转换
字符串大小写转换使用函数 toUpperCase() / toLowerCase():
var txt = "Hello World!"; // String
var txt1 = txt.toUpperCase(); // txt1 文本会转换为大写
var txt2 = txt.toLowerCase(); // txt2 文本会转换为小写
字符串转为数组
字符串使用split()函数转为数组:
txt = "a,b,c,d,e" // String
txt.split(","); // 使用逗号分隔
txt.split(" "); // 使用空格分隔
txt.split("|"); // 使用竖线分隔
特殊字符
Javascript 中可以使用反斜线(\)插入特殊符号,如:撇号,引号等其他特殊符号。
查看如下 JavaScript 代码:
var txt="We are the so-called "Vikings" from the north.";
document.write(txt);
在JavaScript中,字符串的开始和停止使用单引号或双引号。这意味着,上面的字符串将被切成: We are the so-called
解决以上的问题可以使用反斜线来转义引号:
var txt="We are the so-called \"Vikings\" from the north.";
document.write(txt);
JavaScript将输出正确的文本字符串:We are the so-called "Vikings" from the north.
下表列出其他特殊字符,可以使用反斜线转义特殊字符:
代码 | 输出 |
---|---|
\' | 单引号 |
\" | 双引号 |
\\ | 斜杆 |
\n | 换行 |
\r | 回车 |
\t | tab |
\b | 空格 |
\f | 换页 |
字符串 属性 和 方法
属性:
- length
- prototype
- constructor
方法:
- charAt()
- charCodeAt()
- concat()
- fromCharCode()
- indexOf()
- lastIndexOf()
- match()
- replace()
- search()
- slice()
- split()
- substr()
- substring()
- toLowerCase()
- toUpperCase()
- valueOf()
更多方法与属性介绍可以参考:JavaScript String 对象
Date(日期) 对象
日期对象用于处理日期和时间。
在线实例
- 如何使用 Date() 方法获得当日的日期。
- getFullYear() 使用 getFullYear() 获取年份。
- getTime() getTime() 返回从 1970 年 1 月 1 日至今的毫秒数。
- setFullYear() 如何使用 setFullYear() 设置具体的日期。
- toUTCString() 如何使用 toUTCString() 将当日的日期(根据 UTC)转换为字符串。
- getDay() 如何使用 getDay() 和数组来显示星期,而不仅仅是数字。
- Display a clock 如何在网页上显示一个钟表。
完整的 Date 对象参考手册
我们提供 JavaScript Date 对象参考手册,其中包括所有可用于日期对象的属性和方法。JavaScript Date 对象参考手册。
该手册包含了对每个属性和方法的详细描述以及相关实例。
创建日期
Date 对象用于处理日期和时间。
可以通过 new 关键词来定义 Date 对象。以下代码定义了名为 myDate 的 Date 对象:
有四种方式初始化日期:
new Date();
new Date(value);
new Date(dateString);
new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);
上面的参数大多数都是可选的,在不指定的情况下,默认参数是0。
实例化一个日期的一些例子:
var today = new Date()
var d1 = new Date("October 13, 1975 11:13:00")
var d2 = new Date(79, 5, 24)
var d3 = new Date(79, 5, 24, 11, 33, 0)
设置日期
通过使用针对日期对象的方法,我们可以很容易地对日期进行操作。
在下面的例子中,我们为日期对象设置了一个特定的日期 (2010 年 1 月 14 日):
var myDate = new Date();
myDate.setFullYear(2010, 0, 14);
在下面的例子中,我们将日期对象设置为 5 天后的日期:
var myDate = new Date();
myDate.setDate(myDate.getDate() + 5);
注意: 如果增加天数会改变月份或者年份,那么日期对象会自动完成这种转换。
两个日期比较
日期对象也可用于比较两个日期。
下面的代码将当前日期与 2100 年 1 月 14 日做了比较:
var x = new Date();
x.setFullYear(2100, 0, 14);
var today = new Date();
if (x > today) {
alert("今天是2100年1月14日之前");
} else {
alert("今天是2100年1月14日之后");
}
笔记
如何把日期格式化为指定格式?( 尝试一下 )
Date.prototype.format = function (fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(
RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
document.getElementById("demo1").innerHTML = new Date(79, 5, 24, 11, 33, 0).format("MM月dd日");
var now = new Date();
var nowStr = now.format("yyyy-MM-dd hh:mm:ss");
document.getElementById("demo2").innerHTML = new Date().format("yyyy年MM月dd日");
var nowStr = now.format("yyyy-MM-dd hh:mm:ss");
document.getElementById("demo3").innerHTML = new Date().format("yyyy年MM月dd日hh小时mm分ss秒");
其他格式实例:
alert(new Date().format("yyyy年MM月dd日"));
alert(new Date().format("MM/dd/yyyy"));
alert(new Date().format("yyyyMMdd"));
alert(new Date().format("yyyy-MM-dd hh:mm:ss"));
上面是区分了大小写,调用的时候只能按照规定好的字母格式,下面是不会区分大小写,从而更加灵活。
Date.prototype.format = function (fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
// 获取年份
// ①
if (/(y+)/i.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
// ②
if (new RegExp("(" + k + ")", "i").test(fmt)) {
fmt = fmt.replace(
RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
var now = new Date();
var nowStr = now.format("YYYY-MM-DD"); // 2021-01-11
类似 Python 中字典
在 JavaScript 中,对象(Object)的功能与 Python 中的字典(dict)有一些相似之处。以下是一些常见的操作方式:
// 方式一
let obj = {};
// 方式二
let obj2 = new Object();
obj['key1'] = 'value1';
obj.key2 = 'value2'; // 也可以直接使用点语法添加键值对
let k = obj.key1;
let v = obj['key1'];
console.log(`[k:v] ---> ${k}:{v}`)
遍历对象:使用 for...in
let obj = { key1: 'value1', key2: 'value2' };
for (let key in obj) {
console.log(key + ': ' + obj[key]);
}
遍历对象::使用 Object.keys()、Object.values() 和 Object.entries()
let obj = { key1: 'value1', key2: 'value2' };
let keys = Object.keys(obj);
let values = Object.values(obj);
let entries = Object.entries(obj);
keys.forEach(key => console.log(key));
values.forEach(value => console.log(value));
entries.forEach(entry => console.log(entry[0] + ': ' + entry[1]));
检查键是否存在(类似字典判断键是否存在)
let obj = { key: 'value' };
if ('key' in obj) {
console.log('键存在');
} else {
console.log('键不存在');
}
删除键值对(类似字典删除元素)
let obj = { key: 'value' };
delete obj.key;
Array(数组) 对象
数组对象参考手册:https://www.runoob.com/js/jsref-obj-array.html
有三种方法创建一个数组。
// 方法 1:常规方式
var myCars = new Array();
myCars[0] = "Saab";
myCars[1] = "Volvo";
myCars[2] = "BMW";
// 方法 2:简洁方式
var myCars = new Array("Saab", "Volvo", "BMW");
// 方法 3:字面方式
// JavaScript一切皆是对象。数组元素是对象。函数是对象。
// 所以可以在数组中有不同的 变量类型。
let arr = [1, "two", true, { name: "obj" }, [3, 4]];
var x = myCars.length // myCars 中元素的数量
var y = myCars.indexOf("Volvo") // "Volvo" 值的索引值
[0] 是数组的第一个元素。[1] 是数组的第二个元素。通过指定数组名以及索引号码,可以访问某个特定的元素。示例:修改数组 myCars 的第一个元素 myCars[0]="Opel";
遍历 数组
// 方法 1:for 循环
let arr = [10, 20, 30, 40];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// 方法 2:forEach 循环。数组的内置方法,接收一个回调函数作为参数。
let arr = [1, 2, 3, 4, 5];
arr.forEach(function(item) {
console.log(item);
});
let arr = [1, 2, 3, 4, 5];
arr.forEach(item => console.log(item));
// 方法 3:for...of 循环。ES6 引入的新循环方式,简洁易用。
for (let value of arr) {
console.log(value);
}
// 方法 4:map 方法 (通常用于创建新数组)
// 对原数组中的每个元素调用一个提供的函数后的返回值
let arr = [1, 2, 3, 4, 5];
let newArray = arr.map(function(item) {
console.log(item);
return item * 2;
});
console.log(newArray);
// 方法 5:while 循环和数组的索引
let arr = [1, 2, 3, 4, 5];
let index = 0;
while (index < arr.length) {
console.log(arr[index]);
index++;
}
数组 动态添加 新方法
原型是JavaScript全局构造函数。它可以构建新Javascript对象的属性和方法。
实例:创建一个新的方法,用于将数组小写字符转为大写字符( 尝试一下)
Array.prototype.myUcase = function () {
for (i = 0; i < this.length; i++) {
this[i] = this[i].toUpperCase();
}
}
更多实例
- 合并两个数组 - concat()
- 合并三个数组 - concat()
- 用数组的元素组成字符串 - join()
- 删除数组的最后一个元素 - pop()
- 数组的末尾添加新的元素 - push()
- 将一个数组中的元素的顺序反转排序 - reverse()
- 删除数组的第一个元素 - shift()
- 从一个数组中选择元素 - slice()
- 数组排序(按字母顺序升序)- sort()
- 数字排序(按数字顺序升序)- sort()
- 数字排序(按数字顺序降序)- sort()
- 在数组的第2位置添加一个元素 - splice()
- 转换数组到字符串 -toString()
- 在数组的开头添加新元素 - unshift()
Boolean(布尔) 对象
Boolean(布尔)对象用于将非布尔值转换为布尔值(true 或者 false)。
检查布尔值
检查布尔对象是 true 还是 false。
完整的 Boolean(布尔) 对象参考手册
我们提供 JavaScript Boolean 对象参考手册,其中包括所有可用于布尔对象的属性和方法。
该手册包含了对每个属性和方法的详细描述以及相关实例。
创建 Boolean 对象
Boolean 对象代表两个值:"true" 或者 "false"
下面的代码定义了一个名为 myBoolean 的布尔对象:
var myBoolean = new Boolean();
如果布尔对象无初始值或者其值为:
- 0
- -0
- null
- ""
- false
- undefined
- NaN
那么对象的值为 false。否则,其值为 true(即使当变量值为字符串 "false" 时)!
Math(算数) 对象
Math(算数)对象的作用是:执行常见的算数任务。
在线实例
- round() 如何使用 round()。
- random() 如何使用 random() 来返回 0 到 1 之间的随机数。
- max() 如何使用 max() 来返回两个给定的数中的较大的数。(在 ECMASCript v3 之前,该方法只有两个参数。)
- min() 如何使用 min() 来返回两个给定的数中的较小的数。(在 ECMASCript v3 之前,该方法只有两个参数。)
完整的 Math 对象参考手册
我们提供 JavaScript Math 对象的参考手册,其中包括所有可用于算术对象的属性和方法。
该手册包含了对每个属性和方法的详细描述以及相关实例。
Math 对象
Math(算数)对象的作用是:执行普通的算数任务。
Math 对象提供多种算数值类型和函数。无需在使用这个对象之前对它进行定义。
使用 Math 的属性/方法的语法。实例:
var x = Math.PI;
var y = Math.sqrt(16);
注意: Math对象无需在使用这个对象之前对它进行定义。
算数值
JavaScript 提供 8 种可被 Math 对象访问的算数值:
你可以参考如下 Javascript 常量使用方法。实例:
- Math.E
- Math.PI
- Math.SQRT2
- Math.SQRT1_2
- Math.LN2
- Math.LN10
- Math.LOG2E
- Math.LOG10E
算数方法
除了可被 Math 对象访问的算数值以外,还有几个函数(方法)可以使用。
使用 Math 对象的 round 方法对一个数进行四舍五入。document.write(Math.round(4.7)); //结果:5
使用 Math 对象的 random() 方法来返回一个介于 0 和 1 之间的随机数:document.write(Math.random()); // 结果:0.3162989817471187
使用 Math 对象的 floor() 方法和 random() 来返回一个介于 0 和 11 之间的随机数:document.write(Math.floor(Math.random()*11)); // 结果:9
RegExp 对象
RegExp:是正则表达式(regular expression)的简写。
完整 RegExp 对象参考手册
请查看我们的 JavaScript RegExp 对象的参考手册,其中提供了可以与字符串对象一同使用的所有的属性和方法。
这个手册包含的关于每个属性和方法的用法的详细描述和实例。
什么是 RegExp?
正则表达式描述了字符的模式对象。
当您检索某个文本时,可以使用一种模式来描述要检索的内容。RegExp 就是这种模式。
简单的模式可以是一个单独的字符。
更复杂的模式包括了更多的字符,并可用于解析、格式检查、替换等等。
您可以规定字符串中的检索位置,以及要检索的字符类型,等等。
语法:var patt=new RegExp(pattern, modifiers);
或更简单的方法 var patt=/pattern/modifiers;
- 模式描述了一个表达式模型。
- 修饰符(modifiers)描述了检索是否是全局,区分大小写等。
注意:当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 \)。比如,以下是等价的:
var re = new RegExp("\\w+");
var re = /\w+/;
RegExp 修饰符
修饰符用于执行不区分大小写和全文的搜索。
- i - 修饰符是用来执行不区分大小写的匹配。
- g - 修饰符是用于执行全文的搜索(而不是在找到第一个就停止查找,而是找到所有的匹配)。
实例 1:在字符串中不区分大小写找"runoob" ( 尝试一下 )
var str = "Visit RUnoob"; var patt1 = /runoob/i;
// 以下标记的文本是获得的匹配的表达式:Visit RUnoob
实例 2:全文查找 "is" ( 尝试一下 )
var str="Is this all there is?"; var patt1=/is/g;
// 以下标记的文本是获得的匹配的表达式:Is this all there is?
实例 3:全文查找和不区分大小写搜索 "is" ( 尝试一下 )
var str="Is this all there is?"; var patt1=/is/gi;
// 以下 标记的文本是获得的匹配的表达式:Is this all there is?
test()
test() 方法搜索字符串指定的值,根据结果并返回真或假。
下面的示例是从字符串中搜索字符 "e" 。实例:( 尝试一下 )
var patt1=new RegExp("e"); document.write(patt1.test("The best things in life are free"));
// 由于该字符串中存在字母 "e",以上代码的输出将是:true
当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 \)。实例:( 尝试一下 )
var re = new RegExp("\\w+");
exec()
exec() 方法检索字符串中的指定值。返回值是被找到的值。如果没有发现匹配,则返回 null。
下面的示例是从字符串中搜索字符 "e" 。实例 1:( 尝试一下 )
var patt1=new RegExp("e"); document.write(patt1.exec("The best things in life are free"));
// 由于该字符串中存在字母 "e",以上代码的输出将是:e