开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
内存泄漏
五种常见情况↓
/**
* 内存泄漏(因为疏忽或错误而造成程序未能释放已经不能在使用的内存)情况
*/
// ① 意外全局变量 --- 使用严格模式
// 'use strict'
// function fn(){
// // 没有var定义或者使用this定义变量都属于window属性
// a = 10;
// this.b = 20
// }
// fn()
// console.log(a,b)
// ② 定时器 --- 不用时候就及时清除定时器 clearInterval(xxx) / 没有及时清除的dom元素 xxx=null
// ③ 闭包
function fun(name){
function fn(){
console.log(name)
}
return fn
}
var fnn = fun('lily')
fnn()
fnn = null
fnn() // fnn is not a function
// ⑤ 事件监听 --- 不用时候就取消事件监听
闭包
/**
* 闭包:函数中返回函数
* 用途:
* 1、获取私有作用域的变量,且这些变量能保存在内存中
* 2、
*/
// 面试题
var funArr = []
for (var i = 0; i < 10; i++) {
funArr[i] = function () {
return i
}
}
console.log(funArr[3]()) // 10 因为for循环跑完再到funArr[3]()执行
/**解决方法:
* 1、 var 改为 let
* 2、闭包
*/
var funArr = []
for (var i = 0; i < 10; i++) {
funArr[i] = (function () {
let j=i
return function () {
return j
}
})()
}
console.log(funArr[3]()) // 3
null和undefined
/**
* null:没有对象,该处不应该有值;转为数值是0;
* undefined:缺少值;转为数值是NaN(不是数值)
*/
console.log(Number(null)) // 0
console.log(Number(undefined)) // NaN
/**
* 什么时候有null?
* 1、 作为函数的参数,表示该函数的参数不是对象;
* 2、 作为对象原型链的重点
*/
console.log(Object.getPrototypeOf(Object.prototype)) // null
/**
* 什么时候出现undefined?
* 1、变量被声明但没有赋值(预解析,变量提升)
* 2、调用函数时候,应该提供的参数没有提供,该参数等于undefined
* 3、对象没有赋值的属性,该属性的值为undefined
* 4、函数没有返回值,默认返回undefined
*/
数组遍历方法
/**
* 数组方法:
* 1、foreach : 不改变原数组,没有返回值
* arr.forEach(function( item, index, arr){ })
* 2、map :不改变原数组,有返回值
* arr.map(function( item, index, arr){ })
* 3、filter :过滤,返回一个新数组
* 4、for...of :返回数组的元素
* 5、reduce :返回参数函数里的返回值.一般作为累加器计算总价
* 6、some():只要检测到有一个元素符合条件就return.
* 7、every():全部满足返回true,否则false
*
*/
var arr = [1, 2, 3, 4, 5, 6, 7, 8]
var res = arr.filter(item => {
return item > 4
})
console.log(res) // [ 5, 6, 7, 8 ]
for (let value of arr) {
console.log(value)
}
var total = arr.reduce((firstItem, item) => {
return firstItem += item
}, 0)
console.log(total) // 36
var res3 = arr.some((item, index) => {
return item % 2 === 0
})
if (res3) {
console.log(`以上数有2的倍数`)
} else {
console.log(`以上数没有2的倍数`)
}
var res4 = arr.every(item => {
return item > 5
})
console.log(res4) // false
foreach 和 map 区别
/**
* foreach 和 map:都是遍历数组,不会修改原数组,区别是:
* 1、forEach() 方法不会返回执行结果,而是undefined
* 2、有返回值,返回执行结果
*/
var arr = [1, 2, 3, 4, 5, 6]
var result = arr.forEach((item, index, arr) => {
// console.log(item) // 遍历值
// console.log(index) // 索引值
// console.log(arr) // 数组本身
return item *2
})
console.log(arr)
console.log(result) // undefined
var res = arr.map((item,index,arr)=>{
return item*2
})
console.log(arr) // [ 1, 2, 3, 4, 5, 6 ]
console.log(res) //[ 2, 4, 6, 8, 10, 12 ]
call,apply和bind
/**
* 改变this指向:
* 如果第一个参数是null和undefined,this默认指向window
* 1、call: 第二个参数是参数列表
* 2、apply:第二个参数必须以数组形式传参
* 3、bind:需要自调用函数,this是永久改变
*/
var name = 'lily'
var obj = {
name: 'cici',
age: 25,
say: function () {
console.log(this.name)
},
sayHobby: function (val1, val2) {
var str = "I'm " + this.name + ", I like " + val1 + " and " + val2 + ".";
console.log(str)
}
}
var obj2 = {
name: 'grace'
}
obj.say() // cici
// setTimeout(obj.say, 1000) // lily;此时作为settimeout的回调函数调用,this指向全局
// 改变this指向
// setTimeout(obj.say.call(obj), 2000) // cici
// obj.sayHobby('swimming', 'hiking') // cici
obj.sayHobby.call(null, 'swimming', 'hiking') // I'm lily, I like swimming and hiking.
obj.sayHobby.apply(obj2, ['swimming', 'hiking']) // I'm grace, I like swimming and hiking.
obj.sayHobby.bind(obj2, 'swimming', 'hiking')() // I'm grace, I like swimming and hiking.
原型和原型链
/**
* 使用class实现继承
1、什么是原型?
2、原型链是怎样的?
3、显示原型和隐式原型:
每一个函数都有一个prototype属性,就是显示原型;
每个实例对象都有一个__proto__,就是隐式原型;
☆ 实例对象的__proto__ === 构造函数的prototype
*/
// 发现学生类,老师类都有一个共同属性name,那么我们定义一个类接收这个共同属性,然后他们来继承
class Person{
constructor(name){
this.name = name;
}
drink(){
console.log('人类基本技能:喝水!')
}
}
// class继承关键字:extends ; super
class Student extends Person{
constructor(name,score){
// this.name = name;
super(name)
this.score = score
}
introduce(){
console.log(`我是${this.name},考了${this.score}分`)
}
}
// 实例化
const student = new Student('lily',99)
console.log(student)
student.introduce()
class Teacher extends Person{
constructor(name,subject){
// this.name = name;
super(name)
this.subject = subject
}
teach(){
console.log(`我是${this.name},教${this.subject}的`)
}
}
// 创建实例
const teacher = new Teacher('cici','数学')
teacher.teach()
teacher.drink()
/**
* 当我们访问一个对象的属性和方法时,首先从自身出发寻找,如果找不到就从它的原型上找,还是没找到,继续往原型的原型上找,这个路径就成为原型链
* 检验这个属性或方法是否在对象本身上:hasownproperty
*/
console.log(teacher.hasOwnProperty('name')) // true
console.log(teacher.hasOwnProperty('teach')) // false