Web/10-ES6/02-ES5中的一些扩展.md
2018-04-02 10:21:27 +08:00

298 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## JSON 对象
1、js对象(数组) --> json对象(数组)
```javascript
JSON.stringify(obj/arr)
```
2、json对象(数组) --> js对象(数组)
```javascript
JSON.parse(json)
```
上面这两个方法是ES5中提供的。
我们要记住我们通常说的“json字符串”只有两种**json对象、json数组**。
`typeof json字符串`的返回结果是string。
## Object的扩展
ES5给Object扩展了一些静态方法常用的有2个我们接下来讲解。
### 方法一
```javascript
Object.create(prototype, [descriptors])
```
作用: 以指定对象为原型,创建新的对象。同时,第二个参数可以为为新的对象添加新的属性,并对此属性进行描述。
**举例1**:(没有第二个参数时)
```javascript
var obj1 = {username: 'smyhvae', age: 26};
var obj2 = {address:'shenzhen'};
obj2 = Object.create(obj1);
console.log(obj2);
```
打印结果:
![](http://img.smyhvae.com/20180401_2150.png)
我们发现obj1成为了obj2的原型。
**举例2**:(有第二个参数时)
第二个参数可以给新的对象添加新的属性。我们修改上面的代码尝试给obj2添加新属性`sex`
```javascript
var obj1 = {username: 'smyhvae', age: 26};
var obj2 = {address: 'shenzhen'};
obj2 = Object.create(obj1, {
sex: {//给obj2添加新的属性`sex`。注意,这一行的冒号不要漏掉
value: '男', //通过value关键字设置sex的属性值
writable: false,
configurable: true,
enumerable: true
}
});
console.log(obj2);
```
上方代码中我们通过第5行的sex给obj2设置了一个新的属性`sex`,但是要通过`value`来设置属性值第6行
设置完属性值后,这个属性值默认是不可修改的,要通过`writable`来设置。总而言是,这几个关键字的解释如下:
- `value`:设置属性值。
- `writable`标识当前属性值是否可修改。如果不写的话默认为false不可修改。
- `configurable`标识当前属性是否可以被删除。默认为false不可删除。
- `enumerable`:标识当前属性是否能用 for in 枚举。 默认为false不可。
### 方法二
> 这个方法有点难理解。
```javascript
Object.defineProperties(object, descriptors)
```
**作用**:为指定对象定义扩展多个属性。
代码举例:
```javascript
var obj2 = {
firstName : 'smyh',
lastName : 'vae'
};
Object.defineProperties(obj2, {
fullName : {
get : function () {
return this.firstName + '-' + this.lastName
},
set : function (data) { //监听扩展属性当扩展属性发生变化的时候自动调用自动调用后将变化的值作为实参注入到set函数
var names = data.split('-');
this.firstName = names[0];
this.lastName = names[1];
}
}
});
console.log(obj2.fullName);
obj2.firstName = 'tim';
obj2.lastName = 'duncan';
console.log(obj2.fullName);
obj2.fullName = 'kobe-bryant';
console.log(obj2.fullName);
```
- get :用来获取当前属性值的回调函数
- set :修改当前属性值得触发的回调函数,并且实参即为修改后的值
存取器属性setter,getter一个用来存值一个用来取值。
## Object的扩展
obj对象本身就自带了两个方法。格式如下
```javascript
get 属性名(){} 用来得到当前属性值的回调函数
set 属性名(){} 用来监视当前属性值变化的回调函数
```
举例如下:
```javascript
var obj = {
firstName : 'kobe',
lastName : 'bryant',
get fullName(){
return this.firstName + ' ' + this.lastName
},
set fullName(data){
var names = data.split(' ');
this.firstName = names[0];
this.lastName = names[1];
}
};
console.log(obj.fullName);
obj.fullName = 'curry stephen';
console.log(obj.fullName);
```
## 数组的扩展
> 下面讲的这几个方法,都是给数组的实例用的。
**方法1**
```javascript
Array.prototype.indexOf(value)
```
作用:获取值在数组中的第一个下标。
**方法2**
```javascript
Array.prototype.lastIndexOf(value)
```
作用:获取值在数组中的最后一个下标。
举例:
```javascript
var arr = [1, 3, 6, 2, 5, 6];
console.log(arr.indexOf(6));//2
console.log(arr.lastIndexOf(6));//5
```
**方法3**:遍历数组
```javascript
Array.prototype.forEach(function(item, index){})
```
举例:
```javascript
var arr = [1, 3, 6, 2, 5, 6];
arr.forEach(function (item, index) {
console.log(item, index);
});
```
打印结果:
![](http://img.smyhvae.com/20180402_0929.png)
**方法4**
```javascript
Array.prototype.map(function(item, index){})
```
作用:遍历数组返回一个新的数组,返回的是**加工之后**的新数组。
比如说有一个已知的数组arr1我要求让arr1中的每个素加10这里就可以用到map方法。举例
```javascript
var arr1 = [1, 3, 6, 2, 5, 6];
var arr2 = arr1.map(function (item, index) {
return item + 10; //让arr1中的每个元素加10
})
console.log(arr2);
```
打印结果:
![](http://img.smyhvae.com/20180402_0938.png)
**方法5**
```javascript
Array.prototype.filter(function(item, index){})
```
作用遍历过滤出一个新的子数组返回条件为true的值。
举例让找出数组arr1中大于4的元素返回一个新的数组。代码如下
```javascript
var arr1 = [1, 3, 6, 2, 5, 6];
var arr2 = arr1.filter(function (item, index) {
return item > 4; //将arr1中大于4的元素返回
})
console.log(arr2);
```
打印结果:
![](http://img.smyhvae.com/20180402_0951.png)
## 函数function的扩展bind()
> ES5中新增了`bind()`函数来改变this的指向。
```javascript
Function.prototype.bind(obj)
```
作用将函数内的this绑定为obj, 并将函数返回。
**面试题**: call()、apply()和bind()的区别:
- 都能改变this的指向
- call()/apply()是**立即调用函数**
- bind()绑定完this后不会立即调用当前函数而是**将函数返回**,因此后面还需要再加`()`才能调用。
PSbind()传参的方式和call()一样。
**分析**
为什么ES5中要加入bind()方法来改变this的指向呢因为bind()不会立即调用当前函数。
bind()通常使用在回调函数中因为回调函数并不会立即调用。如果你希望在回调函数中改变this不妨使用bind()。