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来实现继承。
定义一个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类。
js闭包Demo:
function A(){
function B(){
alert("Hello Closure!");
}
return B;
}
var b = A();
b();//Hello Closure!
这是史上最简单的闭包,不能再简单了,再简单就不是闭包了!B为在函数内部定义的函数,用A函数返回,并用b来接收,也就是说在函数内部定义的函数,在外部使用,这种现象为闭包,所以继承的封装是闭包的一种应用。
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回收,会一直保存到内存中,所以这种写法满足闭包的条件。
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());
如上使用闭包也可以完成继承。