博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript MVC 学习笔记(四)类的使用(下)
阅读量:7166 次
发布时间:2019-06-29

本文共 3130 字,大约阅读时间需要 10 分钟。

控制“类”库的作用域

在类和实例中都添加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 中新增的尽可能多的特性。

添加私有函数

目前上面为“类”库添加的属性都是“公开的”,可以被随时修改。关于给“类”添加私有属性,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 允许通过给$.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.js()来使用它:

    

jQuery 的作者John Resig 在他的博客中写过一篇文章:。


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

转载地址:http://umqwm.baihongyu.com/

你可能感兴趣的文章
随笔导读 - 我的博客看这一篇就够了
查看>>
UE插件 写文本提示字数限制
查看>>
终端神器 iterm
查看>>
迷你MVVM框架 avalonjs1.5 入门教程
查看>>
集成学习
查看>>
K-D Tree题目泛做(CXJ第二轮)
查看>>
mysql8.0+修改用户密码
查看>>
如何open一个新tab页面
查看>>
Permission denied(publickey)错误
查看>>
题解 P1000 【超级玛丽游戏】
查看>>
CF 988C Equal Sums 思维 第九题 map
查看>>
有关C++字符转换的一点小总结
查看>>
SQL Server TempDB初始化大小是如何决定的
查看>>
获取当前屏幕大小尺寸
查看>>
SugarCRM CE 部署除错
查看>>
高性能javascript学习笔记系列(4) -算法和流程控制
查看>>
python函数初识
查看>>
大数据——基础概念
查看>>
6、情人节杀人事件
查看>>
win10下安装scala
查看>>