ES6给我们带来的新特性包括:简洁的表示法、属性名方法可以是表达式、Object.is( ) 函数、Object.assgin( ) 函数、Object.setPrototypeOf( ) 函数,Object.getPrototypeOf() 函数;此外还拓展了:严格相等和抽象相等的区别、javascript面向对象的实现
对象的传统表示法
1 | let person = { |
- 变量person就是一个对象,对象含有name属性和一个say方法。表示法是用键值对的形式来表示,这就是传统的表示法。
ES6中的简洁写法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var name = "Zhangsan";
var age = 12;
//传统的属性写法
var person = {
"name":name,
"age":age
};
console.log(person);
//结果:{name: "Zhangsan", age: 12}
//ES6的属性写法
var person = {name,age};
console.log(person);
//结果:{name: "Zhangsan", age: 12}对象的方法的简写表示法
1
2
3
4
5
6
7
8
9
10
11
12
13//传统的表示法
var person = {
say:function(){
alert('这是传统的表示法');
}
};
//ES6的表示法
var person = {
say(){
alert('这是ES6的表示法');
}
}; - 下面是一个实际的例子。
1
2
3
4
5
6
7
8
9
10
11
12let birth = '2000/01/01';
const Person = {
name: '张三',
//等同于birth: birth
birth,
// 等同于hello: function ()...
hello() { console.log('我的名字是', this.name); }
};属性表达式
- 在表示法上除了这点改进以外,还有另外一个新特点:用字面量定义一个对象的时候,可以用表达式作为对象的属性名或者方法名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var f = "first";
var n = "Name";
var s = "say";
var h = "Hello";
var person = {
[ f+n ] : "Zhang",
[ s+h ](){
return "你好吗?";
}
};
console.log(person.firstName);
//结果:Zhang
console.log(person.sayHello());
//结果:你好吗? - 意上面person对象的定义,其中属性名和方法名都是用中括号[ ]包裹着,里面都是一个字符串相加的表达式,这就告诉我们,用字面量(大括号{ })定义对象的时候,属性名和方法名可以是一个表达式,表达式的运算结果就是属性名或者方法名。这点改进会使得对象在实际开发中的使用变得更加的灵活方便
ES6为对象新增的函数。
Object.is( )函数
- ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。
- ES6 提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
1 严格相等和抽象相等1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22var str = '12';
var num = 12;
//抽象相等
str == num;
//结果:true
//严格相等
str === num;
//结果:false
````
- Object.is()函数,它的作用也跟严格相等一样
```bash
var str = '12';
var num = 12;
var num2 = 12;
Object.is(str,num);
//结果:false
Object.is(num2,num);
//结果:true - 参数类型不一样str和num进行比较,得到的结果是false。变量类型和值都一样的num和num2进行比较,得到的结果是true。
Object.assign()函数
- 将源对象的属性拷贝到目标对象上
1
2
3
4
5
6
7
8
9
10
11//这个充当目标对象
let target = {"a":1};
//这个充当源对象
let origin = {"b":2,"c":3};
Object.assign(target,origin);
//打印target对象出来看一下
console.log(target);
//结果 {a: 1, b: 2, c: 3} - 注意输出的结果,target对象已经不是{ a:1 }了,而是变成了{a: 1, b: 2, c: 3},经过Object.assign( )函数的处理,源对象的属性被添加到了target对象上。这就是Object.assign( )函数的作用。
- Object.assign( )函数的参数还可以是多个(至少是两个)
1
2
3
4
5
6
7
8
9
10
11
12
13
14//这个充当目标对象
let target = {"a":1};
//这个充当源对象
let origin1 = {"b":2,"c":3};
//这个充当源对象
let origin2 = {"d":4,"e":5};
Object.assign(target,origin1,origin2);
//打印target对象出来看一下
console.log(target);
//结果 {a: 1, b: 2, c: 3, d: 4, e: 5} - 赋值过程中,对象的属性出现了相同的,后面的属性值就会覆盖前面的属性值
1
2
3
4
5
6
7
8
9
10
11
12
13
14//这个充当目标对象
let target = {"a":1};
//这个充当源对象
let origin1 = {"a":2};
//这个充当源对象
let origin2 = {"a":3};
Object.assign(target,origin1,origin2);
//打印target对象出来看一下
console.log(target);
//结果 {a: 3}如果该参数不是对象,则会先转成对象,然后返回。
1
typeof Object.assign(2) // "object"
- 由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。
1
2Object.assign(undefined) // 报错
Object.assign(null) // 报错 - 如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefined和null不在首参数,就不会报错。
1
2
3let obj = {a: 1};
Object.assign(obj, undefined) === obj // true
Object.assign(obj, null) === obj // true - 巧妙利用Object.assign( )函数的功能,我们可以完成很多效果,比如:给对象添加属性和方法,克隆对象,合并多个对象,为对象的属性指定默认值。
ES6原型操作 Object.setPrototypeOf()(写操作)、Object.getPrototypeOf()(读操作)、Object.create()(生成操作)代替。
Object.getPrototypeOf( )函数
- 函数作用:获取一个对象的prototype属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//自定义一个Person类(函数)
function Person(){
}
//函数都有一个预属性prototype对象
Person.prototype = {
//给prototype对象添加一个say方法
say(){
console.log('hello');
}
};
//实例化Person对象,赋值给变量allen
let allen = new Person();
//调用类的say方法
allen.say();
//结果:打印出hello
//获取allen对象的prototype属性
Object.getPrototypeOf(allen);
//结果:打印{say:function(){.....}} - 前面部分都是关于面向对象的实现。把函数Person用new关键字调用,这个时候函数Person就相当于构造函数或者说是一个类,实例化后是一个对象,这个对象会继承Person类的prototype的属性和方法。上述例子中,也就是对象allen继承了一个say方法,可以直接调用
- 如果你想看看prototype中还有哪些方法和属性,那么,你就可以使用Object.getPrototypeOf( )函数来获取,参数就是allen对象,最后的结果也如我们所料,确实打印出了我们刚开始定义好的内容:一个对象,含有一个say方法{say:function(){…..}}
- 那么,如果我想为这个对象修改prototype的内容,要怎么办?这个时候,我们可以用ES6给我们的另一个方法 Object.setPrototypeOf()函数
Object.setPrototypeOf()函数
- 函数作用:用来设置一个对象的prototype对象,返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30// 格式
Object.setPrototypeOf(object, prototype)
//自定义一个Person类(函数)
function Person(){
}
//函数都有一个预属性prototype对象
Person.prototype = {
//给prototype对象添加一个say方法
say(){
console.log('hello');
}
};
//实例化Person对象,赋值给变量allen
let allen = new Person();
//调用类的say方法
allen.say();
//结果:打印出hello
//使用Object.setPrototypeOf
Object.setPrototypeOf(
allen,
{say(){console.log('hi')}
});
//再次调用类的say方法
allen.say();
//结果:打印出hi - 新手如果没有接触过面向对象的话,读起来一定会懵逼,这里要拓展一下javascript的面向对象
javascript的面向对象
- Javascript本身不是一种面向对象的编程语言,在ES5中,它的语法中也没有class(类的关键字),但是,开发者可以利用对象的原型prototype属性来模拟面向对象进行编程开发。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//构造函数模拟创建一个Dog类
function Dog(name){
this.name = name;
}
//把一些属性和方法,定义在prototype对象上
Dog.prototype = {
"type":"动物",
"say":function(){
alert("名字叫"+this.name);
}
};
//实例化
var dog = new Dog('旺财');
//调用say方法
dog.say();
//结果:名字叫旺财 - 上面的案例告诉我们,模拟面向对象编程有几个关键步骤:1、构造函数;2、给prototype对象添加属性和方法;3、实例化;4、通过实例化后的对象调用类的方法或者属性。
扩展运算符
1
2
3
4//扩展运算符
let {a,b,...c} = {a:'text',b:'kill',c:'ddd',d:'eee'}
console.log(a,b,c)
// text kill {c: "ddd", d: "eee"}