夯实基础,彻底掌握js的核心技术(四):ES5、ES6对象方法详解

ES5 Object 对象方法扩展

ES5给Object扩展了一些静态方法,常用的2个

  1. Object.create(prototype,[descriptors])

作用:以指定对象为原型创建新的对象<br />为新对象指定新的属性,并对属性进行描述

  • value: 指定值
  • writable: 标识当前属性值是否是可修改的,默认为false
  • configurable: 标识当前属性是否可以被删除,默认为false
  • enumerable: 标识当前属性是否能用 for in 枚举 默认为false
  1. Object.defineProperties(object, descriptors)

作用: 为指定对象定义扩展多个属性

  • get: 用来获取当前属性值的回调函数
  • set: 修改当前属性值的触发的额回调函数,并且实参即为修改后的值
  • 存取器属性:setter,getter一个用来存值,一个用来取值

ES5数组的扩展

  1. Array.prototype.indexOf(value) : 得到值在数组中的第一个下标
  2. Array.prototype.lastIndexOf(value): 得到值在数组中的最后一个下标
  3. Array.prototype.forEach(function(item, index){}): 遍历数组
  4. Array.prototype.map(function(item, index){}): 遍历数组返回一个新的数组,返回加工后的值
  5. Array.prototype.filter(function(item, index){}): 遍历过滤出一个新的子数组,返回条件为true的值
var arr = [2, 4, 3, 2, 6, 5, 4]
console.log(arr.indexOf(4)) //1
console.log(arr.lastIndexOf(4)) // 7

arr.forEach(function(item, index) {
    console.log(item, index)
})

var arr1 = arr.map(function(item, index) {
return item + 10
})
console.log(arr1) // [12, 14, 13, 12, 16, 15, 14]

var arr2 = arr.filter(function(item, index) {
return item > 3
})
console.log(arr2)  //[4, 6, 5, 4]

ES5函数的扩展

  1. Function.prototype.bind(obj);

作用:将函数内的this绑定为obj,并并将函数返回<br />bind的点: 绑定完this不会立即调用当前函数,而是将函数返回<br />bind传参数的方式同call一样

  1. 区别bind()与call() apply()

都能指定函数中的this<br />call()/apply()是立即调用函数<br />bind()是将函数返回

var obj = {username: 'lanfeng'}
function foo(data) {
    console.log(this, data)
}
foo(); //window

//传人参数的形式
foo.call(obj, 33) // 直接从第二个参数开始,依次传入
foo.apply(obj, [33]) //第二个参数必须是数组,传入参数放在数组里
//bind的点: 绑定完this不会立即调用当前函数,而是将函数返回
foo.bind(obj)()

// ----------
var obj = {username: 'lanfeng'}
setTimeout(function() {
    console.log(this) //obj
}.bind(obj), 1000)

let、const 关键字

let 关键字

  1. 作用:与var类似,用于声明一个变量
  2. 特点:<br />
  • 在块作用域内有效
  • 不能重复声明
  • 不会预处理,不存在提升
  1. 应用:
  • 循环遍历加监听
  • 使用let取代var趋势
let username = 'lanfeng'

#### const 

1. 作用:定义一个常量
1. 特点:
- 不能修改
- 其它特点同let
3. 应用: 

保存不用改变的数据

### ES6箭头函数

