js Object方法大全(自己整理)

Object 靜態(tài)方法總結(jié)

create 創(chuàng)建一個(gè)對(duì)象

const obj = Object.create({a:1}, {b: {value: 2}})

第一個(gè)參數(shù)為對(duì)象,對(duì)象為函數(shù)調(diào)用之后返回新對(duì)象的原型對(duì)象,第二個(gè)參數(shù)為對(duì)象本身的實(shí)例方法(默認(rèn)不能修改,不能枚舉)
obj.__proto__.a === 1      // true 

obj.b = 3;
console.log(obj.b)      // 2

//創(chuàng)建一個(gè)可寫(xiě)的,可枚舉的,可配置的屬性p
obj2 = Object.create({}, {
  p: {
    value: 2,       // 屬性值
    writable: true,     //  是否可以重寫(xiě)值
    enumerable: true,   //是否可枚舉
    configurable: true  //是否可以修改以上幾項(xiàng)配置
  }
});

obj2.p = 3;
console.log(obj2.p)     // 3

注意: enumerable 會(huì)影響以下
for…in  遍歷包括對(duì)象原型上屬性

Object.keys()   只能遍歷自身屬性

JSON.stringify  只能序列化自身屬性

defineProperty Object.defineProperty(object, prop, descriptor)定義對(duì)象屬性

添加數(shù)據(jù)屬性
var obj = {};

// 1.添加一個(gè)數(shù)據(jù)屬性
Object.defineProperty(obj, "newDataProperty", {
    value: 101,
    writable: true,
    enumerable: true,
    configurable: true
});

obj.newDataProperty    // 101

// 2.修改數(shù)據(jù)屬性
Object.defineProperty(obj, "newDataProperty", {
    writable:false
});

//添加訪問(wèn)器屬性
var obj = {};

Object.defineProperty(obj, "newAccessorProperty", {
    set: function (x) {
        this.otherProperty = x;
    },
    get: function () {
        return this.otherProperty;
    },
    enumerable: true,
    configurable: true
});


注意:  1.第一個(gè)參數(shù)必須為對(duì)象
        2.descriptor 不能同時(shí)具有 (value 或 writable 特性)(get 或 set 特性)。
        3.configurable 為false 時(shí),不能重新修改裝飾器


defineProperties Object.defineProperties(object, {prop1 : descriptor1, prop2 : descriptor2, ...)

var obj = {};
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
});

keys 遍歷可枚舉的屬性,只包含對(duì)象本身可枚舉屬性,不包含原型鏈可枚舉屬性

let arr = ["a", "b", "c"];
let obj = { foo: "bar", baz: 42 };
let ArrayLike = { 0 : "a", 1 : "b", 2 : "c"};

Object.keys(arr)        // ['0', '1', '2']
Object.keys(obj)        // ["foo","baz"]
Object.keys(ArrayLike)  // ['0', '1', '2']

values 遍歷可枚舉的屬性值,只包含對(duì)象本身可枚舉屬性值,不包含原型鏈可枚舉屬性值

let arr = ["a", "b", "c"];
let obj = { foo: "bar", baz: 42 };
let ArrayLike = { 0 : "a", 1 : "b", 2 : "c"};

Object.values(arr)      // ["a", "b", "c"]
Object.values(obj)          // ["bar",42]
Object.values(ArrayLike)    // ["a", "b", "c"]

assign Object.assign( target, source, source1 ) 方法用于對(duì)象的合并,將源對(duì)象(source)的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象(target)??截惖膶傩允怯邢拗频?,只拷貝源對(duì)象的自身屬性(不拷貝繼承屬性),也不拷貝不可枚舉的屬性(enumerable: false)

const target = { a: 1, b: 1 };

const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2); target // {a:1, b:2, c:3}


特殊情況:
let obj = {a: 1};
Object.assign(obj, undefined) === obj  // true
Object.assign(obj, null) === obj       // true

Object.assign([1, 2, 3], [4, 5])        // [4, 5, 3]

Object.assign方法實(shí)行的是淺拷貝,而不是深拷貝。

const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);

