对象属性名, 属性值同名, 可以简写, 只写一个
方法可以将 :function
省略不写
let x = 10;
let y = 20;
let obj = {
x,
y,
getPosition() {
return obj.x
}
}
对象属性名, 属性值同名, 可以简写, 只写一个
方法可以将 :function
省略不写
let x = 10;
let y = 20;
let obj = {
x,
y,
getPosition() {
return obj.x
}
}
let arr = ["春天", "夏天", "秋天", "冬天"]
let [spr, sum, aut, win] = arr // 完全解构
let [spr, , aut] = arr // 不完全解构
解构赋值只要两边解构相同就行,所以对象也是可以解构赋值的。但是需要注意的是对象和数组的解构有一个很大的区别:对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let obj = {
name: 'liao',
age: 18,
desc: '不错'
}
// 1. 基本解构
let { name, age, desc } = obj
// 2. 解构重命名 {变量名: 新的变量名}
let { name: myname, age: myage, desc: mydesc } = obj
// 3. 解构默认值
let { name, age, desc, girl = '小花' } = obj
// 4. 重命名 + 默认值
let { name, age, desc, girl: myGirl = '小花' } = obj
// 错误的写法
let x;
{x} = {x: 1};
// 正确的写法
let x;
({x} = {x: 1});
上面的例子中错误的原因是{x}被认为是一个块级作用域,导致解构失败,我们在使用解构要尽量避免这种大括号直接在行首的情况。
Map是一个带键的数据项的集合,就像object一样。但是它们最大的差别是Map允许任何类型的键。
new Map()
—- 创建mapmap.set(key,value)
—- 根据键存储值map.get(key)
—- 根据键来返回值,如果map中不存在对应的key,则返回undefinedmap.has(key)
—- 如果key存在则返回true,负责返回falsemap.delete(key)
—- 删除指定键的值map.clear()
—- 清空mapmap.size
—- 返回当前元素个数let map=new Map()
map.set('1','se') //根据键储存值 返回 Map(1) {"1" => "se"}
map.get('1') //根据键返回值,如果不存在返回undefind 返回se
map.has('1') //如果key存在返回true
map.delete('1') //删除指定键的值 返回true
map.clear() //清空 返回undefind
map.size //返回当前元素个数 返回0
let set = new Set([1, 2, 3, 3, 3, 4, 5]),
array = [...set]
console.log(array) // [1,2,3,4,5]
set.add("a")
添加一个元素set.delete("a")
删除一个元素set.size
获取元素的数量set.clear()
清除对象中的所有元素。set.has("a")
判断s对象中是否有某个元素,返回true或false//实例化一个Set对象
var set =new Set()
//Set对象通过add方法添加元素
set.add('3')
set.add('3') //注意3和'3'是不同的元素
set.add('apple')
console.log(s) //打印结果:Set(3) {3, "3", "apple"}
//使用delete可以删除元素
set.delete('apple')
console.log(s) //打印结果:Set(2) {3, "3"}
//清除set对象中的所有元素。
set.clear()
例:可以用多个add加入元素
set.add(1).add('哈').add('apple')
console.log(s) //Set(3) {1, "哈", "apple"}
//Set括号中数字代表set中有几个元素
用来判断一个数组是否包含一个指定的值
arr.includes(item)
用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
arr.concat(arr1,arr2)
可将伪数组转换为数组
Array.from(arr[, mapFn[, thisArg]])
arr
想要转换成数组的伪数组对象或可迭代对象。
mapFn
如果指定了该参数,新数组中的每个元素会执行该回调函数。
let arr = [1, 2, 3, 4, 5]
//把数组里的值都*100
let newArr = Array.from(arr, (i) => i * 100)
//去重 利用Set构造函数
let arr1 = [1,1,2,2,3,4,5,6,6,7,7]
let newArr1 = Array.from(new Set(arr1))
// [1, 2, 3, 4, 5, 6, 7]
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/from
arr.reduce(callback,[initialValue])
initialValue
)可选
如果没有提供,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供,则从索引0开始。
let arr = [1, 2, 3, 4, 5]
//计算所有元素和
arr.reduce( (prev, now) => previous + now ) // === 15
//自己指定初始值initialValue
arr.reduce( (prev, now) => previous + now , 100) // === 115
https://blog.csdn.net/qq_43340606/article/details/120765502
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
对象调用的方法 | 作用 | 返回值 |
---|---|---|
array.forEach(function(value, index, array){}) | 遍历 | 无 |
array.map(function(value, index, array){}) | 遍历&返回 | 新数组 |
array.filter(function(value, index, array){ return 条件 }) | 过滤&返回 | 新数组 |
array.every(function(value, index, array){ return 条件}) | 遍历&判断 | 布尔值 |
array.some(function(value, index, array){return 条件}) | 遍历&判断 | 布尔值 |
item是形参,如果是简单类型的形参的修改, 不会影响到原来值
let arr = [5, 6, 7, 8];
arr.forEach(function(item){
item = item + 1;
})
//arr没有变化
let arr2 = [
{ name: 'zs', age: 18 },
{ name: 'zs', age: 20 },
]
arr2.forEach(function(item) {
item.age = item.age + 1
})
//{ name: 'zs', age: 19 },
//{ name: 'zs', age: 21 },
let arr = [
{ name: 'zs', score: 100 },
{ name: 'ls', score: 99 },
{ name: 'li', score: 59 }
]
例:只保留名字,利用map()
方法返回新数组来做
let onlyNameArr = arr.map( item => item.name )
//onlyNameArr === ['zs','ls','li']
//如果想原数组只保留name,直接赋值即可arr = arr.map(...)
//箭头函数只有一个参数,并需要被return时,不需要加return和花括号(自动加了)
例:只保留60分以上的同学(包含的信息全都要),利用filter()
过滤并返回新数组
let MoreThan60 = arr.filter( item => item.score >= 60 )
//需要加return条件,会把符合条件的item加到新数组
//(并不是只加item.score,这只是用于判断)
例:比如需要判断所有学生分数是否都高于90
let isMoreThan90 = arr.every( item => item.score >=90 )
//isMoreThan90 === false
只要数组中有一个判断正确,则返回true
对象调用的方法 | 作用 | 返回值 |
---|---|---|
array.find(function(item, index) { return 条件 }) | 遍历 / 查找 | 找到的项 / undefined |
array.findIndex(function(item, index) { return 条件 }) | 遍历 / 查找 | 下标 / -1 |
find()
找第一个符合条件的项, 没找到会返回 undefined
,找所有符合条件的还是使用filter()
方法
findIndex()
找第一个符合条件项的下标, 没找到会返回 -1
push()
增加到最后一个
shift()
增加到第一个
splice()
传三个参数( 从哪开始删 , 删几个 , 要添加到数组的元素 )
第一个参数如果是负数,则为倒数第几个(从-1开始算,不是0,等价于arr.length – n)
要添加到数组的元素可以有多个item1, item2, …
pop()
删除最后一个
unshift()
删除第一个
splice()
根据索引指定删除某一个
继承一些需要重复使用的属性和方法
子构造函数.prototype = new 父构造函数()
注:原型链继承代码必须在创建实例对象之前
(实例对象在创建的那一刻起,其原型链就定下来了)
//定义Person构造函数
function Person() {}
Person.prototype.sayHi = function () {
console.log('hi~')
}
//定义Student构造函数
function Student() {}
//原型继承: 利用原型链, 继承于父级构造函数, 继承原型上的方法
Student.prototype = new Person()
//构造函数指向改回Student 否则会指向Person
Student.prototype.constructor = Student
let one = new Student()
one.sayHi() //继承了Person的sayHi方法
又称伪经典继承
原型链主要用于实例对象继承方法,构造函数用于实现实例对象属性的继承
二次调用父类构造函数
//定义Person构造函数
function Person(name) {
this.name = name
}
Person.prototype.sayHi = function () {
console.log('hi~')
}
//定义Student构造函数
function Student(name,id) {
//第二次调用父类构造函数
Person.call(this,name) // 实现属性的继承
this.id = id
}
//原型继承: 利用原型链, 继承于父级构造函数, 继承原型上的方法
//第一次调用父类构造函数
Student.prototype = new Person()
let one = new Student('Liao',1)
one.sayHi() //继承了Person的sayHi方法
通过借用构造函数来继承属性,通过原型链形式来继承方法,会解决2次调用父类函
数以及复用率的问题。
上例中,Student实例上有name了,原型__proto__
上不需要再有这些属性,利用Object.create()改造
Object.create(参数对象), Object.create 会创建一个新对象, 并且这个新对象的
__proto__
会指向传入参数对象
Object.create()
通过括号内的参数对象,创建一个新的对象出来,新对象的__proto__
指向参数对象
Student.prototype = Object.create(Person.prototype)
//效果等价于(本质还是有区别)
Student.prototype.__proto__ = Person.prototype
//定义Person构造函数
···
//定义Student构造函数
···
//利用fn.call()方法,Student已经继承了Person构造函数中的属性
//原型继承
Student.prototype = Object.create(Person.prototype)
Object.create()
以参数的对象, 作为新建对象的__proto__
属性的值, 返回新建的对象
显式绑定:使用call()、apply()、bind()方法将this进行强制绑定(硬绑定)。
call()
的语法和作用与apply()
方法只有一个区别,就是call()
方法接受的是一个参数列表,而apply()
方法接受的是一个包含多个参数的数组。
使用call()
方法会直接调用函数
function.call(this指向, 参数1, 参数2, ...)
this指向
:可选,用于修改函数this
指向,非严格模式下,指定null、undefined会自动指向全局window
参数1, 参数2, ...
传递给函数的实参
使用apply()
方法会直接调用函数
function.apply(this指向, [参数1, 参数2, ...])
this指向
:第一个参数用于修改函数this
指向
[参数1, 参数2, ...]
:一个数组或者类数组对象,其中的数组元素将作为单独的参数传给function函数。
使用bind()
方法不会不会不会直接调用函数
一个新函数
bind()
方法创建一个新的函数,在 bind()
被调用时,这个新函数的 this
被指定为 bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
function.bind(this指向, 参数1, 参数2, ...)
bf
是bind
创建出来的函数,bf
函数内的this
指向己经被强硬指向了bind
的参数obj
(即对象{name:'liao'}
)
function fn() {
console.log(this)
}
let obj = { name:'liao'}
let bf = fn.bind(obj)
bf()
//{name: 'liao'}
bind
方法返回的新函数和原函数长得一样,但是内存地址不一样
function fn(){}
let fn2 = fn.bind({}) //fn2是新函数,和fn内存地址不一样
console.log(fn == fn2) //false
call()
apply()
bind()
都可以替换修改函数this的指向call()
和 apply()
会立马调用函数, call()
参数需要一个个的传, apply()
传参必须是数组形式bind()
会得到一个新函数, 这个函数绑定死了 this
指向环境对象
指的是函数内部特殊的变量 this
,它代表着当前函数运行时所处的环境
在一个js文件或<script>
标签内,this始终指向window对象
console.log(this) // 全局环境,即window对象下,this -> window
严格模式下,函数中的this为undefined
function fun() {
console.log(this)
}
fun() // fun() 实际上是window.fun(), 所以this -> window
let obj = {
name: 'liao',
sayHi: function () {
console.log('hi~', this.name)
},
}
let name = 'Li'
obj.sayHi() //hi~ liao this ---> obj
function Person(){
this.name = "liao" // 这里的this -> obj对象
}
let obj = new Person()
在HTML事件句柄中,this指向了接收事件的HTML元素
<button onclick="console.log(this)">点我</button>
this --> button
call / apply / bind
1.在函数调用中,this指向调用它的对象。
2.在构造函数中,this指向实例化对象。
3.在事件体中,this指向事件源。
4.箭头函数中,没有this
5.其他情况中,this指向window
typeof
用于判断简单数据类型
例外 null
typeof null //object
typeof
检测复杂数据类型 结果是object
例外 function
typeof function //function
用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上,存在返回true,不存在返回false
实例对象 instanceof 构造函数
instanceof
判断是否通过该构造函数创建不准确
let arr = []
arr ==> Array.prototype ==> Object.prototype ==> null
console.log(arr instanceof Array) // true
console.log(arr instanceof Object) // true
对象 有 __proto__
属性,指向原型对象,原型对象也是对象,也有__proto__
属性,指向原型对象的原型对象,这样形成的一环一环的链式结构,就是原型链。
老祖宗 function Object()
function Person() {}
let per = new Person()
//原型链:
per.__proto__ ==> Person.prototype
Person.prototype.__proto__ ==> Object.prototype
Object.prototype.__proto__ ==> null
简单理解:沿着对象的原型链来查找
Object.prototype
undefined