Object对象方法总结

Object对象方法总结

主要是Object对象上的方法,以及其创建的实例上方法。 通常可以用在不同实例对象上的方法。

Object方法

Object.assign(targetObj,copyObg)

将一个对象上的方法拷贝到另一个对象上

function Fruit(name) { 
    this.name = name;
}
Fruit.prototype.sayName = function () { 
    console.log(this.name);
}
var Apple = {
    color:"red"
}
var ft = new Fruit("apple");
Object.assign(Apple,ft);  // 将ft对象上的属性和方法复制到Apple上
console.log(Apple);

Object.keys()

获取对象所有(可枚举)属性名的数组,对象原型上的属性不能获取。

function Plant(){
    this.desc = "植物类"
}
Plant.prototype.sayHi = function () { 
    console.log("hi");
}
function Apple() { 
    this.desc = "我是一个大苹果";
    Plant.call(this);
}
Apple.prototype = Object.create(Plant.prototype);
Apple.prototype.constructor = Apple;

// 使用Object.keys()
var bigApple = new Apple();
console.log(bigApple);  // Apple{desc: "植物类"}
console.log(Object.keys(bigApple));  // ["desc"]

Object.getOwnPropertyNames()

获取对象本身的属性,不包括对象原型上的属性
console.log(Object.getOwnPropertyNames(bigApple)); // ["desc"]

Object.getPrototypeOf()

获取对象的原型

function Plant(){
    this.desc = "植物类"
}
var obj = new Plant();
console.log(obj.__proto__ === Object.getPrototypeOf(obj)); // true
console.log(Plant.prototype === Object.getPrototypeOf(obj))// true

等价于实例的__proto__属性

Object.setPrototypeOf()

设置对象的原型

// 创建两个对象
var obj1 = {
    name:"obj1"
};
var obj2 = {
    age:18
}
Object.setPrototypeOf(obj1,obj2);
console.log(Object.getPrototypeOf(obj1) === obj2);  // true

将obj1对象的原型设置为obj2

new原理

new一个对象的原理其实是:
1.创建一个空对象obj
2.将该对象原型设置为Plant.prototype
3.使用构造函数Plant初始化对象。(调用构造函数修改this指向为obj对象即可)

function Plant(){
    this.desc = "植物类"
}
// var plt = new Plant;
var obj = {};
Object.setPrototypeOf(obj,Plant.prototype);
Plant.call(obj);
console.log(obj.desc);  // 植物类
console.log(obj instanceof Plant);  // true

Object.create()

传入一个对象,以这个对象为原型创建一个新对象

var obj1 = {
    name:"obj1"
};
var obj2 = Object.create(obj1);
// getPrototypeOf查看原型对象
console.log(Object.getPrototypeOf(obj2) === obj1);  // true

Object实例方法

对象实例上的方法

valueOf()

只有在计算式中,对象调用这个方法,将对象转换成值

var obj1 = {
    name:"obj1"
};
console.log(obj1.valueOf());  // {name: "obj1"}  
obj1.valueOf = function () { 
    return 3;
}
console.log(obj1+2);   // 5

toString()和toLocaleString()

返回一个对象的字符串形式,默认返回类型字符串

var obj1 = {
    name:"obj1"
};
function fn() {  };
var date = new Date();
console.log(obj1.toString());  // [object Object]  对象-》对象类型
console.log(String("33").toString());  // 33  字符串=》字符串本身
console.log(Number(128).toString());  // 128  数字=》值
console.log([1,3,5].toString());  // 1,3,5    数组=》使用,连接每个数组每个元素,相当于调用join(",")
console.log(fn.toString());  //  function fn() {  }  函数=》函数内容
console.log(date.toString());  // Sat May 09 2020 19:09:55 GMT+0800 (中国标准时间)  时间=》时间戳

对于不同类型的对象,返回不同的值

toLocaleString

使用本地的习惯定义返回值。通常对时间、数组、数字定制了该方法

// toLocalString
console.log(Number(128).toLocaleString());  // 128  
console.log([1,3,5].toLocaleString());  // 1,3,5   
console.log(date.toLocaleString());  // 2020/5/9 下午7:13:24  时间=》时间戳   使用当地习惯的时间表示方法

isPrototypeof()

判断a是否是b的原型

var obj1 = {
    name:"obj1"
};
var obj2 = {
    age:18
}
Object.setPrototypeOf(obj1,obj2);  // 设置obj1的原型是obj2
console.log(obj2.isPrototypeOf(obj1));  // true
console.log(Object.prototype.isPrototypeOf(obj1));  // true  Object.prototype是obj1的原型

其实,根据原型链解释,Object.prototype是所有对象的原型对象。

hasOwnProperty()

判断该实例是否有自己的属性

var obj1 = {
    name:"obj1"
};
var obj2 = {
    age:18
}
Object.setPrototypeOf(obj1,obj2);  // 设置obj1的原型是obj2
console.log(obj1.hasOwnProperty("name"));  // true
console.log(obj1.hasOwnProperty("age"));  // false

这个方法是用来判断一个属性是否是该对象自己的方法,而不是继承过来的方法。

属性对象描述符

属性对象描述符,通常是用来控制对象的一个属性是否可以修改、删除、枚举等操作。

Object.getOwnPropertyDescriptor()

获取对象上的一个属性的属性描述符
参数一为一个对象,参数二为对象上的一个属性

