对象方法

对象方法:
1、Object.keys();
例:
// 定义一个 Array 对象
let arr = ['a', 'b', 'c'];
 
// 定义一个 Object 对象
let obj = { foo: "bar", baz: 42 };
 
  
// 定义一个类数组
 
  
let arrLike = { 0 : "a", 1 : "b", 2 : "c"};
 
  
// 类数组 对象, 随机 key 排序 
let anObj = { 100: 'a', 2: 'b', 7: 'c' }; 
 
  
 
  
/* getFoo 是个不可枚举的属性 */ 
 var my_obj = Object.create({}, {
     getFoo : { value : function () { return this.foo }
);
my_obj.foo = 1;
 
  
console.log(Object.keys(arr)); // ['0','1','2'];
console.log(Object.keys(obj)); // ['foo','baz'];
console.log(Object.keys(arrLike)); // ['0','1','2'];
console.log(Object.keys(anObj)); // ['100','2','7'];
console.log(Object.keys(my_obj)); // foo;
 
  
返回数组中的排序与for..in是一致的,区别在于for..in循环还可以枚举原型链上的属性
2、Object.getOwnPropertyNames
// 定义一个数组 
var arr = ["a", "b", "c"]; 
 // 定义一个 类数组对象 
var obj = { 0: "a", 1: "b", 2: "c"};
 //定义一个 不可枚举属性 
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; }, enumerable: false } }); 
my_obj.foo = 1; 
 // 打印结果 
console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"] 
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"] 
console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
 
3.对象属性相关的方法

对象里目前存在的属性描述符有两种主要形式:数据描述符  和 存取描述符

    数据描述符: 是一个具有值的属性,该值可能是可写的,也可能不是可写的。

    访问器描述符: 是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。

  数据描述符和存取描述符均具有以下可选键值:

    configurable: 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。

    enumerable: 当且仅当该属性的enumerabletrue时,该属性才能够出现在对象的枚举属性中。默认为 false。

    value: 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。

    writable: 当且仅当该属性的writabletrue时,value才能被赋值运算符改变。默认为 false。

    getter: 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。

    setter:  一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。

    注意:如果一个描述符同时设置value,writable,get和set关键字,它将被认为是一个数据描述符。如果一个描述符同时有value或writable和get或set关键字,将产生异常。

    记住,这些选项不一定是自身属性,如果是继承来的也要考虑。为了确认保留这些默认值,你可能要在这之前冻结 Object.prototype,明确指定所有的选项,或者将 __proto__属性指向null

  a).Object.getOwnPropertyDescriptor( obj, prop) 返回一个指定对象上的自有属性对应的属性描述 (自由属性指,直接赋值的属性,不需要从原型上查找的属性)

   参数:

    obj 需要查找的目标对象

    prop 目标对象内的属性名称

 

let o = { get foo() { return 17; } };
let d = Object.getOwnPropertyDescriptor(o, "foo");

let o1 = { bar: 42 };
let d1 = Object.getOwnPropertyDescriptor(o1, "bar");

let o2 = {};
Object.defineProperty(o2, "baz", {
    value: 8675309,
    writable: false,
    enumerable: false
});
let d2 = Object.getOwnPropertyDescriptor(o2, "baz");
console.log(d)// {configurable: true, enumerable: true, get: [Function: get foo],set: undefined}
console.log(d1)//{configurable: true, enumerable: true, value: 42, writable: true}
console.log(d2)// {value: 8675309, writable: false, enumerable: false, configurable: false}

 

b).Object.defineProperty( obj, prop, decriptor)  直接在一个对象上定义一个新属性,或修改一个对象的现有属性,并返回这个对象,默认情况下使用此方法添加的属性值是不能被修改的

  参数:

    obj 要在其上定义属性的对象

    prop 要定义或修改的属性名称

 

    decriptor 将被定义或修改的属性描述符

 

 

var o = {}; // 创建一个新对象

 

// 在对象中添加一个属性与数据描述符的示例

Object.defineProperty(o, "a", {

    value : 37,

    writable : true,

    enumerable : true,

    configurable : true

});

// 对象o拥有了属性a,值为37

 

// 在对象中添加一个属性与存取描述符的示例

var bValue;

Object.defineProperty(o, "b", {

    get : function(){

        return bValue;

    },

    set : function(newValue){

        bValue = newValue;

    },

    enumerable : true,

    configurable : true

});

o.b = 38;

// 对象o拥有了属性b,值为38

 

// o.b的值现在总是与bValue相同,除非重新定义o.b

 

// 数据描述符和存取描述符不能混合使用

Object.defineProperty(o, "conflict", {

    value: 0x9f91102,

    get: function() {

        return 0xdeadbeef;

    }

});

// TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute(无效的属性描述符,不能同时指定访问器和值或可写属性)

  c).Object.defineProperties()

  d).Object.getOwnPropertyNames()

 

 

4.控制对象状态的方法

  a).Object.preventExtensions() 防止对象扩展

  b).Object.isExtensible() 判断对象是否可扩展

  c).Object.seal() 禁止对象配置

  d).Object.isSealed() 判断一个对象是否可配置

  e).Object.freeze() 冻结一个对象

  f).Object.isFrozen() 判断一个对象是否被冻结

 

5.原型链相关方法

  a).Object.creat() 可以指定原型对象和属性,返回一个新的对象

  b).Object.getPrototypeOf() 获取对的的Prototype对象

 

Object对象的实例方法

除了Object对象本身的方法,还有不少方法是部署在Object.prototype对象上的,所有Object的实例对象都继承了这些方法。Object实例对象的方法,主要有以下六个。(此句摘自 --阮一峰 博客)

  a). valueOf()返回当前对象对应的值

  b). toString()返回当前对象对应的字符串形式,用来判断一个值的类型

  c). toLocaleString()返回当前对象对应的本地字符串形式

  d). hasOwnProperty()判断某个属性是否为当前对象自身的属性,还是继承自原型对象的属性

  e). isPrototypeOf()判断当前对象是否为另一个对象的原型

  f). propertyIsEnumerable()判断某个属性是否可枚举

 

 

ES6 允许在对象之中,直接写变量。这时,属性名为变量名, 属性值为变量的值。

属性的赋值器(setter)和取值器(getter),
const cart = {
  _wheels: 4,
  get wheels () {
    return this._wheels;
  },
  set wheels (value) {
    if (value < this._wheels) {
      throw new Error('数值太小了!');
    }
    this._wheels = value;
  }
}
 
4.Object.is() 它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致
ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。
 
Object.is('foo', 'foo') // true 
Object.is({}, {}) // false
 
不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
 
+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
 
  
5.Object.assign( target, source, source1 ) 方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false
 
  

参数

    target 目标对象

    source 源对象

 

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}

 

注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。

如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefinednull不在首参数,就不会报错。

注意:

  a). Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

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

 

上面代码中,源对象obj1a属性的值是一个对象,Object.assign拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。

 

 b).  数组的处理

 

 

Object.assign([1, 2, 3], [4, 5])// [4, 5, 3]
上面代码中,Object.assign把数组视为属性名为 0、1、2 的对象,因此源数组的 0 号属性4覆盖了目标数组的 0 号属性1
 
  
常见用途
a). 为对象添加属性
 
class Point {
  constructor(x, y) {
    Object.assign(this, {x, y});
  }
}
上面方法通过Object.assign方法,将x属性和y属性添加到Point类的对象实例
b). 为对象添加方法
Object.assign(SomeClass.prototype, {
  someMethod(arg1, arg2) {
    ···
  },
  anotherMethod() {
    ···
  }
});

// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
  ···
};
SomeClass.prototype.anotherMethod = function () {
  ···
};
 
  
上面代码使用了对象属性的简洁表示法,直接将两个函数放在大括号中,再使用assign方法添加到SomeClass.prototype之中。
 
  
c). 克隆对象
 
