1、标准库函数:
Object()、String()、Boolean()、Number()、Array()、Function();每一个对象有各自的属性和方法;
标准库函数总结:
基本类型的构造函数:如果前面不加 new 关键字,返回基本类型的值,加 new 关键字会返回 该类型的对象;
复杂类型的构造函数,加不加 new 关键字结果都一样,返回 对象;
2、Array数组:
1、创建数组方法:
let arr = ['a','b'] //['a','b']
let arr = new Array('a','b') //['a','b']
2、数组本质:
原型链上必须有Array.prototype这个属性,js中数组是Array构造出来的对象
3、遍历数组:
VS四种常用遍历数组的方法 https://www.jianshu.com/p/acaddb35c5ed
4、 ForEach遍历数组用法:
1、forEach - 遍历数组
方法一、
var arr = ['jjj','kkk','hhh']
arr.forEach(function(a,b,c){
console.log(a,b,c)
})
//
jjj 0 (3) ["jjj", "kkk", "hhh"]
kkk 1 (3) ["jjj", "kkk", "hhh"]
hhh 2 (3) ["jjj", "kkk", "hhh"]
方法二、
arr.forEach( function(a,b){
console.log(a,b)
})
//
jjj 0
kkk 1
hhh 2
方法三、
arr.forEach( function(value,key){
console.log(value,key)
})
//
jjj 0
kkk 1
hhh 2
方法四、
arr.forEach((v,i)=>{
console.log(v)
console.log(i)
})
- 使用forEach()遍历数组时最好使用箭头函数,好处就是会保留外部this.
2、sort - 排序
方法一、
var arr = [1,3,4,5,6,2]
arr.sort( function(x,y){
return x-y
})
// [1, 2, 3, 4, 5, 6]
arr.sort( function(x,y){
return y-x
})
// [6, 5, 4, 3, 2, 1]
方法二、
var arr = ['马云','马化腾','李彦宏']
var sort = {
'马云':167.92,
'马化腾':376,
'李彦宏':226
}
arr.sort( function(x,y){
return sort[x]-sort[y]
})
//["马云", "李彦宏", "马化腾"]
arr.sort( function(x,y){
return sort[y]-sort[x]
})
// ["马化腾", "李彦宏", "马云"]
3、join - 插入元素
var arr = [1,2,4]
arr.join('s')
// "1s2s4" 变成字符串
4、concat - 连接数组
一般用法、
var a1 = [1,3,4,5,6];
var a2 = ['a,','d','s','c']
a1.concat(a2)
//[1, 3, 4, 5, 6, "a,", "d", "s", "c"]
a2.concat(a1)
// ["a,", "d", "s", "c", 1, 3, 4, 5, 6]
特殊用法、
//利用concat返回新的数组的特性,复制一个数组
var a1 = [1,3,4,5,6];
var b = a.concat([])
b //[1,3,4,5,6]
a === b //false
5、map - 遍历数组
var arr = [1,2,4,4]
arr.map( function(value,key){
return value*2
})
// [2, 4, 8, 8]
map属性和forEach的区别:
和forEach一样,唯一不同的是map有返回值,可以返回任何类型值,forEach没有返回值,返回undefined
举例:
var arr = [1,2,4,4]
arr.map( function(value,key){
return value*2
})
// [2, 4, 8, 8]
arr.forEach( function(value,key){
return value*2
})
// undefined
6、filter - 过滤数组
方法一、
//过滤掉一部分 var a = [1,2,3,4,5,6,7,8,9]
a.filter(function(value,key){ //必须传入两个参数
return value >= 4 //布尔值ture留下,false去掉
})
//[4, 5, 6, 7, 8, 9]
方法二、
//过滤掉奇数
var a = [1,2,3,4,5,6,7,8,9]
a.filter(function(value,key){
return value % 2 == 0 //余数等于零
})
// [2, 4, 6, 8]
方法三、
//filter和map一起用 —— 链式操作 ,map返回不一样的数组,filter返回元素数量上的不同
var a = [1,2,3,4,5,6,7,8,9]
a.filter(function(value,key){
return value % 2 === 0
}).map(function(value){
return value * value
})
//[4, 16, 36, 64]
7、reduce - 遍历数组
方法一、
var arr = [1,2,3,4,5,6,7,8,9,10]
var sum = 0
arr.reduce( function(sum,n){
return sum + n
},0)
//55
方法二、
var arr = [1,2,3,4,5,6,7,8,9,10]
var sum = 0
arr.reduce((sum,n) => sum + n,0)
//55
8、乱炖-reduce 代替其它map、filter、
1、代替filter、
//求偶数
var arr = [1,2,3,4,5,6,7,8,9,10]
arr.reduce( function(a,n){
if(n%2 == 0){
a.push(n)
}
return a
},[])
// [2, 4, 6, 8, 10]
2、代替map、
//每一个元素变为原来的两倍
var arr = [1,3,4,5]
arr.reduce( function(a,n){
a.push(n*2)
return a
},[])
// [2, 6, 8, 10]
3、代替map和filter
//求奇数之和
var arr = [1,2,3,4,5,6,7,8,9,10]
arr.reduce( function(sum,n){
if(n%2 !== 0){
sum = sum + n
}
return sum
},0)
// 25
3、Function函数:
1、声明函数
1、关键字声明具名函数:
function f(input){return undefined} ///f函数名、input参数,可以有多个、函数体默认返回undefined
2、关键字声明匿名函数
var f = function(){} //必须赋值给变量
3、关键字声明具名函数赋给变量
var x = function y(input1,inpu2){}
4、全局对象声明(少用)
var f = new Function('参数一','参数二','return语句')
5、箭头函数
fn =(x,y)=> {return x+y} //如果参数只有一个,那么可以省略圆括号;如果return只有一个语句,且不能返回一个对象时可以一起省略花括号和return
2、函数的name属性:
- 具名函数的name就是"函数名"
- 匿名函数的name就是付给的的变量名
- 具名函数赋给变量的话:函数名为等号右边的函数名:
var f1 = function f2(){}; f1.name //'f2' f2.name //报错 console.log(f2) //当然也会报错
- 全局变量生命的匿名函数名:"anonymous"
- 箭头函数没有函数名
3、函数参数不是变量而是函数的几种情况
1、函数里面传入的参数可以是函数
function fn(f){
console.log('参数为函数')
return undefined
}
2、函数里面传入的参数可以是函数,使用循环语句
function fn(f){
if(typeof f!=='function'){
console.log('滚')
return false
}else{
console.log('函数')
return true
}
}
fn(1)
// 滚
// false
fn(function(){})
// 函数
// true
3、函数里面传入的参数可以是函数,并且可以调用这个函数
function fn(f){
if(typeof f!=='function'){
console.log('滚')
return false
}else{
console.log('接受了这个函数当作参数')
f.call()
console.log('并且我调用了它')
return true
}
}
fn(1)
// 滚
// false
fn(function(){console.log('我被调用了')})
// 接受了这个函数当作参数
// 我被调用了
// 并且我调用了它
// true
4、函数里面传入的参数可以是函数,并且可以调用这个函数并同时传参给另一个函数
function fn(f){
console.log('函数为参数')
return undefined
}
function fn(y){
y(555)
}
fn(function(){
console.log(arguments)
})
//Arguments [555, callee: ƒ, Symbol(Symbol.iterator): ƒ]
4、this 和 arguments
this
- f.call(undefined,input1,input2) //call的第一个参数undefined可以通过this来得到,call后面的参数可以通过arguments来得到
- this为对象,执行时输入的参数是什么类型的值就会输出什么类型的对象
function f(){
console.log(this)
}
f.call(1) //打印出Number类型的对象1:Number {1}
// 但是严格模式下:上面的的代码块会打印出 1
- 不传入参数,this就会返回window (普通模式下this指向window ,严格模式下this如果没有参数就会返回undefined)
function f(){
console.log(this)
}
f.call() //window
//但是严格模式下:上面的代码块会返回undefined
arguments
- arguments是伪数组
function f(){
console.log(arguments)
}
f.call(undefined,1) //Arguments [1, callee: ƒ, Symbol(Symbol.iterator): ƒ]
-
伪数组: 一个对象,长得像数组,但他的原型链没有指向Array.prototype这个属性,同时它的原型链的原型链也没有指向Array.prototype;也就是说arr.____proto____ !== Array.prototype,(或者说没有数组的原型链中的属性)那么就是为数组。或者没有继承数组的原型链。又或者说没有数组的push、pop等方法。
常见伪数组:函数的arguments对象,DOM API获取的Elements.
5、作用域scope
-
作用域和数据结构中的树tree紧密相关的,按照语法树一层一层往上找声明,遵循就近原则;
作用域 - 问:如果在声明函数的时候没有加 var,就一定是在声明全局变量吗?
- 答:很多人都会这么认为,但这种说法其实是错误的。
例如 a = 3 ,会优先认为它是一个赋值,此时并没有声明;
然后它会寻找自己当前所在的作用域内是否存在 a 的声明,若不存在声明,则会沿着作用域树一层一层地向上(向父级作用域)寻找声明;
当在全局范围找到 a 的声明时,就将 a = 3 的值赋给全局变量 a;
那么,a = 3 在什么情况下是在声明一个全局变量呢?
在整个作用域树中都找不到对 a 的声明(包括全局范围),此时的 a = 3 就是在声明一个全局变量并给它赋值; - 避免找错作用域的捷径:看到递归调用函数,就先所有声明提升,改写代码:变量提升,执行语句全部在下面;
- 有时候变量名不变,还是那个变量名,但是值会变,尤其在for循环中,都会返回到最大值。语句的先后关系直接影响值(因为浏览器的遍历速度是纳米级的,我们统一认可全部遍历);
- 想看跟多作用域面试题,请点击作用域面试题库!
6、闭包
如果一个函数使用了它范围外的变量,那么(这个函数和变量)叫做闭包。
var a = 1
function f(){
console.log(a)
}
- 闭包的作用:
- 可以读取函数内部的变量。
- 可以让这些变量的值始终保持在内存中。
网友评论