var obj1 = {
    name:"haha"
}
// 查看obj1对象的name属性的属性描述符
console.log(Object.getOwnPropertyDescriptor(obj1,"name"));
//结果{value: "haha", writable: true, enumerable: true, configurable: true}
console.log(obj1.propertyIsEnumerable("name"));  // true

Object.getOwnPropertyNames()

获取可枚举属性和不可遍历的属性

var obj1 = {
    name:"haha"
}
Object.defineProperty(obj1,"age",{
    value:18,
    writable:false,
    enumerable:true
})
console.log(Object.getOwnPropertyNames(obj1));  // ["name", "age"]

propertyIsEnumerable()

判断对象是否可枚举,只能判断对象本身的属性,不可枚举的属性或者继承的属性一律返回false
具体可设置的属性如下

属性名作用
value“haha”对象的值
writabletrue设置该属性是否可写
enumerabletrue设置该属性是否可枚举(例如:for in遍历对象时,遍历到这个属性)
configurabletrue是否可配置,对象能否删除
setundefined设置对象属性时调用,例如:obj.name=123
getundefined获取对象属性时调用,例如:obj.name

注意

  1. writable:原型对象上age属性的writable为false时,实例对象不可自定义该属性;但是通过对子对象定制foo描述符,覆盖原型上的foo对象描述符
  2. enumrable:表示可枚举,就是这个属性能否被遍历到。
  3. configurable:为true时,属性可以被删除;为false时,value、writable、enumerable都不能被修改;writable只能从true改为false,从false改为true时会失败。
  4. value:只要writable和configurable有一个为true,就允许被修改

defineProperty()

定义对象上属性的属性描述符
参数为对象,参数二为属性,参数三为对象描述符

var obj1 = {
    name:"haha"
}
Object.defineProperty(obj1,"age",{
    value:18,
    writable:false,
    enumerable:true
})
console.log(Object.getOwnPropertyDescriptor(obj1,"age"));
//结果:{value: 18, writable: false, enumerable: true, configurable: false}

对于没有定义的属性描述符,默认为false

defineProperties()

定义多个对象属性的属性描述符
参数一为对象,参数二为键值对列表(键为属性名,值为属性描述符)

var obj1 = {
    name:"haha"
}
Object.defineProperties(obj1,{
    p1:{
        value:"hello",
        writable:true
    },
    p2:{
        get:function () { 
            return this.name + " is sb"
        },
        set:function(newVal){
            console.log("set");
            this.name = newVal
        }
    }
})
console.log(Object.getOwnPropertyDescriptor(obj1,"p1"));  
// {value: "hello", writable: true, enumerable: false, configurable: false}
console.log(Object.getOwnPropertyDescriptor(obj1,"p2"));
// {enumerable: false, configurable: false, get: ƒ, set: ƒ}
console.log(obj1.p2);  // haha is sb
obj1.p2 = "apple";  // set

总结

  1. value和get方法只能定制一个
  2. 一旦设置get,不能使用writable属性
  3. 设置空属性描述对象时,默认所有属性全为false

案例:使用Object方法实现对象的深拷贝

浅拷贝和深拷贝简介

js有基本数据类型和引用数据类型

深拷贝

基本数据类型使用等号,直接复制对象

let a = 22;
let b = a;
b = 4;
console.log(a);  // 22
console.log(b);  // 4

b复制了a的值之后,与原对象a就没有任何关系。b的值修改,a的值也不会变。

浅拷贝

如果是引用类型(对象、数组),直接复制,变量获得的是对象的内存地址,而不是对象的值

// 案例一
let arr1 = [1,4,5];
let arr2 = arr1;
arr2.push(66);
console.log(arr1);  // [1, 4, 5, 66]
console.log(arr2);  // [1, 4, 5, 66]
// 案例二
let obj1 = {
    name:"apple",
    age:12
};
let obj2 = obj1;
obj2.name = "banana";
console.log(obj1);  // {name: "banana", age: 12}
console.log(obj2);  // {name: "banana", age: 12}

实现方法

对对象的属性依次遍历,判断是否是一个对象,是则递归遍历;不是,则复制到新对象上。

function deepCopy(oldObj,newObj) { //oldObj:被复制的对象  newObj:新对象,复制到这个对象中
    for(key in oldObj){
        // hasOwnProperty判断这个属性是否是自己的属性,而不是继承过来的
        if(oldObj.hasOwnProperty(key)){
            if(oldObj[key] && typeof oldObj[key] === "object"){
                // 判断是数组还是对象
                newObj[key] = oldObj[key].constructor === Array?[]:{};
                // 继续递归,将数组/对象中的值赋值到新对象中
                deepCopy(oldObj[key],newObj[key]);

            }else{  // 如果是一个属性,则直接复制到新对象
                newObj[key] = oldObj[key];
            }
        }

    }
    return newObj
}
var obj1 = {
    name:"apple",
    color:['blue','green'],
    prop:{
        num:12
    }
};
var obj2 = deepCopy(obj1,{});
console.log(obj1);  // {name: "apple", color: Array(2), prop: {…}}
console.log(obj2);  // {name: "apple", color: Array(2), prop: {…}}
obj2.name = "banana";
obj2.color.pop();
console.log(obj1);  // {name: "apple", color: Array(2), prop: {…}}
console.log(obj2);  // {name: "banana", color: Array(1), prop: {…}}
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页