obj1.a.b = 2;
console.log(obj2.a.b) //2
obj2.a.b = 3
console.log(obj1.a.b) //3

getPrototypeOf 獲取指定對(duì)象的原型(內(nèi)部[[Prototype]]屬性的值)

const prototype1 = {};
const object1 = Object.create(prototype1);

console.log(Object.getPrototypeOf(object1) === prototype1);   // true

注意:Object.getPrototypeOf(Object) 不是 Object.prototype
     Object.getPrototypeOf( Object ) === Function.prototype;  // true

setPrototypeOf 設(shè)置一個(gè)指定的對(duì)象的原型

const obj = {a: 1}, proto = {b:2}

Object.setPrototypeOf(obj, proto)

obj.__proto__ === proto     //true

getOwnPropertyNames 與keys相似,但包含遍歷包含不可枚舉屬性

var my_obj = Object.create({}, {
  getFoo: {
    value: function() { return this.foo; },
    enumerable: false
  }
});

my_obj.foo = 1;

Object.getOwnPropertyNames(my_obj).sort()   // ["foo", "getFoo"]

getOwnPropertyDescriptor 獲取該屬性的描述對(duì)象

let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')

//  { value: 123, writable: true, enumerable: true, configurable: true }

getOwnPropertyDescriptors 返回指定對(duì)象所有自身屬性(非繼承屬性)的描述對(duì)象

Object.getOwnPropertyDescriptors 方法,返回指定對(duì)象所有自身屬性(非繼承屬性)的描述對(duì)象。

const obj = {
  foo: 123,
  get bar() { return 'abc' }
};
 
console.dir(Object.getOwnPropertyDescriptors(obj))
//   { foo:{ value: 123,
//      writable: true,
//      enumerable: true,
//      configurable: true },
//       bar:{ get: [Function: bar],
//      set: undefined,
//      enumerable: true,
//      configurable: true } 
//     }


使用場(chǎng)景:
Object.assign() 方法只能拷貝源對(duì)象的可枚舉的自身屬性,同時(shí)拷貝時(shí)無(wú)法拷貝屬性的特性,而且訪問(wèn)器屬性會(huì)被轉(zhuǎn)換成數(shù)據(jù)屬性,也無(wú)法拷貝源對(duì)象的原型

Object.create() 方法可以實(shí)現(xiàn)上面說(shuō)的這些,配合getPrototypeOf,以及getOwnPropertyDescriptors實(shí)現(xiàn)全面淺拷貝

Object.create(
  Object.getPrototypeOf(obj), 
  Object.getOwnPropertyDescriptors(obj) 
);

entries 分割對(duì)象


const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

// array like object
const obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

//  string
Object.entries('abc')   // [['0', 'a'], ['1', 'b'], ['2', 'c']]

Object.entries(100)   // []

is 它用來(lái)比較兩個(gè)值是否嚴(yán)格相等,與嚴(yán)格比較運(yùn)算符(===)的行為基本一致

Object.is('foo', 'foo')     // true

Object.is({}, {})           // false

不同于 === 之處
+0 === -0                   //true
NaN === NaN                     // false

Object.is(+0, -0)           // false
Object.is(NaN, NaN)         // true

preventExtensions 讓一個(gè)對(duì)象變的不可擴(kuò)展,也就是永遠(yuǎn)不能再添加新的屬性&isExtensible 判斷一個(gè)對(duì)象是否可擴(kuò)展

let empty = {}

Object.isExtensible(empty)    //true
empty.a = 1             //添加成功
//將對(duì)象變?yōu)椴豢赏卣?Object.preventExtensions(empty)

Object.isExtensible(empty)    //false

empty.b = 2         //靜默失敗,不拋出錯(cuò)誤

empty.a = 5         //修改a屬性值為5  修改成功

