javascript学习笔记 (五) -继承和Closures

本文介绍了JavaScript中实现继承的两种方法:使用call函数和prototype属性,并探讨了闭包的概念及潜在的内存泄露问题。

javascript中的继承和Closures
实现继承的两种方法
使用"call"函数,call允许我们在一个上下文环境中调用另外一个函数。我们在cat和dog类中调用animal类。
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> function Animal(name){
this .name = name;

this .species = 'Animal';
this .sleep = function (){alert( this .name + 'fallsasleep:Zzzzz');}
}
function Cat(name){
Animal.call(
this ,name);

this .talk = function (){alert('Meow ! ');}
}
function Dog(name){
Animal.call(
this ,name);

this .talk = function (){alert('Woof ! ');}
}

var sam = new Cat('Sam');
var joe = new Dog('Joe');
sam.sleep();
// Samfallsasleep:Zzzzz
joe.sleep(); // Joefallsasleep:Zzzzz

sam.talk();
// Meow!
joe.talk(); // Woof!

缺点是prototyping不能在这种方法中使用,animal prototype中的方法不能带到cat或dog中。于是每个cat或dog实例中都有species和sleep的副本,因此效率是不高的。
另外一种替代的方法是使用prototype
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> function Animal(name){
this .name = name;
}
Animal.prototype
= {
species:'Animal',
sleep:
function (){alert( this .name + 'fallsasleep:Zzzzz');}
}

function Cat(name){
Animal.apply(
this ,arguments);
}
Cat.prototype
= new Animal;
Cat.prototype.species
= 'Cat';
Cat.prototype.talk
= function (){alert('Meow ! ');}

function Dog(name){
Animal.apply(
this ,arguments);
}
Dog.prototype
= new Animal;
Dog.prototype.talk
= function (){alert('Woof ! ');}

var sam = new Cat('Sam');
var joe = new Dog('Joe');
sam.sleep();
// Samfallsasleep:Zzzzz
joe.sleep(); // Joefallsasleep:Zzzzz

alert(sam.species);
// Cat
alert(joe.species); // Animal--nospeciesisdefinedforDog

Closures
看如下代码
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> function beginAdding(a){
a
*= 5 ;
return function finishAdding(b){alert(a + b);}
}

var add = beginAdding( 10 );

add(
20 ); // 70

add变量的内容是函数function finishAdding(b){ alert(a+b); } 且有a变量的副本

下面来讨论下内存泄露
IE中有两个GC ,分别用来回收javascript和Dom对象。当退出页面时,他们将删除所有的javascript和dom对象。如果你循环引用DOM->JS->DOM或JS->Dom->Js时会放生泄露。IE将不知道删除那个对象。
例如:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> var someInput = document.getElementById('inputbox');
var someFunction = function (){
alert(someInput.value);
}

someInput.onclick
= someFunction;

当页面不停的刷新时,占用的内存为越来越多。

你也许会在不知情的情况下创建closure
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> function Animal(name){
this .sleep = function (){alert(name + 'fallsasleep:Zzzzz');}
}

sleep函数中name变量来自父函数,这样就产生了一个closure
下面代码也产生了closure 在n函数中有x变量的引用
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> var x = 5 ;
var n = function (){
y
= 10 ;
return y;
}
每个函数都有自己的作用域,你代码的所有域都在一个内部内存栈中。当你创建一个closure,closure访问其中的一个域。当在通过域中创建多个closure时,每个closure会指向相同的域变量。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> var x = 5 ;
var alertX1 = function (){alert(x);}

x
= 10 ;
var alertX2 = function (){alert(x);}

alertX1();
alertX2();

两个的运行结果都是alert 10,因为他们指向相同x的副本


如果我们改变x,两个alert都会跟着改变。解决方法是修改closure的域。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> function makeClosure(x){
return function (){alert(x);}
}

var x = 5 ;
var alertX1 = makeClosure(x);

x
= 10 ;
var alertX2 = makeClosure(x);

alertX1();
// 5
alertX2(); // 10



注意到x变量被拷贝到每个域中。因为x是一个字符串或一个数字。javascript总是将他们以值传递,在新的域中创建x变量的副本。如果是对象就不同了,他会传递引用。这样x变量就会指向相同的对象。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> function makeClosure(x){
return function (){alert(x.val);}
}

var x = {val: 5 };
var alertX1 = makeClosure(x);

x.val
= 10 ;
var alertX2 = makeClosure(x);

alertX1();
// 10
alertX2(); // 10
【电动汽车充电站有序充电调度的分散式优化】基于蒙特卡诺拉格朗日的电动汽车优化调度(分时电价调度)(Matlab代码实现)内容概要:本文介绍了基于蒙特卡洛拉格朗日方法的电动汽车充电站有序充电调度优化方案,重点在于采用分散式优化策略应对分时电价机制下的充电需求管理。通过构建数学模型,结合不确定性因素如用户充电行为电网负荷波动,利用蒙特卡洛模拟生成大量场景,并运用拉格朗日松弛法对复杂问题进行分解求解,从而实现全局最优或近似最优的充电调度计划。该方法有效降低了电网峰值负荷压力,提升了充电站运营效率与经济效益,同时兼顾用户充电便利性。 适合人群:具备一定电力系统、优化算法Matlab编程基础的高校研究生、科研人员及从事智能电网、电动汽车相关领域的工程技术人员。 使用场景及目标:①应用于电动汽车充电站的日常运营管理,优化充电负荷分布;②服务于城市智能交通系统规划,提升电网与交通系统的协同水平;③作为学术研究案例,用于验证分散式优化算法在复杂能源系统中的有效性。 阅读建议:建议读者结合Matlab代码实现部分,深入理解蒙特卡洛模拟与拉格朗日松弛法的具体实施步骤,重点关注场景生成、约束处理与迭代收敛过程,以便在实际项目中灵活应用与改进。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值