Object.keys方法是JavaScript中用於遍歷對象屬性的一個方法 。它傳入的參數是一個對象,返回的是一個數組,數組中包含的是該對象全部的屬性名。
如:javascript
var cat= { name:’mini’, age:2, color:’yellow’, desc:」cute」 } console.log(Object.keys(cat)); // ["name", "age", "color", "desc"]
輸出對象中值大於2的key的數組html
var data = {a: 1, b: 2, c: 3, d: 4}; Object.keys(data).filter(function(x) { return 1 ;})
期待輸出:[「c」,」d」]
請問1處填什麼?java
正確答案:1 :data[x]>2es6
Object.keys是es5中新增的方法,用來獲取對象自身全部的可枚舉的屬性名,但不包括原型中的屬性,而後返回一個由屬性名組成的數組。注意它同for..in同樣不能保證屬性按對象原來的順序輸出。
Object.getOwnPropertyNames也是es5中新增的方法,返回對象的全部自身屬性的屬性名(包括不可枚舉的屬性)組成的數組,但不會獲取原型鏈上的屬性。segmentfault
Array.filter(function)對數組進行過濾返回符合條件的數組。數組
Object.values方法返回一個數組,成員是參數對象自身的(不含繼承的)全部可遍歷( enumerable )屬性的鍵值。瀏覽器
var obj = { foo: "bar", baz: 42 }; Object.values(obj) // ["bar", 42]
返回數組的成員順序,屬性名爲數值的屬性,是按照數值大小,從小到大遍歷的,所以返回的順序是b、c、a。Object.values只返回對象自身的可遍歷屬性。函數
var obj = { 100: 'a', 2: 'b', 7: 'c' }; Object.values(obj) // ["b", "c", "a"]
若是Object.values方法的參數是一個字符串,會返回各個字符組成的一個數組。this
Object.values('foo') // ['f', 'o', 'o']
上面代碼中,字符串會先轉成一個相似數組的對象。字符串的每一個字符,就是該對象的一個屬性。所以,Object.values返回每一個屬性的鍵值,就是各個字符組成的一個數組。
若是參數不是對象,Object.values會先將其轉爲對象。因爲數值和布爾值的包裝對象,都不會爲實例添加非繼承的屬性。因此,Object.values會返回空數組。es5
Object.create()方法建立一個新對象,使用現有的對象來提供新建立的對象的__proto__。
語法
Object.create(proto, [propertiesObject])
參數
proto
新建立對象的原型對象。
propertiesObject
可選。若是沒有指定爲 undefined,則是要添加到新建立對象的可枚舉屬性(即其自身定義的屬性,而不是其原型鏈上的枚舉屬性)對象的屬性描述符以及相應的屬性名稱。這些屬性對應Object.defineProperties()的第二個參數。
返回值
一個新對象,帶着指定的原型對象和屬性。
如:
var parent = { x : 1, y : 1 } var child = Object.create(parent,{ z : { // z會成爲建立對象的屬性 writable:true, configurable:true, value: "newAdd" } }); console.log(child)//{z: "newAdd"}z: "newAdd"__proto__: x: 1y: 1__proto__: Object
function A(){ this.a = 1; this.b = 2; } A.prototype.drive = function(){ console.log('drivvvvvvvvvv'); } //方式1 function B(){} B.prototype = Object.create(new A()); //這裏採用了new 一個實例 //方式2 function C(){ A.call(this); } C.prototype = Object.create(A.prototype) //這裏使用的是父類的原型
以上兩種方式有什麼區別?
1的缺點:
執行了 new,至關於運行了一遍 A ,若是在 A 裏作了一些其它事情(如改變全局變量)就會有反作用。
用 A 建立的對象作原型,裏面可能會有一些冗餘的屬性。
2模擬了 new 的執行過程
判斷對象自身屬性中是否具備指定的屬性。
在某個對象是否擁有某個屬性,判斷的方法有不少,經常使用的方法就是object.hasOwnProperty('×××'),這個方法是不包括對象原型鏈上的方法的
var obj = {
name:'fei'
}
console.log(obj.hasOwnProperty('name'))//true
console.log(obj.hasOwnProperty('toString'))//false
以上,obj對象存在的name屬性的時候,調用這個方法纔是返回true,咱們知道其實每一個對象實例的原型鏈上存在toString方法,在這裏打印false,說明這個方法只是代表實例對象的屬性,不包括原型鏈上的屬性。 ## Object.getOwnPropertyNames()方法 Object.getOwnPropertyNames()方法返回對象的全部自身屬性的屬性名(包括不可枚舉的屬性)組成的數組,但不會獲取原型鏈上的屬性。
function A(a,aa) {
this.a = a;
this.aa = aa;
this.getA = function() {
return this.a;
}
}
// 原型方法
A.prototype.aaa = function () {};
var B = new A('b', 'bb');
B.myMethodA = function() {};
// 不可枚舉方法
Object.defineProperty(B, 'myMethodB', {
enumerable: false,
value: function() {}
});
Object.getOwnPropertyNames(B); // ["a", "aa", "getA", "myMethodA", "myMethodB"]
### Object.getOwnPropertyNames和Object.keysq區別 Object.getOwnPropertyNames和Object.keys的區別,即Object.keys只適用於可枚舉的屬性,而Object.getOwnPropertyNames返回對象自動的所有屬性名稱。
'use strict';
(function(){
if(!Object.getOwnPropertyNames){
console.log('瀏覽器不支持getOwnPropertyNames');
return;
}
//人類的構造函數 var person = function(name, age, sex){ this.name = name; this.age = age; this.sex = sex; this.sing = function(){ console.log('sing'); } } //new 一個ladygaga var gaga = new person('ladygaga', 26, 'girl'); //給嘎嘎發放一個不可枚舉的身份證 Object.defineProperty(gaga, 'id', { value : '1234567890', enumerable : false }); //查看gaga的我的信息 var arr = Object.getOwnPropertyNames(gaga); document.write(arr); //output: name,age,sex,sing,id document.write('</br>');
//注意和getOwnPropertyNames的區別,不可枚舉的id沒有輸出
var arr1 = Object.keys(gaga);
document.write(arr1); //output: name,age,sex,sing
})();
## es6 javascript對象方法Object.assign() Object.assign方法用於對象的合併,將源對象( source )的全部可枚舉屬性,複製到目標對象( target )。
var target = { a: 1 };
var source1 = { b: 2 };
var source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
一、若是目標對象與源對象有同名屬性,或多個源對象有同名屬性,則後面的屬性會覆蓋前面的屬性。 二、若是隻有一個參數,Object.assign會直接返回該參數。
var obj = {a: 1};
Object.assign(obj) === obj // true
三、若是該參數不是對象,則會先轉成對象,而後返回。 四、因爲undefined和null沒法轉成對象,因此若是它們做爲參數,就會報錯。 五、Object.assign方法實行的是淺拷貝,而不是深拷貝。也就是說,若是源對象某個屬性的值是對象,那麼目標對象拷貝獲得的是這個對象的引用。
var obj1 = {a: {b: 1}};
var obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2
上面代碼中,源對象obj1的a屬性的值是一個對象,Object.assign拷貝獲得的是這個對象的引用。這個對象的任何變化,都會反映到目標對象上面。 ### 常見用途 ( 1 )爲對象添加屬性
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}
上面方法經過Object.assign方法,將x屬性和y屬性添加到Point類的對象實例。 ( 2 )爲對象添加方法
Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});
// 等同於下面的寫法
SomeClass.prototype.someMethod = function (arg1, arg2) {
···
};
SomeClass.prototype.anotherMethod = function () {
···
};
上面代碼使用了對象屬性的簡潔表示法,直接將兩個函數放在大括號中,再使用 assign 方法添加到 SomeClass.prototype 之中。 ( 3 )克隆對象
function clone(origin) {
return Object.assign({}, origin);
}
上面代碼將原始對象拷貝到一個空對象,就獲得了原始對象的克隆。 不過,採用這種方法克隆,只能克隆原始對象自身的值,不能克隆它繼承的值。 ( 4 )合併多個對象 將多個對象合併到某個對象。
const merge =(target, ...sources) => Object.assign(target, ...sources);
若是但願合併後返回一個新對象,能夠改寫上面函數,對一個空對象合併。
const merge =(...sources) => Object.assign({}, ...sources);
( 5 )爲屬性指定默認值
const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
};
function processContent(options) {
let options = Object.assign({}, DEFAULTS, options);
}
上面代碼中,DEFAULTS對象是默認值,options對象是用戶提供的參數。Object.assign方法將DEFAULTS和options合併成一個新對象,若是二者有同名屬性,則option的屬性值會覆蓋DEFAULTS的屬性值。 注意,因爲存在深拷貝的問題,DEFAULTS對象和options對象的全部屬性的值,都只能是簡單類型,而不能指向另外一個對象。不然,將致使DEFAULTS對象的該屬性不起做用。 > 參考https://blog.csdn.net/qq_30100043/article/details/53422657 ## Object.defineProperty()方法理解 > Object.defineProperty能夠用來定義新屬性或修改原有的屬性 使用構造函數定義對象和屬性
var obj = new Object; //obj = {}
obj.name = "張三"; //添加描述
obj.say = function(){}; //添加行爲
### 語法
Object.defineProperty(obj, prop, descriptor)
參數說明 obj:必需。目標對象 prop:必需。需定義或修改的屬性的名字 descriptor:必需。目標屬性所擁有的特性 **給對象的屬性添加特性描述,目前提供兩種形式:數據描述和存取器描述** ### 數據描述 修改或定義對象的某個屬性的時候,給這個屬性添加一些特性, 數據描述中的屬性都是可選的
var obj = {
test:"hello"
}
//對象已有的屬性添加特性描述Object.defineProperty(obj,"test",{
configurable:true | false,
enumerable:true | false,
value:任意類型的值,
writable:true | false
});
//對象新添加的屬性的特性描述Object.defineProperty(obj,"newKey",{
configurable:true | false,
enumerable:true | false,
value:任意類型的值,
writable:true | false
});
value: 設置屬性的值 writable: 值是否能夠重寫。true | false enumerable: 目標屬性是否能夠被枚舉。true | false configurable: 目標屬性是否能夠被刪除或是否能夠再次修改特性 true | false ### 存取器描述 使用存取器描述屬性的特性的時候,容許設置如下特性屬性, 當使用了getter或setter方法,不容許使用writable和value這兩個屬性
var obj = {};
Object.defineProperty(obj,"newKey",{
get:function (){} | undefined,
set:function (value){} | undefined
configurable: true | false
enumerable: true | false
});
**getter/setter** getter 是一種得到屬性值的方法 setter是一種設置屬性值的方法。 使用get/set屬性來定義對應的方法
var obj = {};
var initValue = 'hello';
Object.defineProperty(obj,"newKey",{
get:function (){
//當獲取值的時候觸發的函數
return initValue;
},
set:function (value){
//當設置值的時候觸發的函數,設置的新值經過參數value拿到
initValue = value;
}
});
//獲取值console.log( obj.newKey ); //hello
//設置值
obj.newKey = 'change value';
console.log( obj.newKey ); //change value
```
在ie8下只能在DOM對象上使用,嘗試在原生的對象使用 Object.defineProperty()會報錯。 參考https://segmentfault.com/a/1190000007434923