總結(jié):
     1.preventExtensions 可以讓這個(gè)對(duì)象變的不可擴(kuò)展,也就是不能再有新的屬性。
    2.需要注意的是不可擴(kuò)展的對(duì)象的屬性通常仍然可以被刪除。
    3.嘗試給一個(gè)不可擴(kuò)展對(duì)象添加新屬性的操作將會(huì)失敗,不過(guò)可能是靜默失敗,也可能會(huì)拋出 TypeError 異常(嚴(yán)格模式)。        
    4.Object.preventExtensions 只能阻止一個(gè)對(duì)象不能再添加新的自身屬性,仍然可以為該對(duì)象的原型添加屬性。

seal將一個(gè)對(duì)象密封 isSealed 判斷一個(gè)對(duì)象是否為密封的

密封對(duì)象是指那些不能添加新的屬性,不能刪除已有屬性,以及不能修改已有屬性的可枚舉性、可配置性、可寫(xiě)性,但可能可以修改已有屬性的值的對(duì)象。

1. 先講seal 方法:
var o2 = {b: 1}
o2.d = 2    //添加成功
var obj2 = Object.seal(o2);
obj2 === o2         //true  方法返回原對(duì)象,棧指針指向同一塊內(nèi)存
Object.isSealed(o2)   // true

o2.b = 111       //修改b屬性值成功


o2.f = 222       //靜默失敗,屬性f沒(méi)有成功添加
delete o2.b      //靜默失敗,屬性b沒(méi)有成功刪除


2. 講isSealed 方法:
let o = {};
Object.isSealed(o)    //false

// 之后通過(guò)Object.preventExtensions方法將空對(duì)象設(shè)置為不可擴(kuò)展。
Object.preventExtensions(o);
Object.isSealed(o)    // true

但是如果為非空對(duì)象呢?

let o2 = {a: 1}
Object.preventExtensions(o2);
Object.isSealed(o2)    // false

因?yàn)閷傩?a 是可配置的(configurable為true),所以不是密封的對(duì)象,修改方法如下:
let o2 = {a: 1}
Object.preventExtensions(o2);
Object.defineProperty(o2, "a", { configurable: false });
Object.isSealed(o2)    //true


總結(jié): 1.密封一個(gè)對(duì)象會(huì)讓這個(gè)對(duì)象變的不能添加新屬性,且所有已有屬性會(huì)變的不可配置。
      2.屬性不可配置的效果就是屬性變的不可刪除,以及一個(gè)數(shù)據(jù)屬性不能被重新定義成為訪問(wèn)器屬性,或者反之。
      3.但屬性的值仍然可以修改。
      4.嘗試刪除一個(gè)密封對(duì)象的屬性或者將某個(gè)密封對(duì)象的屬性從數(shù)據(jù)屬性轉(zhuǎn)換成訪問(wèn)器屬性,結(jié)果會(huì)靜默失敗或拋出TypeError 異常(嚴(yán)格模式)。

freeze 凍結(jié)一個(gè)對(duì)象&isFrozen 判斷一個(gè)對(duì)象是否已經(jīng)被凍結(jié)

凍結(jié)對(duì)象是指那些不能添加新的屬性,不能修改已有屬性的值,不能刪除已有屬性,以及不能修改已有屬性的可枚舉性、可配置性、可寫(xiě)性的對(duì)象。也就是說(shuō),這個(gè)對(duì)象永遠(yuǎn)是不可變的。

1.先講freeze 方法:
let o3 = {a: 1}

o3.b = 2      //添加屬性b成功
Object.freeze(o3)

Object.isFrozen(o3)    //true 對(duì)象已被凍結(jié)

o3.a = 2       //修改屬性a值失敗
o3.c = 5       //添加屬性c失敗
delete o3.b   //刪除屬性b失敗

2.再講isfrozen 方法:

let o4 = {a: 1}

o4.b = 2     // 添加屬性b成功
Object.priventExtensions(o4)
Object.defineProperties(o4, {
    a: {configurable: false, writable: false},
    b: {configurable: false, writable: false}
})

Object.isFrozen(o4)    //true o4 已經(jīng)被凍結(jié)


