所有对象都有哪些?
js 里一切皆是对象,在赋值对象时,大家都知道直接赋值是赋值的对象的地址,而为了获得一个属性相同的另一个对象,就有了克隆这一说。
简单的克隆, 类似于 string、number、boolean 简单基本类型可以直接进行赋值。
对于对象中一些特殊的内置对象, 如 Date、Function 、RegExp 则需判断返回相应的新对象。
方法代码如下:
function deepClone (obj) {
if (typeof obj !== 'object') {
return obj;
}
if (!obj) { // obj 是 null的情况
return obj;
}
if (obj instanceof Date) {
return new Date(obj);
}
if (obj instanceof RegExp) {
return new RegExp(obj);
}
if (obj instanceof Function) {
return obj;
}
let newObj;
if (obj instanceof Array) {
newObj = [];
for(let i = 0, len = obj.length; i < len; i++){
newObj.push(deepClone(obj[i]));
}
return newObj;
}
newObj = {};
for(let key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] !== 'object') {
newObj[key] = obj[key];
} else {
newObj[key] = deepClone(obj[key]);
}
}
}
return newObj;
}
挖掘
关于判断对象类型
方式一:
ES2015 Update: the name of class Foo {} is Foo.name. The name of thing’s class, regardless of thing’s type, is thing.constructor.name. Builtin constructors in an ES2015 environment have the correct name property; for instance (2).constructor.name is “Number”.
大致翻译即是: 获取 class foo{} 的 name 就是 foo.name。 那么对象的类, 或者说对象的类型,就是它 constructor.name 值。ES2015环境中的内置构造函数具有正确的名称属性,比如 2 的构造类就是 Number。
也就是说现在我们可以通过.constrctor.name 属性拿到拿到对象的构造类名了。
方式二:
typeof
它对所有基本类型都能判断出来,唯一不足是不能判断出 Object 类对象具体属于什么类。
方式三:
也就是我用到的 instanceof
,但是它只支持判断 Object,不支持基本类型。
方式四:
Object.prototype.toString
再挖掘
想想这里的 prototype 是什么?
首先我们要有一个‘类函数’
function Person() {
//.......
}
let man = new Person();
Person.prototype 就是 Person的原型。它具体表现为
而这里通过 new 新建的man对象,在创建时就会把 man[[Prototype]]链接到 Person的原型,Object.getPrototypeOf(man) 指向的原型就是 Person 的原型。
而 Person 的它是通过 function 创建的,它在创建的时候也被指定了 Object 的原型。
通过一系列在对象原型上含内置原型形成的链就叫原型链。
当我们在一个对象上查找属性时,就会按照原型链一条一条的去匹配属性。使用 for…in 遍历对象是原理就和查找原型类似,任何可以通过原型链访问到的属性都会被枚举。
Prototype 是对象的内置属性,其实就是对于其他对象的引用。
几乎所有的对象在创建时[[Prototype]] 属性都会被赋予一个非空的值。
原型链的尽头就是 Object 原型