资讯专栏INFORMATION COLUMN

JavaScript MVC 学习笔记(四)类的使用(下)

Rango / 1008人阅读

摘要:基于函数进行调用的,用来确保函数是在指定的值所在的上下文中调用的。添加私有函数目前上面为类库添加的属性都是公开的,可以被随时修改。以基于的富应用开发为主要学习资料。

控制“类”库的作用域

在类和实例中都添加proxy函数,可以在事件处理程序之外处理函数的时候保持类的作用域。下面是不用proxy的办法:

var Class = function(parent){
    var klass = function(){
        this.init.apply(this, arguments);
    };

    klass.prototype.init = function(){};
    klass.fn = klass.prototype;

    // 添加一个proxy 函数
    klass.proxy = function(func){
        var self = this;
        return(function(){
            return func.apply(self, arguments);
        });
    }

    // 在实例中也添加这个函数
    klass.fn.proxy = klass.proxy;
    return klass;
};

下面是用proxy()函数来包装函数,以确保它们在正确的作用域中被调用:

var Button = new Class;
    Button.include({
    init: function(element){
        this.element = jQuery(element);

        // 代理了这个click 函数
        this.element.click(this.proxy(this.click));
    },
    click: function(){ /* ... */ }
});

如果没有使用proxyclick()的回调包装起来,它就会基于上下文this.element来调用,而不是Button,这会造成各种问题。在新版本的JavaScript——ECMAScript 5(ES5)——中同样加入了bind()函数用以控制调用的作用域。bind()基于函数进行调用的,用来确保函数是在指定的this值所在的上下文中调用的。例如:

Button.include({
    init: function(element){
        this.element = jQuery(element);
        // 绑定这个click 函数
        this.element.click(this.click.bind(this));
    },
    click: function(){ /* ... */ }
});

这个例子和proxy()函数是等价的,它能确保click() 函数基于正确的上下文进行调用。老版本的浏览器不支持bind(),但可以手动实现它,兼容性也不错,直接扩展相关对象的原型,这样就可以像在ES5 中使用bind(),在任意浏览器中调用它。下面是一段实现了bind() 函数的代码:

if (!Function.prototype.bind) {
    Function.prototype.bind = function (obj) {
        var slice = [].slice,
        args = slice.call(arguments, 1),
        self = this,
        nop = function () {},
        bound = function () {
        return self.apply( this instanceof nop ? this : (obj || {}),
            args.concat(slice.call(arguments)));
        };

        nop.prototype = self.prototype;
        bound.prototype = new nop();
        return bound;
    };
}

如果浏览器原生不支持bind(),则仅仅重写了Function 的原型。现代浏览器则可以继续使用内置的实现。

对于数组来说这种“打补丁”式的做法非常有用,因为在新版本的JavaScript 中,数组增加了很多新的特性。可以使用es5-shi项目,它涵盖了ES5 中新增的尽可能多的特性。

添加私有函数

目前上面为“类”库添加的属性都是“公开的”,可以被随时修改。关于给“类”添加私有属性,JavaScript支持不可变属性,但在主流浏览器中并未实现,没办法直接利用这个特性。可以利用JavaScript 匿名函数来创建私有作用域,这些私有作用域只能在内部访问:

var Person = function(){};

(function(){
    var findById = function(){ /* ... */ };
    Person.find = function(id){

    if (typeof id == "integer")
        return findById(id);
    };
})();

上面的代码将类的属性都包装进一个匿名函数中,然后创建了局部变量(findById),这些局部变量只能在当前作用域中被访问到。Person变量是在全局作用域中定义的,可以在任何地方都能访问到。定义变量的时候不要丢掉var运算符,如果丢掉var就会创建全局变量。如果需要定义全局变量,可以在全局作用域中定义,或者定义为window的属性:

(function(exports){
    var foo = "bar";

    // 将变量暴露出去
    exports.foo = foo;
})(window);

assertEqual(foo, "bar");
“类”库

jQuery 本身并不支持类,但通过插件的方式可以轻易引入类的支持,比如HJS。HJS 允许通过给$.Class.create传入一组属性来定义类:

var Person = $.Class.create({

    // 构造函数
    initialize: function(name) {
        this.name = name;
    }
});

可以在创建类的时候传入父类作为参数,这样就实现了类的继承:

var Student = $.Class.create(Person, {
    price: function() { /* ... */ }
});

var alex = new Student("Alex");
alex.pay();

可以直接给类挂载属性:

Person.find = function(id){ /* ... */ };

HJS 的API 中同样包含一些工具函数,比如clone() 和equal() :

var alex = new Student("Alex");
var bill = alex.clone();
assert( alex.equal(bill) );

还有 Spine 同样实现了类,通过直接在页面中引入spine.js(http://maccman.github.com/spine/spine.js)来使用它:

    
    

jQuery 的作者John Resig 在他的博客中写过一篇文章:专门讲解如何实现经典的类继承。

公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。类的部分终于看完了,再慢慢消化。JS真是博大精深!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85509.html

相关文章

  • JavaScript MVC 学习笔记(二)类的使用(上)

    摘要:任何函数都可以用做构造函数,构造函数必须使用运算符作为前缀来创建新的实例。当使用关键字来调用构造函数时,执行上下文从全局对象变成一个空的上下文,这个上下文代表了新生成的实例。默认情况下,如果构造函数中没有返回任何内容,就会返回当前的上下文。 公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。 JavaScr...

    caozhijian 评论0 收藏0
  • JavaScript MVC 学习笔记(三)类的使用(中)

    摘要:实际上,可以将其理解为某种形式的继承。如果上下文是,则使用全局对象代替。例如的第个参数是上下文,后续是实际传入的参数序列中允许更换上下文是为了共享状态,尤其是在事件回调中。 公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。接上一篇类的学习,发现实在是看晕了,有些例子是能看懂在干嘛,但是不知道为什么这样做,有的甚至...

    DandJ 评论0 收藏0
  • JavaScript MVC 学习笔记(一)初识JS MVC

    摘要:以基于的富应用开发为主要学习资料。下面用实现一个例子使用匿名函数来封装一个作用域在页面加载时绑定事件监听上面的代码创建了控制器,这个控制器是放在变量下的命名空间。然后用了一个匿名函数封装了一个作用域,以避免对全局作用域造成污染。 公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。 什么是MVC MVC 是一种设...

    xorpay 评论0 收藏0
  • JavaScript MVC 学习笔记(五)事件的基本操作

    摘要:事件是应用程序的核心,是所有内容的驱动。将对这两种事件模型的支持都加入标准规范之中。根据型,事件首先被目标元素所捕捉,然后向上冒泡。取消事件冒泡当事件冒泡时,可以通过数来终止冒泡,这个函数是对象中的方法。 事件是 JavaScript 应用程序的核心,是所有内容的驱动。尽管后来W3C 对此做了标准化,但 IE 仍然坚持使用与 W3C 不兼容的事件模型,直到 IE9 才遵循标准。有很多诸...

    Julylovin 评论0 收藏0
  • Backbone.js学习笔记(一)

    摘要:它通过数据模型进行键值绑定及事件处理,通过模型集合器提供一套丰富的用于枚举功能,通过视图来进行事件处理及与现有的通过接口进行交互。 本人兼职前端付费技术顾问,如需帮助请加本人微信hawx1993或QQ345823102,非诚勿扰 1.为初学前端而不知道怎么做项目的你指导 2.指导并扎实你的JavaScript基础 3.帮你准备面试并提供相关指导性意见 4.为你的前端之路提供极具建设性的...

    FrancisSoung 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<