總結(jié):
    1.凍結(jié)對(duì)象的所有自身屬性都不可能以任何方式被修改。
    2.任何嘗試修改該對(duì)象的操作都會(huì)失敗,可能是靜默失敗,也可能會(huì)拋出異常(嚴(yán)格模式中)。
    3.數(shù)據(jù)屬性的值不可更改,訪問(wèn)器屬性(有g(shù)etter和setter)也同樣(但由于是函數(shù)調(diào)用,給人的錯(cuò)覺(jué)是還是可以修改這個(gè)屬性)。
    4.如果一個(gè)屬性的值是個(gè)對(duì)象,則這個(gè)對(duì)象中的屬性是可以修改的,除非它也是個(gè)凍結(jié)對(duì)象。
    
    
淺凍結(jié)與深凍結(jié):
(function () {
    obj = {
        internal :{}
    };
    Object.freeze(obj);//淺凍結(jié)
    obj.internal.a = "aValue";
    console.log(obj.internal.a);//"aValue"

    //想讓一個(gè)對(duì)象變得完全凍結(jié),凍結(jié)所有對(duì)象中的對(duì)象,可以使用下面的函數(shù).
    function deepFreeze(o){
        var prop,propKey;
        Object.freeze(o);//首先凍結(jié)第一層對(duì)象
        for(propKey in o){
            prop = o[propKey];
            if(!o.hasOwnProperty(propKey) || !(typeof prop === "object") || Object.isFrozen(prop)){
                continue;
            }
            deepFreeze(prop);//遞歸
        }
    }

    deepFreeze(obj);
    obj.internal.b = "bValue";//靜默失敗
    console.log(obj.internal.b);//undefined
})();

hasOwnProperty

方法會(huì)返回一個(gè)布爾值,指示對(duì)象自身屬性中是否具有指定的屬性

let o = {a: 1 }

o.hasOwnProperty('a')   //true
o.hasOwnProperty('b')   //false   對(duì)象自身沒(méi)有屬性b
o.hasOwnProperty('toString');  //false  不能檢測(cè)對(duì)象原型鏈上的屬性


如何遍歷一個(gè)對(duì)象的所有自身屬性,例子:
var buz = {
    fog: 'stack'
};

for (var name in buz) {
    if (buz.hasOwnProperty(name)) {
       console.log("this is fog (" + name + ") for sure. Value: " + buz[name]);
    }
    else {
       console.log(name); // toString or something else
    }
}

isPrototypeOf

isPrototypeOf方法用于測(cè)試一個(gè)對(duì)象是否存在于另一個(gè)對(duì)象的原型鏈上

function Foo() {}
function Bar() {}
function Baz() {}

Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);

var baz = new Baz();

console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true

propertyIsEnumerable指定的屬性是否可枚舉

obj.propertyIsEnumerable(prop)   prop為被測(cè)試的屬性名

1. 一般情況下
var o = {};
var a = [];
o.prop = 'is enumerable';
a[0] = 'is enumerable';

o.propertyIsEnumerable('prop');   //  返回 true
a.propertyIsEnumerable(0);        // 返回 true


2. 瀏覽器內(nèi)置對(duì)象
var a = ['is enumerable'];

a.propertyIsEnumerable(0);          // 返回 true
a.propertyIsEnumerable('length');   // 返回 false

Math.propertyIsEnumerable('random');   // 返回 false
this.propertyIsEnumerable('Math');     // 返回 false

3. 自身屬性和繼承屬性
(原型鏈上propertyIsEnumerable不被考慮)

var fn = function(){
    this.prop = '123';
}

fn.prototype = { prototypeProp: true}

var o = new fn()

o.propertyIsEnumerable('prop')               // true
o.propertyIsEnumerable('prototypeProp')   // false

caller 返回當(dāng)前函數(shù)的調(diào)用者

function test(){
    if(test.caller == null){
        alert("JavaScript頂層作用域調(diào)用了test()函數(shù)");
    }else{
        alert( test.caller + "函數(shù)調(diào)用了test()函數(shù)");
    }
};
test(); // JavaScript頂層作用域調(diào)用了test()函數(shù)


function callTest(){
    test();
}
callTest(); // function callTest(){ test(); }函數(shù)調(diào)用了test()函數(shù)



