实现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());
如上使用闭包也可以完成继承。
相关文章推荐
- javascript 拷贝文本
- 深入理解Javascript函数编程
- Jsp中两种请求方式的区别
- [LeetCode][JavaScript]Count Primes
- eval在JS中的作用
- js setInterval和clearInterval 的使用
- JS闭包小结
- Jsonp 复习笔记
- JavaScript--map、reduce、filter、sort
- js中的各种宽高
- 解析JSON数据的详细步骤以及偷懒技巧(使用第三方库GSON以及GsonFormat工具)
- netctoss01_项目概述及规范【Servlet+JSP版】
- html、css、js的命名规范
- js继承学习
- jsp内置对象*response
- jsp内置对象*session
- jsp内置对象*out
- jsp内置对象*page
- jsp内置对象*exception
- jsp内置对象*pageContext