create 创建一个对象

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

第一个参数为对象,对象为函数调用之后返回新对象的原型对象,第二个参数为对象本身的实例方法(默认不能修改,不能枚举)
obj.__proto__.a === 1      // true 

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

//创建一个可写的,可枚举的,可配置的属性p
obj2 = Object.create({}, {
  p: {
    value: 2,       // 属性值
    writable: true,     //  是否可以重写值
    enumerable: true,   //是否可枚举
    configurable: true  //是否可以修改以上几项配置
  }
});

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

注意: enumerable 会影响以下
for…in  遍历包括对象原型上属性

Object.keys()   只能遍历自身属性

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

defineProperty Object.defineProperty(object, prop, descriptor)定义对象属性

添加数据属性
var obj = {};

// 1.添加一个数据属性
Object.defineProperty(obj, "newDataProperty", {
    value: 101,
    writable: true,
    enumerable: true,
    configurable: true
});

obj.newDataProperty    // 101

// 2.修改数据属性
Object.defineProperty(obj, "newDataProperty", {
    writable:false
});

//添加访问器属性
var obj = {};

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


注意:  1.第一个参数必须为对象
        2.descriptor 不能同时具有 (value 或 writable 特性)(get 或 set 特性)。
        3.configurable 为false 时,不能重新修改装饰器

keys 遍历可枚举的属性,只包含对象本身可枚举属性,不包含原型链可枚举属性

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 遍历可枚举的属性值,只包含对象本身可枚举属性值,不包含原型链可枚举属性值

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 ) 方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(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方法实行的是浅拷贝,而不是深拷贝。

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

entries 分割对象

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 它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致

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

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

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

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

hasOwnProperty

方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性

let o = {a: 1 }

o.hasOwnProperty('a')   //true
o.hasOwnProperty('b')   //false   对象自身没有属性b
o.hasOwnProperty('toString');  //false  不能检测对象原型链上的属性


如何遍历一个对象的所有自身属性,例子:
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
    }
}

valueOf 需要返回对象的原始值

备注:js对象中的valueOf()方法和toString()方法非常类似,但是,当需要返回对象的原始值而非字符串的时候才调用它,尤其是转换为数字的时候。如果在需要使用原始值的上下文中使用了对象,JavaScript就会自动调用valueOf()方法。

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

// 给大家出一个题
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:返回数组对象本身
var array = ["CodePlayer", true, 12, -5];
array.valueOf() === array;   // true

// Date:当前时间距1970年1月1日午夜的毫秒数
var date = new Date(2013, 7, 18, 23, 11, 59, 230);
date.valueOf()     // 1376838719230

// Number:返回数字值
var num =  15.26540;
num.valueOf()     // 15.2654

// 布尔:返回布尔值true或false
var bool = true;
bool.valueOf() === bool    // true
// new一个Boolean对象
var newBool = new Boolean(true);
// valueOf()返回的是true,两者的值相等
newBool.valueOf() == newBool     // true
// 但是不全等,两者类型不相等,前者是boolean类型,后者是object类型
newBool.valueOf() === newBool     // false

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

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

// String:返回字符串值
var str = "http://www.365mini.com";
str.valueOf() === str       // true
// new一个字符串对象
var str2 = new String("http://www.365mini.com");
// 两者的值相等,但不全等,因为类型不同,前者为string类型,后者为object类型
str2.valueOf() === str2      // false
Set对象

Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用

语法:new Set([iterable])

iterable 如果传递一个可迭代对象,它的所有元素将被添加到新的 Set中;如果不指定此参数或其值为null,则新的 Set为空

new Set([1,2,3])
// output: Set(3) {1, 2, 3}
new Set([1,2,3]).size
// output: 3

Set方法

let setDemo = new Set();
1、add()
setDemo.add(5); // {1}

2、delete(value) // value将要删除的元素,删除成功返回true,否则返回false
setDemo.delete(5); // 返回true,删除成功

3、clear() // 用语清空Set所有元素
setDemo.add(5).add('aa');
setDemo.clear();
setDemo.size; // 0

4、has(value) // 判断指定value是否存在
setDemo.add('foo').add('aa');
setDemo.has('foo'); // true
setDemo.has(5); // false

5、entries() // 返回一个新的包含 [value, value] 形式的数组迭代器对象,value 是给定集合中的每个元素,迭代器 对象元素的顺序即集合对象中元素插入的顺序

let mySet = new Set();
mySet.add("foobar");
mySet.add(1);
mySet.add("baz");

let setIter = mySet.entries();

console.log(setIter.next().value); // ["foobar", "foobar"]
console.log(setIter.next().value); // [1, 1]
console.log(setIter.next().value); // ["baz", "baz"]

6、values()
语法:mySet.values() 或者 mySet.keys()
返回值:返回一个 Iterator  对象,这个对象以插入Set 对象的顺序包含了原 Set 对象里的每个元素
var mySet = new Set();
mySet.add('foo');
mySet.add('bar');
mySet.add('baz');

var setIter = mySet.values();

console.log(setIter.next().value); // "foo"
console.log(setIter.next().value); // "bar"
console.log(setIter.next().value); // "baz"

7、forEach() // 正常用法
Map对象

Map是一组键值对的结构,具有极快的查找速度。

语法:new Map([Array])

// mapkey是唯一的,多次对一个key设置value会进行覆盖
var m = new Map();

m.set('Adam', 67);

m.set('Adam', 88);

m.get('Adam'); // 88

Map的方法

var m = new Map(); // 空Map

1、set() //设置值
m.set('Adam', 67); // 添加新的key-value

m.set('Bob', 59);

2、has()
m.has('Adam'); // 是否存在key 'Adam': true

3、get() // 获取值
m.get('Adam'); // 67

4、delete() // 删除值
m.delete('Adam'); // 删除key 'Adam'

m.get('Adam'); // undefined