js---闭包和面向对象编程

这两个概念理解起来不容易,翻查了很多资料,几乎耗费了我一天的时间来理解它,感觉自己都快走火入魔了。不过最终有所了悟,一番付出还是有所收获的。

(1)闭包概念

很多书上关于闭包的定义直接阅读的话很难理解,下面我通过实例来讲解这个概念。

1、首先,我们必须了解变量的作用于问题。js的作用于无外乎有两种,一种是全局变量(可以在全局范围内被调用),一种是局部变量(一般在函数内声明,正常情况下只能在函数内调用)。

js语言的特俗之处就在于函数内部可以读取全局变量。(需要注意的是,在函数内部定义变量一定要用到var,否则你定义的就是全局变量)

2、一般情况下,从函数外部无法读取函数内部的局部变量。但是特殊情况下,通过变通的方式可以实现。

我们可以在函数内部在定义一个函数。

function f1() {

var n = 999;

function f2() {

alert(n);

return f2;

}

var result = f1();

result();

上述代码中,f2函数就是闭包。我给出的定义是能够读取函数内部变量的函数就叫闭包。

3、闭包的用途

.可以读取函数内部的变量

.让这些变量的值始终保持在内存中。

function f1() {

var n=999;

nAdd = function() {n+=1};

function f2() {

alert(n);

return f2;

var result = f1();//运行之后返回f2,此时n=1000.注意f2函数并未运行,也就是不会运行alert(n);

result();//运行完后,变量n仍然保存在内存中,值为999

nAdd();//全局函数,n自加1;

result();

result实际上就是等于函数f2.它一共运行了2次,一次是999,一次是1000.这证明了函数f1中的局部变量n一直保存在内存中,并没有在调用后被自动清理机制自动清除。

为什么会这样?原因就在与f2被赋予给一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终保存在内存中,不会在调用结束后被垃圾回收机制回收。

至于nAdd = function() {n+=1}这一行,没有使用var关键字,因此nAdd是一个全局变量而不一个局部变量。这样函数可以在外部对函数内部的局部变量进行操作。

(2)面向对象编程:封装

如果我们要把“属性”和“方法”封装成一个对象,甚至从原型对象生成一个实例对象,我们该怎么做?下面我介绍封装方法的演变过程。

1、生成对象的原始模式

把手机看成一个对象,他有类型和颜色两个属性

var shouji = {

type = “”,

color = “”

根据这个原型对象的规格,生成两个实例。

var shouji1 = {};

shouji1.type = “苹果”;

shouji1.color = “red”;

var shouji2 = {};

shouji2.type = “华为”;

shouji2.color = “blue”;

上面是最简单的封装,缺点:多生成几个实力写起来就会非常麻烦,实力和原型之间没有什么办法看出什么联系。

2、原始模式的改进

通过构造一个函数解决函数重复问题。

function Shouji(type,color) {

return {

type:type,

color:color

生成实例

var shouji1 =new Shouji(“苹果”,“red”);

var shouji2 =new Shouji(“华为”,“blue”);

shouji1和shouji2之间没有内在练习,不能反映出它们是同一个原型对象的实例。

3、构造函数模式

构造函数就是普通函数,除了按约定首字母大写,内部使用了this变量。对构造函数使用new运算符就能生成实例,并且this对象会绑定在实例对象上。

例:function Shouji(type,color) {

this.type = type;

this.color = color;

生成实例

var shouji1 =new Shouji(“苹果”,“red”);

var shouji2 =new Shouji(“华为”,“blue”);

这时shouji1和shouji2自动含有一个construcor属性,指向他们的构造函数。

shouji1.constructor == Shouji;

shouji2.constructor == Shouji;

如果上述对象添加一个shouji添加一个不变的属性“gongneng”和一个“internet”上网功能,那么原型对象就变成下面这个样子。

function Shouji(type,color) {

this.type = type;

this.color = color;

this.gongneng = “打电话”;

this.internet = function(){alert(“吃老鼠”)}

生成实例

var shouji1 =new Shouji(“苹果”,“red”);

var shouji2 =new Shouji(“华为”,“blue”);

对于每一个实力对象,gongneng属性和internet()方法都是一模一样的内容,每次生成一个实力都必须重复同样的内容,多占用一些内容这样既不环保也缺乏效率。

能不能让gongneng属性和internet方法在内存中只生成一次,然后所有实例都指向那个内存地址?以下的方式可以。

4、prototype模式

js规定每一个构造函数都有一个prototype属性,指向另一个对象。这个对象所有属性和方法都会被构造函数的实例继承。

我们可以把这些不变的属性和方法直接定义在prototype对象上。

function Shouji(type,color) {

this.type = type;

this.color = color;

Shouji.prototype.gongneng = “猫科动物”;
Shouji.prototype.nternet = function(){alert(“吃老鼠”)};

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值