function callTest2(){
    // setTimeout()或setInterval()中定時(shí)執(zhí)行的函數(shù)也屬于頂層作用域調(diào)用
    setTimeout(test, 5000); // JavaScript頂層作用域調(diào)用了test()函數(shù)
}
callTest2();

valueOf 需要返回對(duì)象的原始值

備注:js對(duì)象中的valueOf()方法和toString()方法非常類似,但是,當(dāng)需要返回對(duì)象的原始值而非字符串的時(shí)候才調(diào)用它,尤其是轉(zhuǎn)換為數(shù)字的時(shí)候。如果在需要使用原始值的上下文中使用了對(duì)象,JavaScript就會(huì)自動(dòng)調(diào)用valueOf()方法。

const o = {a: 1, valueOf: function(){ return 123123 } }
Number(o)    //123123

// 給大家出一個(gè)題
const o2 = {
    x: 1,
    valueOf: function(){
        return this.x++
    }
}

if(o2 == 1 && o2 == 2 && o2 == 3){
    console.log('down')
    console.log(o2.x)
}else{
    console.log('faild')
}

// Array:返回?cái)?shù)組對(duì)象本身
var array = ["CodePlayer", true, 12, -5];
array.valueOf() === array;   // true

// Date:當(dāng)前時(shí)間距1970年1月1日午夜的毫秒數(shù)
var date = new Date(2013, 7, 18, 23, 11, 59, 230);
date.valueOf()     // 1376838719230

// Number:返回?cái)?shù)字值
var num =  15.26540;
num.valueOf()     // 15.2654

// 布爾:返回布爾值true或false
var bool = true;
bool.valueOf() === bool    // true
// new一個(gè)Boolean對(duì)象
var newBool = new Boolean(true);
// valueOf()返回的是true,兩者的值相等
newBool.valueOf() == newBool     // true
// 但是不全等,兩者類型不相等,前者是boolean類型,后者是object類型
newBool.valueOf() === newBool     // false

// Function:返回函數(shù)本身
function foo(){ 
}
foo.valueOf() === foo      // true
var foo2 =  new Function("x", "y", "return x + y;");
foo2.valueOf() === foo2    // true

// Object:返回對(duì)象本身
var obj = {name: "張三", age: 18};
obj.valueOf() === obj        // true

// String:返回字符串值
var str = "http://www.365mini.com";
str.valueOf() === str       // true
// new一個(gè)字符串對(duì)象
var str2 = new String("http://www.365mini.com");
// 兩者的值相等,但不全等,因?yàn)轭愋筒煌?,前者為string類型,后者為object類型
str2.valueOf() === str2      // false

getOwnPropertySymbols在給定對(duì)象自身上找到的所有 Symbol 屬性的數(shù)組。

var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");

obj[a] = "localSymbol";
obj[b] = "globalSymbol";

var objectSymbols = Object.getOwnPropertySymbols(obj);

console.log(objectSymbols.length); // 2
console.log(objectSymbols)         // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0])      // Symbol(a)

toString toLocalString

toString 方法不做過(guò)多介紹
區(qū)別:
當(dāng)被轉(zhuǎn)化的值是個(gè)時(shí)間對(duì)象時(shí),toLocaleString會(huì)將轉(zhuǎn)化的結(jié)果以本地表示。

(new Date).toString(); //"Mon Nov 06 2017 13:02:46 GMT+0800 (China Standard Time)"

(new Date).toLocaleString();  //"2017/11/6 下午1:03:12"

另外當(dāng)被轉(zhuǎn)化的值是個(gè)時(shí)間戳?xí)r,toLocaleString會(huì)把時(shí)間戳每三位添加一個(gè)逗號(hào),代碼如下。

(Date.parse(new Date())).toLocaleString() //"1,509,944,637,000"

(Date.parse(new Date())).toString() //"1509944643000"

call  apply bind  大家自己回去研究

length

Object.length    //1

name

Object.name    //"Object"

本文作者原創(chuàng),僅供學(xué)習(xí)交流使用,轉(zhuǎn)載需注明出處。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容