zoukankan      html  css  js  c++  java
  • LINQ to JavaScript

    LINQ to JavaScript 源码分析

     

    在.net平台工作一年有余,最喜欢的应属Linq特性

    在几个移动端web小项目过程中,前端需要对json对象集合进行比较复杂的操作,为提高开发效率,引入了LINQ to Javascript,该项目地址:http://jslinq.codeplex.com/

    LINQ to JavaScript代码不到两百行,可读性很好,今天来对它的源代码进行下分析

     Linq to JavaScript使用示例

    复制代码
    var myList = [
                {FirstName:"Chris",LastName:"Pearson"},
                {FirstName:"Kate",LastName:"Johnson"},
                {FirstName:"Josh",LastName:"Sutherland"},
                {FirstName:"John",LastName:"Ronald"},
                {FirstName:"Steve",LastName:"Pinkerton"}
                ];
                
    var exampleArray = JSLINQ(myList)
                       .Where(function(item){ return item.FirstName == "Chris"; })
                       .OrderBy(function(item) { return item.FirstName; })
                       .Select(function(item){ return item.FirstName; });
    复制代码

    Linq to JavaScript整体架构

    复制代码
    (function() {
        JSLINQ = window.JSLINQ = function(dataItems) {
            return new JSLINQ.fn.init(dataItems);
        };
        JSLINQ.fn = JSLINQ.prototype = {
            init: function(dataItems) {
                this.items = dataItems;
            },
            Where: function(clause) {
                ...
            }, 
      
            ...
      } JSLINQ.fn.init.prototype = JSLINQ.fn; })();
    复制代码

    这个结构的关键点有

    1. 最外层用一个匿名函数(function(){}))()构造块级作用域
    2. 不采用new JSLINQ().Where()方式,而是将JSLINQ()作为一个工厂方法,返回init()函数的实例对象
    3. 为了在init()函数的实例对象上继续调用JSLINQ原型对象的方法,将JSLINQ.fn.init.prototype指向JSLINQ.fn,也即JSLINQ.prototype
      • 通过这一操作,调用new JSLINQ().Where()时,首先可以在init()函数的实例对象中查询,未找到后在init.prototype中查询,未找到,继续沿原型链向上查找,在JSLINQ.prototype上找到Where方法
      • 如果没有这一操作,调用new JSLINQ().Where()时,将会提示Where方法未被定义

    观察Linq to JavaScript整体结构会发现,其结构与JQuery的非常相似

    复制代码
    (function( window, undefined ) {
        var jQuery = (function() {
           // 构建jQuery对象
           var jQuery = function( selector, context ) {
               return new jQuery.fn.init( selector, context, rootjQuery );
           }
       
           // jQuery对象原型
           jQuery.fn = jQuery.prototype = {
               constructor: jQuery,
               init: function( selector, context, rootjQuery ) {
                  
               }
           };
       
           // Give the init function the jQuery prototype for later instantiation
           jQuery.fn.init.prototype = jQuery.fn;
          
            // 到这里,jQuery对象构造完成,后边的代码都是对jQuery或jQuery对象的扩展
           return jQuery;  
        })();
       
        window.jQuery = window.$ = jQuery;
    })(window);
    复制代码

    LINQ to JavaScript详细分析

    复制代码
    //构造块级作用域
    (function() {
        //工厂方法,返回init()的实例对象
        JSLINQ = window.JSLINQ = function(dataItems) {
            return new JSLINQ.fn.init(dataItems);
        };
        JSLINQ.fn = JSLINQ.prototype = {
            init: function(dataItems) {
                this.items = dataItems;
            }
            //clause是一个函数表达式
            Where: function(clause) {
                var item;
                //创建本地数组,存储返回值
                var newArray = new Array();
    
                // The clause was passed in as a Method that return a Boolean
                for (var index = 0; index < this.items.length; index++) {
                    //将元素传入函数
                    if (clause(this.items[index], index)) {
                        newArray[newArray.length] = this.items[index];
                    }
                }
                //将结果数组传入JSLINQ(),创建新的init()对象实例,以便可以链式调用
                return new JSLINQ(newArray);
            },
            Select: function(clause) {
                var item;
                var newArray = new Array();
    
                // The clause was passed in as a Method that returns a Value
                for (var i = 0; i < this.items.length; i++) {
                    if (clause(this.items[i])) {
                        newArray[newArray.length] = clause(this.items[i]);
                    }
                }
                return new JSLINQ(newArray);
            }
            ...
            JSLINQ.fn.init.prototype = JSLINQ.fn;
            }
    })();
    复制代码

    更多

    从LINQ to JavaScript使用示例中可以看到,Where(),Select()等方法中仅支持匿名函数的方式

    而在.net3.0之后,LINQ的Where等扩展方法中,已经可以使用便捷的lambda表达式

    如果你希望在javascript中也使用lambda表达式语法书写linq,可以关注LINQ for JavaScript,这是另一个提供linq支持的javascript库,项目地址http://linqjs.codeplex.com/

    LINQ for JavaScript调用示例

    复制代码
    var jsonArray = [
        { "user": { "id": 100, "screen_name": "d_linq" }, "text": "to objects" },
        { "user": { "id": 130, "screen_name": "c_bill" }, "text": "g" },
        { "user": { "id": 155, "screen_name": "b_mskk" }, "text": "kabushiki kaisha" },
        { "user": { "id": 301, "screen_name": "a_xbox" }, "text": "halo reach" }
    ]
    // ["b_mskk:kabushiki kaisha", "c_bill:g", "d_linq:to objects"]
    var queryResult = Enumerable.From(jsonArray)
        .Where(function (x) { return x.user.id < 200 })
        .OrderBy(function (x) { return x.user.screen_name })
        .Select(function (x) { return x.user.screen_name + ':' + x.text })
        .ToArray();
    // shortcut! string lambda selector
    var queryResult2 = Enumerable.From(jsonArray)
        .Where("$.user.id < 200")
        .OrderBy("$.user.screen_name")
        .Select("$.user.screen_name + ':' + $.text")
        .ToArray();
    复制代码
     
     
  • 相关阅读:
    LeetCode 42. Trapping Rain Water
    LeetCode 209. Minimum Size Subarray Sum
    LeetCode 50. Pow(x, n)
    LeetCode 80. Remove Duplicates from Sorted Array II
    Window10 激活
    Premiere 关键帧缩放
    AE 「酷酷的藤」特效字幕制作方法
    51Talk第一天 培训系列1
    Premiere 视频转场
    Premiere 暴徒生活Thug Life
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4050371.html
Copyright © 2011-2022 走看看