简单创建:
// 构造函数体内的"this"将指向 实例对象
function Box(x, y){
this.x = x;
this.y = y;
};
var box1 = new Box(4, 5); // {x:4,y:5}
// 使用JS内置构造函数创建对应对象,如Object/Array/Function/RegExp/String
var obj = new Object();
// 创建空对象的语法糖
var obj1 = {}
添加/删除:
// 已有一个对象: person = { name: 'zhangsan' }
// 通过.操作符为对象添加属性
person.age = 20; // { name: 'zhangsan', age: 20 }
// 通过[]操作符为对象添加属性
person["weight"] = 100; // { name: 'zhangsan', age: 20, weight: 100 }
// 向原型对象添加属性
person.__proto__.test = 110; // 打印person仍为{ name: 'zhangsan', age: 20, weight: 100 },但打印person.test为110
// 原型中添加属性,所有继承自该原型均获得指定属性
Object.prototype.test2 = 220;
// 删除属性,注意:delete不能删除继承属性
delete person.weight;
delete person["age"];
检测属性:
检测包含原型继承的属性: ... in obj
let obj = {x: 1, y: 2};
Object.prototype.x = 100;
console.log("x" in obj); // true
console.log("z" in obj); // true 能检测从原型继承的属性
console.log("h" in obj); // false
检测私有属性: .hasOwnProperty('prop')
let obj = {x: 1};
obj.y = {a: 22}; // 添加属性 y
Object.prototype.z = 100; // 原型继承属性 z
console.log(obj.hasOwnProperty('x')); // true
console.log(obj.hasOwnProperty('y')); // true 后期添加的属性为私有属性
console.log(obj.hasOwnProperty('z')); // false
console.log(obj.hasOwnProperty('a')); // false "孙"属性不属于私有属性
获取Key:
获取私有属性的"key"值: Object.keys()
let obj = {x: 1, y: 2};
Objcet.prototype.z = 3;
// 返回私有"key"数组
console.log(Object.keys(obj)); // ["x", "y"]
获取包含原型继承属性的"key"值: for-in循环
let obj = {x: 1, y: 2};
Objcet.prototype.z = 3;
let output = [];
for(let i in obj) {
output.push(i);
}
console.log(output); // ["x", "y", "z"]
关于"typeof"和"instanceof":
typeof 和 instanceof 常用来判断一个变量是否为空,或者是什么类型的。
区别的:
typeof 返回值是一个字符串,一般只能返回这几个结果:number,boolean,string,function,object,undefined。但对于 Array,Null 等特殊对象使用 typeof 一律返回 object 。
let obj = {};
console.log(typeof obj); // 'object' 注意是小写开头
instanceof 用于判断一个变量是否某个对象的实例,返回布尔值。
let obj = {};
console.log(obj instanceof Objcet); // true
最常见的用途:
若"a"变量未声明,if(a)会报错。正确做法是:
if (typeof a != 'undefined') { ... }
对象为"引用类型"数据:
let obj1 = {x: 1, y: 2};
let obj2 = obj1; // obj2只是指向了obj1,数据只有一份
// 当修改其中一个,其他的"引用"均发生变化。添加/删除属性的操作同理
obj1.x = 100;
obj2.y = 200;
console.log(obj1, obj2); // {x: 100, y: 200} {x: 100, y: 200}
// 数组也是"引用类型"
let arr = [1, 2, 3];
let arr2 = arr;
arr[0] = 100;
console.log(arr2); // [ 100, 2, 3 ]
克隆:
(有缺陷的)深拷贝1: newObj = JSON.parse(JSON.stringify(obj))
let obj = {x: 1, y: {a: 2, b: 3}};
let obj1 = JSON.parse(JSON.stringify(obj));
obj.y.a = 200;
console.log(obj1); // {x: 1, y: {a: 2, b: 3}} 验证obj1不是引用obj
// 缺点是无法拷贝对象里的function及原型链里的属性
obj.z = function () {};
obj2 = JSON.parse(JSON.stringify(obj));
console.log(obj2); // {x: 1, y: {a: 200, b: 3}} // 会忽略函数类型
浅拷贝: Object.assign(target, ...sources)
var obj = { a: 1 };
var copy = Object.assign({}, obj);
obj.a = 2;
console.log(copy); // { a: 1 }
// 假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值。
obj.b = { x: 11 };
var copy2 = Object.assign({}, obj);
obj.b.x = 22;
console.log(copy2); // { a: 1, b: { x: 22 } }
深拷贝1: (自定义函数)
function deepCopy( source ) {
let target = Array.isArray( source ) ? [] : {}
for ( var k in source ) {
if ( typeof source[ k ] === 'object' ) {
target[ k ] = deepCopy( source[ k ] )
} else {
target[ k ] = source[ k ]
}
}
return target
}
// 测试
var objO = { a: {x: "hello", y: 21} };
let objN = deepCopy(objO);
objO.a.x = "bye";
console.log(objN); // { a: {x: "hello", y: 21} }
深拷贝2: lodash库的 .cloneDeep 函数
var lodash = require('lodash');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = lodash.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f); // false
其他: