JavaScript MVC 进修笔记(三)类的运用(中)

公然纪录进修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 继承了Animal
Dog.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 ;属性并非一切浏览器都支撑,相似Super.js的类库则经由过程属性复制的体式格局来处置惩罚这
个题目,而非经由过程固有的动态继承的体式格局来完成。

经由过程给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()将其转换为可用的数组。

    原文作者:JingDing
    原文地址: https://segmentfault.com/a/1190000002525229
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