function clone(origin) {
  return Object.assign({}, origin);
}

上面代码将原始对象拷贝到一个空对象,就得到了原始对象的克隆。

不过,采用这种方法克隆,只能克隆原始对象自身的值,不能克隆它继承的值。如果想要保持继承链,可以采用下面的代码

 

function clone(origin) {
  let originProto = Object.getPrototypeOf(origin);
  return Object.assign(Object.create(originProto), origin);
}
d). 合并多个对象,将多个对象合并到某个对象。
 
const merge = (target, ...sources) => Object.assign(target,...sources);

//如果希望合并后返回一个新对象,可以改写上面函数,对一个空对象合并。

const merge =(...sources) => Object.assign({}, ...sources);
 
  
e). 为属性指定默认值
 
6.属性的可枚举和可遍历
 
  
  可枚举性
 
  
  对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。
 
  
  a). Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。
 
  
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
//  { value: 123, writable: true, enumerable: true, configurable: true };
 
  
            目前,有四个操作会忽略enumerable为false的属性。

    for...in循环:只遍历对象自身的和继承的可枚举的属性。

    Object.keys():返回对象自身的所有可枚举的属性的键名。

    JSON.stringify():只串行化对象自身的可枚举的属性。

    Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。
 
 
ES6 规定,所有 Class 的原型的方法都是不可枚举的。
 
for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。     
Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。     Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。     Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。     
Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
 
 
7.Object.getOwnPropertyDescriptors()
 
8.__proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf() 
9.super 关键字
10.Object.keys(),Object.values(),Object.entries()
 
11.对象的扩展运算符
 
  
  a). 解构赋值
 
  
  b). 扩展运算符
 
  
 12.Null 传导运算符
 
  
 
  
 
  

对象可枚举和不可枚举属性

 在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable值决定的。可枚举性决定了这个属性能否被for…in查找遍历到。
 
一、怎么判断属性是否可枚举
js中基本包装类型的原型属性是不可枚举的,如Object, Array, Number等,如果你写出这样的代码遍历其中的属性:
var num = new Number();
for(var pro in num) {
    console.log("num." + pro + " = " + num[pro]);
}
它的输出结果会是空。这是因为Number中内置的属性是不可枚举的,所以不能被for…in访问到。

Object对象的propertyIsEnumerable()方法可以判断此对象是否包含某个属性,并且这个属性是否可枚举。

需要注意的是:如果判断的属性存在于Object对象的原型内,不管它是否可枚举都会返回false。

 

二、枚举性的作用

属性的枚举性会影响以下三个函数的结果:

for…in

Object.keys()

JSON.stringify

 

先看一个例子,按如下方法创建kxy对象:

function Person() {

    this.name = "KXY";

}

Person.prototype = {

    constructor: Person,

    job: "student",

};

 

var kxy = new Person();

Object.defineProperty(kxy, "sex", {

    value: "female",

    enumerable: false

 

});

 

其中用defineProperty为对象定义了一个名为”sex”的不可枚举属性

for(var pro in kxy) {

    console.log("kxy." + pro + " = " + kxy[pro]);

 

  }

 

可以看到除了”sex“之外的属性都遍历到了

只包含”name”属性,说明该方法只能返回对象本身具有的可枚举属性。

 

 

13、call();

call() 方法是与经典的对象冒充方法最相似的方法。它的第一个参数用作 this 的对象。其他参数都直接传递给函数自身。

function sayColor(sPrefix,sSuffix) {

    alert(sPrefix + this.color + sSuffix);

};

 

var obj = new Object();

obj.color = "blue";

 

 

sayColor.call(obj, "The ", "is a very nice color indeed.");

14、apply();

apply() 方法有两个参数,用作 this 的对象和要传递给函数的参数的数组。

function sayColor(sPrefix,sSuffix) {
    alert(sPrefix + this.color + sSuffix);
};

var obj = new Object();
obj.color = "blue";

sayColor.apply(obj, new Array("The ", " is a very nice color indeed."));
对象方法:
1、Object.keys();
例:
// 定义一个 Array 对象
let arr = ['a', 'b', 'c'];
 
