js内存泄漏常见情况

13 篇文章 0 订阅

js内存泄漏常见情况

1、意外的全局变量 



js中如果不用var声明变量,该变量将被视为window对象(全局对象)的属性,也就是全局变量.
function foo(arg) {
bar = "this is a hidden global variable";
}
// 上面的函数等价于
function foo(arg) {
window.bar = "this is an explicit global variable";
}

所以,你调用完了函数以后,变量仍然存在,导致泄漏.

如果不注意this的话,还可能会这么漏:
function foo() {
this.variable = "potential accidental global";
}
    // 没有对象调用foo, 也没有给它绑定this, 所以this是window 
foo(); 
你可以通过加上’use strict’启用严格模式来避免这类问题, 严格模式会组织你创建意外的全局变量.


2、被遗忘的定时器或者回调


var someResource = getData();
setInterval(function() {
var node = document.getElementById('Node');
if(node) {
node.innerHTML = JSON.stringify(someResource);
}
}, 1000);

这样的代码很常见, 如果id为Node的元素从DOM中移除, 该定时器仍会存在,。
同时, 因为回调函数中包含对someResource的引用, 定时器外面的someResource也不会被释放.

3、没有清理的DOM元素引用
var elements = {
button: document.getElementById('button'),
image: document.getElementById('image'),
text: document.getElementById('text')
};


function doStuff() {
image.src = 'http://some.url/image';
button.click();
console.log(text.innerHTML);
}


function removeButton() {
document.body.removeChild(document.getElementById('button'));


// 虽然我们用removeChild移除了button, 但是还在elements对象里保存着#button的引用
// 换言之, DOM元素还在内存里面.
}

4、闭包 
function Cars(){
  this.name = "Benz";
  this.color = ["white","black"];
}
Cars.prototype.sayColor = function(){
  var outer = this;
  return function(){
    return outer.color
  };
};
 
var instance = new Cars();
console.log(instance.sayColor()())


优化后的代码:
function Cars(){
  this.name = "Benz";
  this.color = ["white","black"];
}
Cars.prototype.sayColor = function(){
  var outerColor = this.color; //保存一个副本到变量中
  return function(){
    return outerColor; //应用这个副本
  };
  outColor = null; //释放内存
};
 
var instance = new Cars();
console.log(instance.sayColor()())


稍微复杂一点的例子:
function inheritPrototype(subType,superType){
  var prototype = Object(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
}
 
function Cars(){
  this.name = "Benz";
  this.color = ["white","black"];
}
Cars.prototype.sayColor = function(){
  var outer = this;
  return function(){
    return outer.color;
  };
};
 
function Car(){
  Cars.call(this);
  this.number = [321,32];
}
inheritPrototype(Car,Cars);
Car.prototype.sayNumber = function(){
  var outer = this;
  return function(){
    return function(){
      return outer.number[outer.number.length - 1];
    }
  };
};
 
var instance = new Car();
console.log(instance.sayNumber()()());


首先,该例子组合使用了构造函数模式和原型模式创建Cars 对象,并用了寄生组合式继承模式来创建Car 对象并从Cars 对象获得属性和方法的继承;
其次,建立一个名为instance 的Car 对象的实例;instance 实例包含了sayColor 和sayNumber 两种方法;
最后,两种方法中,前者使用了一个闭包,后者使用了两个闭包,并对其this 进行修改使其能够访问到this.color 和this.number。
这里存在内存泄露问题,优化后的代码如下:


function inheritPrototype(subType,superType){
  var prototype = Object(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
}
 
function Cars(){
  this.name = "Benz";
  this.color = ["white","black"];
}
Cars.prototype.sayColor = function(){
  var outerColor = this.color; //这里
  return function(){
    return outerColor; //这里
  };
  this = null; //这里
};
 
function Car(){
  Cars.call(this);
  this.number = [321,32];
}
inheritPrototype(Car,Cars);
Car.prototype.sayNumber = function(){
  var outerNumber = this.number; //这里
  return function(){
    return function(){
      return outerNumber[outerNumber.length - 1]; //这里
    }
  };
  this = null; //这里
};
 
var instance = new Car();
console.log(instance.sayNumber()()());
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值