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

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

公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。接上一篇类的学习,发现实在是看晕了,有些例子是能看懂在干嘛,但是不知道为什么这样做,有的甚至看不懂,真是博大精深!

基于原型的类继承

JavaScript 是基于原型的编程语言,原型用来区别类和实例。原型是一个“模板”对象,它上面的属性被用做初始化一个新对象。任何对象都可以作为另一个对象的原型对象,以此来共享属性。实际上,可以将其理解为某种形式的继承。

当读取一个对象的属性时,JavaScript 首先会在本地对象中查找这个属性,如果没有找到,JavaScript 开始在对象的原型中查找,若还未找到还会继续查找原型的原型,直到查找到Object.prototype。如果找到这个属性,则返回这个值,否则返回undefined。例如,给 Array.prototype 添加了属性,那么所有的 JavaScript 数组都具有了这些属性。

让子类继承父类的属性的方法:

先定义一个构造函数,然后将父类的新实例赋值给构造函数的原型:

// 父,动物大类var Animal = function(){};Animal.prototype.breath = function(){    console.log('breath');};// 子,狗类var Dog = function(){};// Dog 继承了AnimalDog.prototype = new Animal;Dog.prototype.wag = function(){    console.log('wag tail');};

检查继承是否生效了:

var dog1 = new Dog;dog1.wag();dog1.breath(); // 继承的属性

给“类”库添加继承

通过传入一个可选的父类来创建新类,这个可以作为创建类的基础模板:

var Class = function(parent){    var klass = function(){        this.init.apply(this, arguments);    };    // 改变klass 的原型    if (parent) {        var subclass = function() { };        subclass.prototype = parent.prototype;        klass.prototype = new subclass;    };    klass.prototype.init = function(){};    // 定义别名    klass.fn = klass.prototype;    klass.fn.parent = klass;    klass._super = klass.__proto__;    /* include/extend 相关的代码…… */    return klass;};

如果将parent 传入Class 构造函数,那么所有的子类则共享同一个原型。这种创建

临时匿名函数的小技巧避免了在继承类的时候创建实例,这里暗示了只有实例的属性才会被继承,而非类的属性【我没读懂这句和上面代码的关系,感觉已经晕了 = =】。设置对象的proto ;属性并不是所有浏览器都支持,类似的类库则通过属性复制的方式来解决这
个问题,而非通过固有的动态继承的方式来实现。

通过给Class 传入父类来实现简单的继承:

var Animal = new Class;Animal.include({    breath: function(){        console.log('breath');    }});var Cat = new Class(Animal);// 用法var tommy = new Cat;

函数调用

在JavaScript中,函数和其他东西一样都是对象。和其他对象不同的是,函数可调用。函数内上下文,如this 的取值,取决调用它的位置和方法。

除了使用方括号可以调用函数之外,还有其他两种方法可以调用函数:apply()call()。两者的区别在于传入函数的参数的形式。

apply() 函数有两个参数:第1个参数是上下文,第2个参数是参数组成的数组。如果上下文是null,则使用全局对象代替。例如:

function.apply(this, [1, 2, 3])

call()的第1个参数是上下文,后续是实际传入的参数序列:

function.call(this, 1, 2, 3);

JavaScript 中允许更换上下文是为了共享状态,尤其是在事件回调中。jQuery 在其API 的实现中就利用了apply() 和call() 来更改上下文,比如在事件处理程序中或者使用each() 来做迭代时。

$('.clicky').click(function(){    // ‘this’指向当前节点    $(this).hide();});$('p').each(function(){    // ‘this’指向本次迭代    $(this).remove();});

为了访问原始上下文,可以将this 的值存入一个局部变量中,这是一种常见的模式,比如:

var clicky = {    wasClicked: function(){        /* ... */    },    addListeners: function(){        var self = this;        $('.clicky').click(function(){            self.wasClicked()        });    }};clicky.addListeners();

可以用apply来将这段代码变得更干净一些,通过将回调包装在另外一个匿名函数中,来保持原始的上下文:

var proxy = function(func, thisObject){    return(function(){        return func.apply(thisObject, arguments);    });};var clicky = {    wasClicked: function(){        /* ... */    },    addListeners: function(){        var self = this;        $('.clicky').click(proxy(this.wasClicked, this));    }};

上面的例子中在点击事件的回调中指定了要使用的上下文;jQuery中调用这个函数所用的上下文就可以忽略了。实际上jQuery也包含了实现了这个功能的API——jQuery.proxy()

$('.clicky').click($.proxy(function(){ /* ... */ }, this));

使用apply()call()还有其他很有用的原因,比如“委托”。可以将一个调用委托给另一个调用,甚至可以修改传入的参数:

var App {    log: function(){        if (typeof console == "undefined") return;        // 将参数转换为合适的数组        var args = jQuery.makeArray(arguments);        // 插入一个新的参数        args.unshift("(App)");        // 委托给console        console.log.apply(console, args);    }};

这个例子中首先构建了一个参数数组,然后将参数添加进去,最后将这个调用委托给了console.log()arguments变量是解释器内置的当前调用的作用域内用来保存参数的数组。但它并不是真正的数组,比如它是不可变的,因此需要通过jQuery.makeArray()将其转换为可用的数组。

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

你可能感兴趣的文章
Java基础第三天_数组
查看>>
PHP 中文汉字转换成拼音函数
查看>>
MySQL备份需要考虑的问题
查看>>
python基础(1)
查看>>
关于php7.0下Sqli-labs搭建的小问题
查看>>
股价飙升20%市值增长100亿,《纸牌屋》之父Netflix凭什么比他的竞争者要强12倍?...
查看>>
决心书
查看>>
SylixOS调试与性能分析技术--内存泄漏检测
查看>>
shell训练营Day15
查看>>
MySQL常用语句命令
查看>>
关于字符串的一些操作
查看>>
无法访问磁盘提示无法访问的文件寻回方案
查看>>
计算机来当球赛战术分析员 看看它们怎么演算的
查看>>
C#中的webBrowser空间 连接InvokeMember("click") 无效问题
查看>>
整合spring cloud云服务架构 - eureka 基础
查看>>
区块链vs传统数据库:分布式运行有何优势?
查看>>
交换机原理
查看>>
TCP三次握手和四次挥手
查看>>
Spring Clould负载均衡重要组件:Ribbon中重要类的用法
查看>>
如何对flv视频进行压缩,3种方法教你搞定
查看>>