1. 作用: 定义匿名函数
1. 基本语法:
- 没有参数:()=> console.log('xxxx') , 小括号不能省略
- 一个参数:i => i+2
- 大于一个参数:(i, j) => i + j
- 函数体不用大括号:默认返回结果
- 函数体如果有多个语句,需要用{}包围,若有需要返回的内容,需要手动返回
- 使用场景: 多用来定义回调函数
3. 箭头函数的特点:
- 简洁
- 箭头函数没有自己的this,箭头函数的this不是调用的时候决定的,而是定义的时候处在的对象就是它的额this
- 扩展理解:外层函数的this看外层是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window
```javascript
let fun = () => console.log('我是箭头函数')
fun();

//形参的情况
// 1. 没有形参的时候,小括号不能省略
let fun1 = ()=> console.log('我是箭头函数')

// 2. 只有一个形参的时候,小括号可以省略
let fun2 = (a) => console.log(a)
fun2('langfeng')

//3. 两个及两个以上的形参的时候,小括号不能省略
let fun3 = (x, y) => console.log(x, y)
fun3(25, 36)

//  函数体的情况
// 1. 函数体只有一条语句或者是表达式的时候,大括号可以省略,会自动返回语句执行的结果或者是表达式的结果
    let fun4 = (x, y) => x+y
  console.log(fun4(24, 36))
// 2. 函数体不止一条语句或者是表达式的额情况,{}不可以省略
let fun5 = (x, y) => {
  console.log(x, y)
  return x + y  
}
console.log(fun5(35, 49))


ES6 promise对象

  1. 理解:
  • promise对象:代表了未来某个将要发生的事件(通常是一个异步操作)
  • 有了promise对象,可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
  • ES6的promise是一个构造函数,用来生成promise实例
  1. 创建promise基本步骤(2步)
  • 创建promise对象
let promise = new Promise((resolve, reject)) => {
//初始化promise状态为pending
//执行异步操作
if(异步操作成功) {
resolve(value)  //修改promise的状态为fullfilled
} else {
reject(errMsg) //修改promise的状态为rejected
}
}
  • 调用promise的then()
promise.then(
    result => console.log(result),
  errorMsg => alert(errorMsg)
)
  1. promise对象的三个状态
  • pending: 初始化状态
  • fullfilled: 成功状态
  • rejected: 失败状态

ES6中的Symbol

  1. 概念:ES6中的添加了一种原始数据类型symbol(已有的原始数据类型:String, Number, boolean, undefined, null,Object)
  2. 特点:
  • symbol属性对应的值是唯一的,解决命名冲突问题
  • symbol值不能与其它数据进行计算,包括同字符串拼串
  • for in, for of遍历时不会遍历symbol属性
  1. 使用:
  • 调用symbol函数到symbol值
let symbol = Symbol();
let obj = {}
obj[symbol] = 'hello'
  • 传参标识
let symbol = Symbol('one')
let symbol2 = Symbol('two')
console.log(symbol) // Symbol('one')
console.log(symbol2)  // Symbol('two')
  • 内置Symbol值

除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法<br />Symbol.iterator<br />对象的Symbol.iterator属性,指向该对象的默认遍历器方法<br />

ES6中的async函数

  1. 概念:真正意义上去解决异步回调的问题,同步流程表达异步操作
  2. 本质:Generator的语法糖
  3. 语法:
async function foo() {
    await 异步操作
  await 异步操作
}
  1. 特点:
  • 不需要Generator去调用next方法,遇到await等待,当前的异步操作完成就往下执行
  • 返回的总是Promise对象,可以用then方法进行下一步操作
  • async 取代Generator函数的星号*,await取代Generator的yield
  • 语意上更为明确,使用简单

ES6中的class类

  1. 通过class定义类实现类的继承
  2. 在类中通过constructor定义构造函数
  3. 通过new来创建类的实例
  4. 通过extends来实现类的继承
  5. 通过super调用父类的构造方法
  6. 重写从父类中继承的一般方法
class Person {
  //类的构造方法
    constructor(name, age) {
    this.name = name;
    this.age = age
  }
  showName() {
    console.log(this.name)
  }
}
let person = new Person('kobe', 39)
console.log(person)
console.log(person.showName())

//子类
class StartPerson extends Person {
    constructor(name, age) {
    super(); //调用父类构造方法
  }
}
let startPerson = new StartPerson('lanfeng', 28, 10000)
console.log(startPerson.showName()) // lanfeng

ES6中字符串的扩展

  1. includes(str): 判断是否包含指定的字符串
  2. startsWith(str): 判断是否以指定字符串开头
  3. endsWith(str): 判断是否以指定字符串结尾
  4. repeat(count): 重复指定次数

ES6中数组扩展方法

  1. Array.from(v): 将伪数组对象或者可遍历转换为真熟组
  2. Array.of(v1, v2, v3): 将一系列值转换成数组
  3. find(function(value, index, arr) { return true }) : 找出第一个满足条件返回true的元素
  4. findIIndex(function(value, index, arr) { retturn true }): 找出第一个满足条件返回true的元素下标

ES6中对象扩展方法

  1. Object.is(v1, v2)

判断2个数据是否完全相等

  1. Object.assign(target, source1, source2...)

将源对象的属性复制到目标对象上

  1. 直接操作proto属性

let obj2 = {}<br />obj2._ proto_ = obj1<br />

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

数组和对象的克隆

  1. 对象复制
let obj = { username: 'lanfeng'}
let obj1 = obj; // obj1 复制了obj在堆内存的引用
  1. 常用的拷贝技术
  • arr.concat():数组浅拷贝
  • arr.slice(): 数组浅拷贝
  • JSON.parse(JSON.stringify(arr/obj)) : 数组或对象深拷贝
  • 浅拷贝包含函数数据的对象/数组
  • 深拷贝包含函数数据的对象/数组

拷贝数据:

  1. 基本数据类型:拷贝后会生成一份新的数据,修改拷贝后的数据不会影响原数据
  2. 对象/数组:拷贝后不会生成新的数据,而是拷贝的是引用,修改拷贝以后的数据会影响原来的数据
//拷贝数组/对象,没有生成新的数组而是复制了一份引用
let obj = {username: 'lanfeng', age: 30}
let obj1 = obj
console.log(obj1) // {username: "lanfeng", age: 30} 
obj1.username = 'qiuqiu'
console.log(obj.username) //qiuqiu

拷贝数据的方法:

  • 直接赋值给一个变量. // 浅拷贝
  • Object.assgin()
  • Array.prototype.concat() // 浅拷贝
  • Array.prototype.slice() // 浅拷贝
  • JSON.parse(JSON.stringfy()) //深拷贝,拷贝的数据里面不能有函数数据,处理不了
let obj = {username: 'lanfeng'}
let obj2 = Object.assign(obj)
console.log(obj2) // {username: "lanfeng"}
obj2.username = 'qiuqiu'
console.log(obj) // {username: "qiuqiu"}

// ---------
let arr = [1, 3, {username:'lanfeng'}]
let arr2 = arr.concat()
// console.log(arr2) //[1, 3, {username:'lanfeng'}]
arr2[1] = 'a'
console.log(arr)  //[1, 3, {username:'lanfeng'}]
arr2[2].username = 'qiuqiu'
console.log(arr)  //[1, 3, {username:'qiuqiu'}]

// ------
let arr = [1, 3, {username:'lanfeng'}]
let arr4 = JSON.parse(JSON.stringify(arr))
arr4[2].username = 'lanfeng2'
console.log(arr)  // [1, 3, {username:'lanfeng'}]


浅拷贝(对象/数组)<br />特点:拷贝的引用,修改拷贝以后会影响原数据<br />深拷贝(深度克隆):拷贝的时候生成新的数据,修改拷贝以后不会影响原数据

在实现深拷贝之前,我们需要掌握以下知识点<br />如果判断数据类型:

  1. typeof返回的数据类型:String, Number, Boolean, undefined, object,function
  2. Object.prototype.toString.call(obj)
let result = 'abcd'
result = null;
result = [1, 3]
console.log(Object.prototype.toString.call(result).slice(8, -1)); // Array

for in 循环 对象(属性名) 数组(下标)

let obj = {username: 'lanfeng', age: 39}
for(let i in obj) {
    console.log(i)
}
let arr = [1,3, 'abc']
for(let i in arr) {
    console.log(i)
}

定义检测数据类型的功能函数

function checkType(target) {
    return Object.prototype.toString.call(result).slice(8, -1)
}

实现深度克隆 ,一般针对数组或者对象

function checkedType(target) {
    return Object.prototype.toString.call(target).slice(8, -1)
}

function clone(target) {
    // 首先判断拷贝数据的类型
  //
  let result, targetType = checkedType(target);
  if(targetType === 'Object') {
    result = {};
  } else if(targetType === 'Array') {
    result = [];
  } else {
    return target
  }
  
  // 遍历目标数据
  for(let i in target) {
    // 获取遍历数据结构的每一项值
    let value = target[i]
    
    // 判断目标结构里的每一项值是否存在对象或数组
    if(checkedType(value) === 'Object' || checkedType(value) === 'Array') {
        // 继续遍历获取到value值
      result[i] = clone(value)
    } else {
      // 获取都的value值是最基本的数据类型或者是函数
        result[i] = value
    }
  }
  return result 
}
let arr3 = [1,2, {username: 'lanfeng'}]
let arr4 = clone(arr3)
console.log(arr4)
arr4[2].username = 'qiuqiu'
console.log(arr3, arr4)

运行结果如下图:<br />

ES6中的set、map容器

  1. Set容器: 无序不可重复的多个value的集合体
  • Set()
  • Set(array)
  • add(value)
  • delete(value)
  • has(key)
  • clear()
  • size
let set = new Set([1,2,4,2,5])
console.log(set)
  1. Map容器:无序的key不重复的多个key-value的集合体
  • Map()
  • Map(array)
  • set(key, value) //添加
  • get(key)
  • delete(key)
  • has(key)
  • clear()
  • size

ES6中的for of

for (let value of target) {} 循环遍历

  • 遍历数组
  • 遍历Set
  • 遍历Map
  • 遍历字符串
  • 遍历伪数组
let set = new Set([1,2,4,5,2,3])
let arr = []
for(let i of set) {
    arr.push(i)
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • ES5 严格模式 1. 理解: * 除了正常运行模式(混杂模式),ES5添加了第二种运行模式:"严格模式"(str...
    BJ000阅读 761评论 0 1
  • ES5 1、严格模式 *理解 1、除了正常运行的模式(混杂模式),es5添...
    Shy啊阅读 2,380评论 0 1
  • ECMAScript理解 它是一种由ECMA组织(前身为欧洲计算机制造商协会)制定和发布的脚本语言规范 而我们学的...
    我本无常阅读 428评论 0 0
  • ECMAScript理解 它是一种由ECMA组织(前身为欧洲计算机制造商协会)制定和发布的脚本语言规范 而我们学的...
    咻咻咻滴赵大妞阅读 4,560评论 0 3
  • 什么是JavaScript JavaScript一种动态类型、弱类型、基于原型的客户端脚本语言,用来给HTML网页...
    zhaodadaya阅读 8,519评论 0 2