javascript中的继承和Closures
实现继承的两种方法
使用"call"函数,call允许我们在一个上下文环境中调用另外一个函数。我们在cat和dog类中调用animal类。
缺点是prototyping不能在这种方法中使用,animal prototype中的方法不能带到cat或dog中。于是每个cat或dog实例中都有species和sleep的副本,因此效率是不高的。
另外一种替代的方法是使用prototype
Closures
看如下代码
add变量的内容是函数function finishAdding(b){ alert(a+b); } 且有a变量的副本
下面来讨论下内存泄露
IE中有两个GC ,分别用来回收javascript和Dom对象。当退出页面时,他们将删除所有的javascript和dom对象。如果你循环引用DOM->JS->DOM或JS->Dom->Js时会放生泄露。IE将不知道删除那个对象。
例如:
当页面不停的刷新时,占用的内存为越来越多。
你也许会在不知情的情况下创建closure
sleep函数中name变量来自父函数,这样就产生了一个closure
下面代码也产生了closure 在n函数中有x变量的引用
两个的运行结果都是alert 10,因为他们指向相同x的副本
如果我们改变x,两个alert都会跟着改变。解决方法是修改closure的域。
注意到x变量被拷贝到每个域中。因为x是一个字符串或一个数字。javascript总是将他们以值传递,在新的域中创建x变量的副本。如果是对象就不同了,他会传递引用。这样x变量就会指向相同的对象。
实现继承的两种方法
使用"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!
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
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
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;
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');}
}
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会指向相同的域变量。
var n = function (){
y = 10 ;
return y;
}
<!--<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();
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
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
return function (){alert(x.val);}
}
var x = {val: 5 };
var alertX1 = makeClosure(x);
x.val = 10 ;
var alertX2 = makeClosure(x);
alertX1(); // 10
alertX2(); // 10
本文介绍了JavaScript中实现继承的两种方法:使用call函数和prototype属性,并探讨了闭包的概念及潜在的内存泄露问题。
 -继承和Closures&spm=1001.2101.3001.5002&articleId=81715183&d=1&t=3&u=f64731ef0ac44551ba4198535840f4ef)
671

被折叠的 条评论
为什么被折叠?