// 定义一个 Object 对象
let obj = { foo: "bar", baz: 42 };
 
     
// 定义一个类数组
 
     
let arrLike = { 0 : "a", 1 : "b", 2 : "c"};
 
     
// 类数组 对象, 随机 key 排序 
let anObj = { 100: 'a', 2: 'b', 7: 'c' }; 
 
     
 
     
/* getFoo 是个不可枚举的属性 */ 
 var my_obj = Object.create({}, {
     getFoo : { value : function () { return this.foo }
);
my_obj.foo = 1;
 
     
console.log(Object.keys(arr)); // ['0','1','2'];
console.log(Object.keys(obj)); // ['foo','baz'];
console.log(Object.keys(arrLike)); // ['0','1','2'];
console.log(Object.keys(anObj)); // ['100','2','7'];
console.log(Object.keys(my_obj)); // foo;
 
     
返回数组中的排序与for..in是一致的,区别在于for..in循环还可以枚举原型链上的属性
2、Object.getOwnPropertyNames
// 定义一个数组 
var arr = ["a", "b", "c"]; 
 // 定义一个 类数组对象 
var obj = { 0: "a", 1: "b", 2: "c"};
 //定义一个 不可枚举属性 
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; }, enumerable: false } }); 
my_obj.foo = 1; 
 // 打印结果 
console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"] 
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"] 
console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
 
3.对象属性相关的方法

对象里目前存在的属性描述符有两种主要形式:数据描述符  和 存取描述符

    数据描述符: 是一个具有值的属性,该值可能是可写的,也可能不是可写的。

    访问器描述符: 是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。

  数据描述符和存取描述符均具有以下可选键值:

    configurable: 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。

    enumerable: 当且仅当该属性的enumerabletrue时,该属性才能够出现在对象的枚举属性中。默认为 false。

    value: 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。

    writable: 当且仅当该属性的writabletrue时,value才能被赋值运算符改变。默认为 false。

    getter: 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。

    setter:  一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。

    注意:如果一个描述符同时设置value,writable,get和set关键字,它将被认为是一个数据描述符。如果一个描述符同时有value或writable和get或set关键字,将产生异常。

    记住,这些选项不一定是自身属性,如果是继承来的也要考虑。为了确认保留这些默认值,你可能要在这之前冻结 Object.prototype,明确指定所有的选项,或者将 __proto__属性指向null

  a).Object.getOwnPropertyDescriptor( obj, prop) 返回一个指定对象上的自有属性对应的属性描述 (自由属性指,直接赋值的属性,不需要从原型上查找的属性)

   参数:

    obj 需要查找的目标对象

    prop 目标对象内的属性名称

 

let o = { get foo() { return 17; } };
let d = Object.getOwnPropertyDescriptor(o, "foo");

let o1 = { bar: 42 };
let d1 = Object.getOwnPropertyDescriptor(o1, "bar");

let o2 = {};
Object.defineProperty(o2, "baz", {
    value: 8675309,
    writable: false,
    enumerable: false
});
let d2 = Object.getOwnPropertyDescriptor(o2, "baz");
console.log(d)// {configurable: true, enumerable: true, get: [Function: get foo],set: undefined}
console.log(d1)//{configurable: true, enumerable: true, value: 42, writable: true}
console.log(d2)// {value: 8675309, writable: false, enumerable: false, configurable: false}

 

b).Object.defineProperty( obj, prop, decriptor)  直接在一个对象上定义一个新属性,或修改一个对象的现有属性,并返回这个对象,默认情况下使用此方法添加的属性值是不能被修改的

  参数:

    obj 要在其上定义属性的对象

    prop 要定义或修改的属性名称

 

    decriptor 将被定义或修改的属性描述符

 

 

var o = {}; // 创建一个新对象

 

// 在对象中添加一个属性与数据描述符的示例

Object.defineProperty(o, "a", {

    value : 37,

    writable : true,

    enumerable : true,

    configurable : true

});

