您的位置:首页 > Web前端 > JavaScript

实现javaScript对象的"继承"的两种方法(prototype与闭包)

2016-02-28 16:13 841 查看

javaScript的prototype属性:

什么是prototype:

javaScript的方法分为三类:

类方法

对象方法

原型方法

function People(name)
{
this.name=name;
//对象方法
this.Introduce=function(){
alert("My name is "+this.name);
}
}
//类方法
People.Run=function(){
alert("I can run");
}
//原型方法
People.prototype.IntroduceChinese=function(){
alert("我的名字是"+this.name);
}

//测试

var p1=new People("Windking");

p1.Introduce();

People.Run();

p1.IntroduceChinese();


javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。

定义:原型就是一个函数对象的属性。

作用:

利用原型为函数对象增加属性和方法

函数对象的属性或方法与原型的属性或方法同名时:

函数对象本身的属性和方法的优先级要高于原型上的熟悉感和方法

利用函数对象的属性和方法重写原型上的属性和方法

内建对象(应该都是函数对象):都有prototype属性

可以扩展内建对象的属性和方法

实现继承

在简单了解了prototype的作用后,我们来使用prototype来实现继承。

利用prototype来实现继承

定义一个Person类

function  Person(){
this.sayHello = function(){
alert("helloworld");
}
}
Person.prototype.setName=function(name){
this.name = name;
}
Person.prototype.getName=function(){
return this.name;
}
var p = new Person();
p.sayHello();
p.setName("wang");
alert(p.getName());


现在我们定义一个Student类来继续Person类:

function Student(){

}
Student.prototype = new Person();
var s = new Student();
s.sayHello();
s.setName("xi");
alert(s.getName());


这样Student类即继承了Person类。

使用javaScript的闭包来完成继承:

1.什么是js的闭包

js闭包Demo:

function A(){

function B(){
alert("Hello Closure!");
}
return B;
}
var b = A();
b();//Hello Closure!


这是史上最简单的闭包,不能再简单了,再简单就不是闭包了!B为在函数内部定义的函数,用A函数返回,并用b来接收,也就是说在函数内部定义的函数,在外部使用,这种现象为闭包,所以继承的封装是闭包的一种应用。

2.闭包的作用

avascript中的GC机制:在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收,否则这个对象一直会保存在内存中。

在上述例子中,B定义在A中,因此B依赖于A,而外部变量b又引用了B, 所以A间接的被b引用,也就是说,A不会被GC回收,会一直保存在内存中。

这就是闭包的作用,有时候我们需要一个模块中定义这样一个变量:希望这个变量一直保存在内存中但又不会“污染”全局的变量,这个时候,我们就可以用闭包来定义这个模块。

闭包无处不在,比如:jQuery、zepto的主要代码都包含在一个大的闭包中,上面的写法其实是最简单最原始的写法,而在实际应用中,没人这么玩,特别是在一些大型JS框架中更不会这么写。现在我们来写一个闭包的高端用法:

(function(document){

var viewport;

var obj = {
init:function(id)
{
viewport = document.querySelector("#"+id);
},
addChild:function(child){
viewport.appendChild(child);
},
removeChild:function(child){
viewport.removeChild(child);
} }
window.jView = obj;

})(document);


这个组件的作用是:初始化一个容器,然后可以给这个容器添加子容器,也可以移除一个容器。功能很简单,但这里涉及到了另外一个概念:立即执行函数。 简单了解一下就行。主要是要理解这种写法是怎么实现闭包功能的。

(function(){})() 红色部分是一个表达式,而这个表达式本身是一个匿名函数,所以在这个表达式后面加()就表示执行这个匿名函数。

因此这段代码执行执行过程可以分解如下:

var f = function(document){

var viewport;

var obj = {

init:function(id){
viewport = document.querySelector("#"+id);
},
addChild:function(child){
viewport.appendChild(child);
},
removeChild:function(child){
viewport.removeChild(child);
} }

window.jView = obj;

};

f(document);


在这段代码中似乎看到了闭包的影子,但 f 中没有任何返回值,似乎不具备闭包的条件,注意这句代码:

window.jView = obj;


obj 是在 f 中定义的一个对象,这个对象中定义了一系列方法, 执行window.jView = obj 就是在 window 全局对象定义了一个变量 jView,并将这个变量指向 obj 对象,即全局变量 jView 引用了 obj . 而 obj 对象中的函数又引用了 f 中的变量 viewport ,因此 f 中的 viewport 不会被GC回收,会一直保存到内存中,所以这种写法满足闭包的条件。

了解了js的闭包之后使用闭包来实现继承

function extend(obj1){
function F(){ }
//判断传递进行的是一个new出来的对象
if(typeof obj1 == "object"){
for(var i in obj1){
//直接调用对象的属性来获取,调用方法的prototype来接受
F.prototype[i] = obj1[i];
}
}
//返回函数
return  F;
}
var person_son = extend(new Person());
var p = new person_son();
p.sayHello();
p.setName("abc");
alert(p.getName());


如上使用闭包也可以完成继承。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: