JavaScript 的基本数据类型包括 Undefined
、Null
、Boolean
、String
、Number
和 Object
,以及 ES6 新增的 Symbol
类型。
对象和其他基本类型值不同的是,对象是一种复合值:它可以将多个原始值或者其他对象聚合在一起,可通过键名访问这些值。
对象也可看作是属性的无序集合,每个属性都是一个键值对。属性名是 String
类型或 Symbol
类型,因此我们可以把对象看成是从字符串到值的映射。
创建对象的方法:
JavaScript 提供了叫做字面量的快捷方式,用于创建大多数原生对象值。使用字面量只是隐藏了与使用 new
操作符相同的基本过程,于是也可以叫做语法糖。
对象字面量是由若干键值对组成的映射表,键值对中间用冒号分隔,整个映射表用花括号括起来。
不同属性之间用逗号分隔,属性名可以是任意 String
类型或 Symbol
类型值,属性值可以是任意类型表达式,表达式的值是属性值。
const uzi = {name : 'uzi',age : 22,5 : true}
对象键名字符化:使用对象字面量的方法来定义对象,属性名会自动转换成字符串。
const uzi = {'name' : 'uzi','age' : 22,'5' : true,}
使用 new
操作符调用 Object 构造函数来初始化一个新创建的对象。new 实现过程
let uzi = new Object();uzi.name = 'Uzi';uzi.age = 22;
如果该参数是一个对象,则直接返回这个对象。
参数为对象:
let foo = { a: 1 }let bar = new Object(foo)console.log(foo === bar)// true
参数为函数(对象):
let foo = function(){}let bar = new Object(foo)console.log(foo === bar)// true
如果参数是一个原始类型的值,则返回该值对应的包装对象。
console.log(new Object('foo'))// String {0: "f", 1: "o", 2: "o", length: 3, [[PrimitiveValue]]: "foo"}console.log(new Object(1))// Number {[[PrimitiveValue]]: 1}console.log(new Object(true))// Boolean {[[PrimitiveValue]]: true}
Object.create() 方法用于创建指定对象为原型对象的新对象。
📖 语法
Object.create(proto, properties)
参数 | 说明 | 类型 |
---|---|---|
proto | 新创建对象指向的原型对象 | object |
properties | 可选参数。添加到新创建对象的可枚举属性(即自身定义的属性,而不是原型链上的枚举属性 | object |
const object = Object.create({ x:1, y:1 })// object 继承了属性 x 和 yconsole.log(object.x);// 1
可以通过传入参数 null
来创建一个没有原型的新对象,但通过这种方式创建的对象不会继承任何东西,甚至不包括基础方法,比如 toString
和 valueOf
。
继承对象:
const foo = {}console.log(Number(foo));// NaN
不继承任何属性和方法:
const bar = Object.create(null);// bar 不继承任何属性和方法console.log(Number(bar));// Uncaught TypeError: Cannot convert object to primitive value
如果想创建一个普通的空对象(比如通过 {}
或 new Object()
创建的对象),需要传入 Object.prototype
。
// Example1const foo = {};console.log(Number(foo))// NaN// Example2const bar = Object.create(Object.prototype);// bar 和 {} 和 new Object()一样console.log( Number(bar) );// NaN
Object.create()
方法的第二个参数是属性描述符。
const obj = Object.create({ z:3 }, {x:{value:1,writable: false,enumerable:true,configurable:true},y:{value:2,writable: false,enumerable:true,configurable:true}})console.log(obj.x, obj.y, obj.z);// 1 2 3
对象是属性的无序集合,由 键名 和 属性值 组成。
对象的所有键名都是字符串,所以加不加引号都可以,如果不是字符串也会自动转换成字符串。
const foo = { name: 'bar', 123: 'car'}
属性值可以是任何类型的表达式,最终表达式的结果就是属性值的结果。
如果属性值为函数,则通常把这个属性称为"方法"。
const foo = {run: function (x) {return 2 * x;}}foo.run(1);// 2
由于对象的方法就是函数,因此也有 name
属性。方法的 name
属性返回紧跟在 function
关键字后面的函数名。如果是匿名函数,ES5 环境会返回 undefined
,ES6 环境会返回方法名。
const foo = {mth1: function f() {},mth2: function () {}}foo.mth1.name;// "f"foo.mth2.name;// ES5: undefinedfoo.mth2.name;// ES6: "m2"
如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。
let foo = {};let bar = foo;foo.a = 1;console.log(bar.a);// 1bar.b = 2;console.log(foo.b);// 2
如果取消某一个变量对于原对象的引用,不会影响到另一个变量。
let foo = {};let bar = foo;foo = 1;console.log(bar);// {}