// 对象o拥有了属性a,值为37

 

// 在对象中添加一个属性与存取描述符的示例

var bValue;

Object.defineProperty(o, "b", {

    get : function(){

        return bValue;

    },

    set : function(newValue){

        bValue = newValue;

    },

    enumerable : true,

    configurable : true

});

o.b = 38;

// 对象o拥有了属性b,值为38

 

// o.b的值现在总是与bValue相同,除非重新定义o.b

 

// 数据描述符和存取描述符不能混合使用

Object.defineProperty(o, "conflict", {

    value: 0x9f91102,

    get: function() {

        return 0xdeadbeef;

    }

});

// TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute(无效的属性描述符,不能同时指定访问器和值或可写属性)

  c).Object.defineProperties()

  d).Object.getOwnPropertyNames()

 

 

4.控制对象状态的方法

  a).Object.preventExtensions() 防止对象扩展

  b).Object.isExtensible() 判断对象是否可扩展

  c).Object.seal() 禁止对象配置

  d).Object.isSealed() 判断一个对象是否可配置

  e).Object.freeze() 冻结一个对象

  f).Object.isFrozen() 判断一个对象是否被冻结

 

5.原型链相关方法

  a).Object.creat() 可以指定原型对象和属性,返回一个新的对象

  b).Object.getPrototypeOf() 获取对的的Prototype对象

 

Object对象的实例方法

除了Object对象本身的方法,还有不少方法是部署在Object.prototype对象上的,所有Object的实例对象都继承了这些方法。Object实例对象的方法,主要有以下六个。(此句摘自 --阮一峰 博客)

  a). valueOf()返回当前对象对应的值

  b). toString()返回当前对象对应的字符串形式,用来判断一个值的类型

  c). toLocaleString()返回当前对象对应的本地字符串形式

  d). hasOwnProperty()判断某个属性是否为当前对象自身的属性,还是继承自原型对象的属性

  e). isPrototypeOf()判断当前对象是否为另一个对象的原型

  f). propertyIsEnumerable()判断某个属性是否可枚举

 

 

ES6 允许在对象之中,直接写变量。这时,属性名为变量名, 属性值为变量的值。

属性的赋值器(setter)和取值器(getter),
const cart = {
  _wheels: 4,
  get wheels () {
    return this._wheels;
  },
  set wheels (value) {
    if (value < this._wheels) {
      throw new Error('数值太小了!');
    }
    this._wheels = value;
  }
}
 
4.Object.is() 它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致
ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。
 
Object.is('foo', 'foo') // true 
Object.is({}, {}) // false
 
不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
 
+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
 
     
5.Object.assign( target, source, source1 ) 方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false
 
     

参数

    target 目标对象

    source 源对象

 

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}

 

注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。

如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefinednull不在首参数,就不会报错。

注意:

  a). Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

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

 

上面代码中,源对象obj1a属性的值是一个对象,Object.assign拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。

 

 b).  数组的处理

 

 

Object.assign([1, 2, 3], [4, 5])// [4, 5, 3]
上面代码中,Object.assign把数组视为属性名为 0、1、2 的对象,因此源数组的 0 号属性4覆盖了目标数组的 0 号属性1
 
     
常见用途
a). 为对象添加属性
 
class Point {
  constructor(x, y) {
    Object.assign(this, {x, y});
  }
}
上面方法通过Object.assign方法,将x属性和y属性添加到Point类的对象实例
b). 为对象添加方法
Object.assign(SomeClass.prototype, {
  someMethod(arg1, arg2) {
    ···
  },
  anotherMethod() {
    ···
  }
});

// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
  ···
};
SomeClass.prototype.anotherMethod = function () {
  ···
};
 
     
上面代码使用了对象属性的简洁表示法,直接将两个函数放在大括号中,再使用assign方法添加到SomeClass.prototype之中。
 
     
c). 克隆对象
 
function clone(origin) {
  return Object.assign({}, origin);
}

