DOM操作的对象是文档,所以DOM和浏览器没有关系,因为它关注网页本身的内容 。
BOM:brower object model,浏览器对象模型
提供独立于内容面和浏览器窗口进行交互的对象。
管理窗口与窗口之间的通讯,核心对象是window-->location(用于url相关的操作),history(用于历史相关的操作),navigator(包含了浏览器相关的信息)
BOM是控制浏览器行为的api,DOM是一个页面结构的api。
与数组相似,但是没有数组常见的方法属性。
function func () {
console.log(arguments)
}
func(1, 2, 3, 4, 5, 5)
function func () {
console.log(arguments)
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i])//1 2 5
}
}
func(1, 2, 5)
使用call和apply,使用forEach方法(数组的方法)
call:调用一个对象的一个方法,以另一个对象替换当前的对象。
function fun1 () {
Array.prototype.forEach.call(arguments, (item) => {
console.log(item)//1 2 3
})
}
fun1(1, 2, 3)
使用Array.from(),对一个类数组,创建一个新的数组实例。
function fun2 () {
const arr = Array.from(arguments)
console.log(arr)//(3) [1, 2, 3]
arr.forEach((item) => {
console.log(item)// 1 2 3
})
arr.push(7)
console.log(arr)//(4) [1, 2, 3, 7]
}
fun2(1, 2, 3)
function fun3 () {
const arr1 = [...arguments]
console.log(arr1)//(3) [7, 17, 27]
//把数据遍历出来
arr1.forEach((item) => {
console.log(item)//7 17 27
})
}
fun3(7, 17, 27)
类本身指向就是构造函数,类的数据类型就是函数。
function Person (name) {
this.name = name
}
var obj = new Person('zz')
判断构造函数的prototype属性是否出现在对象的原型链的任何位置。
function Person (name) {
this.name = name
}
var obj = new Person('zz')
// obj是属于Person这个类的
console.log(obj instanceof Person)//true
// obj1不属于Person,因为它不是通过这个构造函数实例化构造出来的
var obj1 = {}
console.log(obj1 instanceof Person)//false
console.log(obj)
// 可以通过
console.log(obj.constructor)//ƒ Person (name) {this.name = name}
// 也可以通过
console.log(obj.__proto__.constructor)//ƒ Person (name) {this.name = name}
不是很好,因为这个是作为这个对象的属性来进行操作的,这个属性是可以被修改
// 会更改,这里更改为Array
obj.__proto__.constructor = Array
console.log(obj.__proto__.constructor)//ƒ Array() { [native code] }
回调函数种有三个参数,第一个参数数组的遍历值(数组的元素值),第二个参数数组的索引值,第三个参数是数组的本身。
//map
var arr = [1, 2, 3]
arr.map((item, index, arr) => {
console.log(item)//数组的遍历值
console.log(index)//数组的索引值
console.log(arr)//数组的本身
// 不会更改原数组
item *= 2//改数组的遍历值,不会
arr[0] = 10//改数组的本身,就会进行更改
})
console.log(arr)
//forEach
var arr = [1, 2, 3]
arr.forEach((item, index, arr) => {
console.log(item)//数组的遍历值
console.log(index)//数组的索引值
console.log(arr)//数组的本身
// 不会更改原数组
item *= 2//改数组的遍历值,不会
arr[0] = 10//改数组的本身,就会进行更改
})
console.log(arr)
//map
var arr = [1, 2, 3]
var result = arr.map((item, index, arr) => {
item *= 2
arr[0] = 10
// 会返回新数组,用新数组存放并且返回
return index * 2
})
console.log(arr)//(3) [10, 2, 3]
console.log(result)//(3) [0, 2, 4]
//forEach
var arr = [1, 2, 3]
var result = arr.forEach((item, index, arr) => {
item *= 2
arr[0] = 10
return index * 2
})
console.log(arr)//(3) [10, 2, 3]
console.log(result)//undefined
map分配内存空间存储新数组,并且返回;forEach不会返回执行结果,返回undefined。
ES6新增遍历方式,可以遍历数组和对象,并且能返回数组的元素和对象的属性值;而不像for循环通过下标或者属性名。
是允许遍历一个含有iterator接口的数据结构(数组,对象等)并且返回各项的值。
需要遍历的对象是类数组对象,可以使用数组的Array.from将类数组转为数组
var obj = {
0: 1,
1: 2,
2: 9,
length: 3
}
obj = Array.from(obj)
for (let value of obj) {
console.log(value)// 1 2 9
}
如果需要遍历的对象不是类数组,需要给对象添加一个Symbol.iterator属性,让它指向迭代器。
1.创建一个指针对象,指向当前数据结构的起始位置
2.第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员
3.第二次调用指针对象的next方法,指针就指向数据结构的第二个成员
4.不断调用指针对象的next方法,直到它指向数据结构的结束位置
每一次调用next方法,都会返回数据结构的当前成员的信息,返回一个包含value和done两个属性的对象
value:当前成员的值;done:是一个布尔值,表示遍历是否结束。
var person = {
name: 'zz',
age: 10,
height: 100
}
// 1.指针对象
person[Symbol.iterator] = function () {
// 2.第二个成员
// 拿到对象中的所有key值,返回的是数组
// this谁调用了这个函数就指向谁(person)
var keys = Object.keys(this)
// 定义数组的下标值
var index = 0
return {
next () {
if (index < keys.length) {
return { value: person[keys[index++]], done: false }
} else {
// 遍历完了
return { value: undefined, done: true }
}
}
}
}
for (let value of person) {
console.log(value)//zz 10 100
}
var arr = [1, 2, 3, 4]
不会改变原数组,没有返回值。
// 三个参数,遍历值,索引值,数组本身
let resultFor = arr.forEach((item, index, arr) => {
// console.log(item)
// console.log(index)
// console.log(arr)
return index * 2
})
console.log(resultFor)//undefined
不会改变原数组,有返回值。
let resultMap = arr.map((item, index, arr) => {
// console.log(item)
// console.log(index)
// console.log(arr)
return index * 2
})
console.log(resultMap)//(4) [0, 2, 4, 6]
可以遍历数组也可以过滤数组。有返回值,返回包含符合条件的元素的数组。
let resultFilter = arr.filter((item) => {
console.log(item)//1 2 3 4
return item > 3
})
console.log(resultFilter)//[4]
返回的是数组的元素,对象的属性值。但是不能遍历普通的对象。
for (let value of arr) {
console.log(value)//1 2 3 4
}
接收一个函数,作为一个累加器。
//其他方法的累加比较麻烦
var total = 0
for (let value of arr) {
total += value
console.log(value)//1 2 3 4
console.log(total)//10
}
//reduce方法
// 函数有两个参数是必传参数,第一个计算之后返回的值或者初始值;第二个当前的元素
let resultReduce = arr.reduce((pre, item) => {
// 初始值pre=0
console.log('pre', pre)
console.log('item', item)
return pre + item
}, 0)
// let resultReduce把最后相加的值输出出来
console.log(resultReduce)//10
默认对应着一个空对象(没有我们指定的方法和属性),这个空对象就是原型对象。每一个prototype都是不相等的。
function Person () {
}
console.log(Person.prototype)
每一个函数都有一个prototype属性,就是显示原型
每一个实例对象都会有一个__proto__,就是隐式原型
实例对象的隐式原型等于对应的构造函数的显示原型的值
function Fun () {//内部语句:Fun(this).prototype={}
}
console.log(Fun.prototype)
var fun = new Fun()//内部语句:fun(this).__proto__=Fun.prototype
console.log(fun.__proto__)
console.log(Fun.prototype === fun.__proto__)//true
函数的prototype属性,在定义函数是自动添加的,默认值是一个空对象
对象的__proto__属性,创建对象的时候自动添加的,默认值是构造函数的prototype属性
查找对象的属性(方法)。
// 创建构造函数
function Fun () {//内部语句:Fun(this).prototype={}
this.test1 = function () {
console.log('test1()')
}
}
// 添加test2方法
Fun.prototype.test2 = function () {
console.log('test2()')
}
console.log(Fun.prototype)//{test2: ƒ, constructor: ƒ}
// 实例化对象
var fun = new Fun()//内部语句:fun(this).__proto__=Fun.prototype
// 打印test1
fun.test1()//test1()
fun.test2()//test2()
console.log(fun.toString())//[object Object]
//toString()属于Object原型对象的方法
fun.test3()//fun.test3 is not a function
按照步骤路线查找即可
// 创建构造函数
function Person (name) {
this.name = name
}
修改原型没有影响。
//1.修改原型
Person.prototype.getName = function () {
console.log(this.name)
}
// 实例化对象
var p = new Person('zz')
console.log(p.__proto__ === Person.prototype)//true
console.log(p.__proto__ === p.constructor.prototype)//true
重写有影响,需要把constructor指向回来。
Person.prototype = {
getName: function () {
console.log(this.name)
}
}
//直接给Person的原型对象用对象进行赋值时,p的构造函数指向根构造函数Object
var p = new Person('zz')//内部语句:p的隐式原型等于Person的显示原型p(this).__proto__=Person.prototype
console.log(p.__proto__ === Person.prototype)//true
// 指向了Object,需要把constructor指向回来
console.log(p.constructor)//ƒ Object() { [native code] }
console.log(p.__proto__ === p.constructor.prototype)//false
//指向回来
p.constructor = Person
console.log(p.__proto__ === p.constructor.prototype)//true
for...of遍历获取对象的键值,for...in获取对象的键名。
function Person (name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
// 构造函数原型上面去定义一个属性
Person.prototype.height = 111
var p = new Person('zz', 7, 'nan')
// 写iterater属性,获取Person,返回对象过去
p[Symbol.iterator] = function () {
var keys = Object.keys(this)
var index = 0
return {
next () {
if (index < keys.length) {
return { value: p[keys[index++]], done: false }
} else {
return { value: undefined, done: true }
}
}
}
}
// 遍历
for (let value of p) {
console.log(value)//zz 7 nan
}
for (let key in p) {
console.log(key)//name age sex height
}
for...in会遍历对象的整个原型链,性能很差。
for...of只会遍历当前对象。
对于数组的遍历,for...in返回数组中所有可枚举的属性,for...of返回数组的下标对应的属性值。
var arr = [1, 2, 3, 4]
console.log(arr)//(4) [1, 2, 3, 4]
for (let i of arr) {
console.log(value)//1 2 3 4
}
// for...in数组原型上面添加属性的话,也会遍历出来
Array.prototype.value = 50
for (let i in arr) {
console.log(i)//0 1 2 3 value
}
是数组,但有下标,像对象一样。
for...in返回数组中所有可枚举的属性,
for...of返回数组的下标对应的属性值。
主要是为了遍历对象而产生,不适用于遍历数组。
循环可以用来遍历数组,类数组对象,字符串...
因篇幅问题不能全部显示,请点此查看更多更全内容