上面代码将原始对象拷贝到一个空对象,就得到了原始对象的克隆。

不过,采用这种方法克隆,只能克隆原始对象自身的值,不能克隆它继承的值。如果想要保持继承链,可以采用下面的代码

 

function clone(origin) {
  let originProto = Object.getPrototypeOf(origin);
  return Object.assign(Object.create(originProto), origin);
}
d). 合并多个对象,将多个对象合并到某个对象。
 
const merge = (target, ...sources) => Object.assign(target,...sources);

//如果希望合并后返回一个新对象,可以改写上面函数,对一个空对象合并。

const merge =(...sources) => Object.assign({}, ...sources);
 
     
e). 为属性指定默认值
 
6.属性的可枚举和可遍历
 
     
  可枚举性
 
     
  对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。
 
     
  a). Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。
 
     
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
//  { value: 123, writable: true, enumerable: true, configurable: true };
 
     
            目前,有四个操作会忽略enumerable为false的属性。

    for...in循环:只遍历对象自身的和继承的可枚举的属性。

    Object.keys():返回对象自身的所有可枚举的属性的键名。

    JSON.stringify():只串行化对象自身的可枚举的属性。

    Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。
 
 
ES6 规定,所有 Class 的原型的方法都是不可枚举的。
 
for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。     
Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。     Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。     Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。     
Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
 
 
7.Object.getOwnPropertyDescriptors()
 
8.__proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf() 
9.super 关键字
10.Object.keys(),Object.values(),Object.entries()
 
11.对象的扩展运算符
 
     
  a). 解构赋值
 
     
  b). 扩展运算符
 
     
 12.Null 传导运算符
 
     
 
     
 
     

对象可枚举和不可枚举属性

 在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable值决定的。可枚举性决定了这个属性能否被for…in查找遍历到。
 
一、怎么判断属性是否可枚举
js中基本包装类型的原型属性是不可枚举的,如Object, Array, Number等,如果你写出这样的代码遍历其中的属性:
var num = new Number();
for(var pro in num) {
    console.log("num." + pro + " = " + num[pro]);
}
它的输出结果会是空。这是因为Number中内置的属性是不可枚举的,所以不能被for…in访问到。

Object对象的propertyIsEnumerable()方法可以判断此对象是否包含某个属性,并且这个属性是否可枚举。

需要注意的是:如果判断的属性存在于Object对象的原型内,不管它是否可枚举都会返回false。

 

二、枚举性的作用

属性的枚举性会影响以下三个函数的结果:

for…in

Object.keys()

JSON.stringify

 

先看一个例子,按如下方法创建kxy对象:

function Person() {

    this.name = "KXY";

}

Person.prototype = {

    constructor: Person,

    job: "student",

};

 

var kxy = new Person();

Object.defineProperty(kxy, "sex", {

    value: "female",

    enumerable: false

 

});

 

其中用defineProperty为对象定义了一个名为”sex”的不可枚举属性

for(var pro in kxy) {

    console.log("kxy." + pro + " = " + kxy[pro]);

 

  }

 

可以看到除了”sex“之外的属性都遍历到了

只包含”name”属性,说明该方法只能返回对象本身具有的可枚举属性。

 

 

13、call();

call() 方法是与经典的对象冒充方法最相似的方法。它的第一个参数用作 this 的对象。其他参数都直接传递给函数自身。

function sayColor(sPrefix,sSuffix) {

    alert(sPrefix + this.color + sSuffix);

};

 

var obj = new Object();

obj.color = "blue";

 

 

sayColor.call(obj, "The ", "is a very nice color indeed.");

14、apply();

apply() 方法有两个参数,用作 this 的对象和要传递给函数的参数的数组。

function sayColor(sPrefix,sSuffix) {
    alert(sPrefix + this.color + sSuffix);
};

var obj = new Object();
obj.color = "blue";

sayColor.apply(obj, new Array("The ", " is a very nice color indeed."));

转载于:https://www.cnblogs.com/echo-HE/p/10185144.html

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值