首頁 web前端 js教程 Underscore.js 1.3.3 中文註解翻譯說明_基礎知識

Underscore.js 1.3.3 中文註解翻譯說明_基礎知識

May 16, 2016 pm 03:52 PM
翻譯 說明

// Underscore.js 1.3.3

// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.

// Underscore is freely distributable under the MIT license.

// Portions of Underscore are inspired or borrowed from Prototype,

// Oliver Steele's Functional, and John Resig's Micro-Templating.

// For all details and documentation:

// http://documentcloud.github.com/underscore

(function() {

 

  // 建立一個全域物件, 在瀏覽器中表示為window物件, 在Node.js中表示global對象

  var root = this;

 

  // 儲存"_"(底線變數)被覆寫先前的值

  // 如果出現命名衝突或考慮到規範, 可透過_.noConflict()方法恢復"_"Underscore佔用之前的值, 並傳回Underscore物件以便重新命名

  var previousUnderscore = root._;

 

  // 建立一個空的物件常數, 便於內部共享使用

  var breaker = {};

 

  // 將內建物件的原型鏈緩存在局部變數, 方便快速調用

  var ArrayProto = Array.prototype, //

  ObjProto = Object.prototype, //

  FuncProto = Function.prototype;

 

  // 將內建物件原型中常用的方法快取在局部變數, 方便快速調用

  var slice = ArrayProto.slice, //

  unshift = ArrayProto.unshift, //

  toString = ObjProto.toString, //

  hasOwnProperty = ObjProto.hasOwnProperty;

 

  // 這裡定義了一些JavaScript 1.6提供的新方法

  // 如果宿主環境中支援這些方法則優先呼叫, 如果宿主環境中沒有提供, 則會由Underscore實現

  var nativeForEach = ArrayProto.forEach, //

  nativeMap = ArrayProto.map, //

  nativeReduce = ArrayProto.reduce, //

  nativeReduceRight = ArrayProto.reduceRight, //

  nativeFilter = ArrayProto.filter, //

  nativeEvery = ArrayProto.every, //

  nativeSome = ArrayProto.some, //

  nativeIndexOf = ArrayProto.indexOf, //

  nativeLastIndexOf = ArrayProto.lastIndexOf, //

  nativeIsArray = Array.isArray, //

  nativeKeys = Object.keys, //

  nativeBind = FuncProto.bind;

 

  // 建立物件式的呼叫方式, 將傳回一個Underscore包裝器, 包裝器物件的原型中包含Underscore所有方法(類似與將DOM物件包裝為一個jQuery物件)

  var _ = function(obj) {

    // 所有Underscore物件在內部均透過wrapper物件進行建構

    return new wrapper(obj);

  };

  // 針對不同的宿主環境, 將Undersocre的命名變數存放到不同的物件中

  if( typeof exports !== 'undefined') {// Node.js環境

    if( typeof module !== 'undefined' && module.exports) {

      exports = module.exports = _;

    }

    exports._ = _;

  } else {// 瀏覽器環境中Underscore的命名變數被掛在window物件中

    root['_'] = _;

  }

 

  // 版本聲明

  _.VERSION = '1.3.3';

 

  // 集合相關的方法(資料和物件的通用處理方法)

  // --------------------

 

  // 迭代處理器, 對集合中每一個元素執行處理器方法

  var each = _.each = _.forEach = function(obj, iterator, context) {

    // 不處理空值

    if(obj == null)

      return;

    if(nativeForEach && obj.forEach === nativeForEach) {

      // 如果宿主環境支援, 則優先呼叫JavaScript 1.6提供的forEach方法

      obj.forEach(iterator, context);

    } else if(obj.length === obj.length) {

      // 對中每一個元素執行處理器方法

      for(var i = 0, l = obj.length; i 中每一個元素執行處理器方法

      for(var key in obj) {

        if(_.has(obj, key)) {

          if(iterator.call(context, obj[key], key, obj) === breaker)

            return;

        }

      }

    }

  };

  // 迭代處理器, 與each方法的差異在於map會儲存每次迭代的返回值, 並作為一個新的陣列返回

  _.map = _.collect = function(obj, iterator, context) {

    // 用於存放回傳值的數組

    var results = [];

    if(obj == null)

      return results;

    // 優先呼叫宿主環境提供的map方法

    if(nativeMap && obj.map === nativeMap)

      return obj.map(iterator, context);

    // 迭代處理集合中的元素

    each(obj, function(value, index, list) {

      // 將每次迭代處理的回傳值儲存到results數組

      results[results.length] = iterator.call(context, value, index, list);

    });

    // 回傳處理結果

    if(obj.length === obj.length)

      results.length = obj.length;

    return results;

  };

  // 將集合中每個元素放入迭代處理器, 並將本次迭代的返回值作為"memo"傳遞到下一次迭代, 一般用於累計結果或連接數據

  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {

    // 透過參數數量檢查是否存在初始值

    var initial = arguments.length > 2;

    if(obj == null)

      obj = [];

    // 優先呼叫宿主環境提供的reduce方法

    if(nativeReduce && obj.reduce === nativeReduce && false) {

      if(context)

        iterator = _.bind(iterator, context);

      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);

    }

    // 迭代處理集合中的元素

    each(obj, function(value, index, list) {

      if(!initial) {

        // 如果沒有初始值, 則將第一個元素作為初始值; 如果被處理的是物件集合, 則預設值為第一個屬性的值

        memo = value;

        initial = true;

      } else {

        // 記錄處理結果, 並將結果傳遞給下次迭代

        memo = iterator.call(context, memo, value, index, list);

      }

    });

    if(!initial)

      throw new TypeError('Reduce of empty array with no initial value');

    return memo;

  };

  // 與reduce作用相似, 將逆向迭代集合中的元素(即從最後一個元素開始直到第一個元素)

  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {

    var initial = arguments.length > 2;

    if(obj == null)

      obj = [];

    // 優先呼叫宿主環境提供的reduceRight方法

    if(nativeReduceRight && obj.reduceRight === nativeReduceRight) {

      if(context)

        iterator = _.bind(iterator, context);

      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);

    }

    // 逆轉集合中的元素順序

    var reversed = _.toArray(obj).reverse();

    if(context && !initial)

      iterator = _.bind(iterator, context);

    // 透過reduce方法處理數據

    return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);

  };

  // 遍歷集合中的元素, 傳回第一個能夠通過處理器驗證的元素

  _.find = _.detect = function(obj, iterator, context) {

    // result存放第一個能夠通過驗證的元素

    var result;

    // 透過any方法遍歷資料, 並記錄經過驗證的元素

    // (如果是在迭代中檢查處理器返回狀態, 這裡使用each方法會更合適)

    any(obj, function(value, index, list) {

      // 如果處理器傳回的結果轉換為Boolean類型後值為true, 則目前記錄並傳回目前元素

      if(iterator.call(context, value, index, list)) {

        result = value;

        return true;

      }

    });

    return result;

  };

  // 與find方法作用類似, 但filter方法會記錄下集合中所有經過驗證的元素

  _.filter = _.select = function(obj, iterator, context) {

    // 用於儲存通過驗證的元素數組

    var results = [];

    if(obj == null)

      return results;

    // 優先呼叫宿主環境提供的filter方法

    if(nativeFilter && obj.filter === nativeFilter)

      return obj.filter(iterator, context);

    // 迭代集合中的元素, 並將透過處理器驗證的元素放到陣列中並傳回

    each(obj, function(value, index, list) {

      if(iterator.call(context, value, index, list))

        results[results.length] = value;

    });

    return results;

  };

  // 與filter方法作用相反, 即傳回沒有經過處理器驗證的元素列表

  _.reject = function(obj, iterator, context) {

    var results = [];

    if(obj == null)

      return results;

    each(obj, function(value, index, list) {

      if(!iterator.call(context, value, index, list))

        results[results.length] = value;

    });

    return results;

  };

  // 如果集合中所有元素都能通過處理器驗證, 則傳回true

  _.every = _.all = function(obj, iterator, context) {

    var result = true;

    if(obj == null)

      return result;

    // 優先呼叫宿主環境提供的every方法

    if(nativeEvery && obj.every === nativeEvery)

      return obj.every(iterator, context);

    // 迭代集合中的元素

    each(obj, function(value, index, list) {

      // 這裡理解為 result = (result && iterator.call(context, value, index, list))

      // 驗證處理器的結果轉換為Boolean型別後是否為true值

      if(!( result = result && iterator.call(context, value, index, list)))

        return breaker;

    });

    return !!result;

  };

  // 檢查集合中任何一個元素在轉換為Boolean型別時, 是否為true值?或透過處理器處理後, 是否值為true?

  var any = _.some = _.any = function(obj, iterator, context) {

    // 如果沒有指定處理器參數, 則預設的處理器函數會傳回元素本身, 並在迭代時透過將元素轉換為Boolean類型來判斷是否為true值

    iterator || ( iterator = _.identity);

    var result = false;

    if(obj == null)

      return result;

    // 優先呼叫宿主環境提供的some方法

    if(nativeSome && obj.some === nativeSome)

      return obj.some(iterator, context);

    // 迭代集合中的元素

    each(obj, function(value, index, list) {

      if(result || ( result = iterator.call(context, value, index, list)))

        return breaker;

    });

    return !!result;

  };

  // 檢查集合中是否有值與目標參數完全匹配(同時將符合資料型別)

  _.include = _.contains = function(obj, target) {

    var found = false;

    if(obj == null)

      return found;

    // 優先呼叫宿主環境提供的Array.prototype.indexOf方法

    if(nativeIndexOf && obj.indexOf === nativeIndexOf)

      return obj.indexOf(target) != -1;

    // 透過any方法迭代集合中的元素, 驗證元素的值和類型與目標是否完全匹配

    found = any(obj, function(value) {

      return value === target;

    });

    return found;

  };

  // 依序呼叫集合中所有元素的同名方法, 從第3個參數開始, 將會被以此傳入到元素的呼叫方法中

  // 回傳一個陣列, 儲存了所有方法的處理結果

  _.invoke = function(obj, method) {

    // 呼叫同名方法時傳遞的參數(從第3個參數開始)

    var args = slice.call(arguments, 2);

    // 依序呼叫每個元素的方法, 並將結果放入數組中返回

    return _.map(obj, function(value) {

      return (_.isFunction(method) ? method || value : value[method]).apply(value, args);

    });

  };

  // 遍歷一個由物件列表組成的陣列, 並傳回每個物件中的指定屬性的值列表

  _.pluck = function(obj, key) {

    // 如果某一個物件中不存在該屬性, 則回傳undefined

    return _.map(obj, function(value) {

      return value[key];

    });

  };

  // 傳回集合中的最大值, 如果不存在可比較的值, 則回傳undefined

  _.max = function(obj, iterator, context) {

    // 如果集合是陣列, 且沒有使用處理器, 則使用Math.max取得最大值

    // 一般會是在一個數組儲存了一系列Number類型的數據

    if(!iterator && _.isArray(obj) && obj[0] === obj[0])

      return Math.max.apply(Math, obj);

    // 對於空值, 直接回傳負無窮大

    if(!iterator && _.isEmpty(obj))

      return -Infinity;

    // 一個暫時的物件, computed用於在比較過程中儲存最大值(暫時的)

    var result = {

      computed : -Infinity

    };

    // 迭代集合中的元素

    each(obj, function(value, index, list) {

      // 如果指定了處理器參數, 則比較的資料為處理器傳回的值, 否則直接使用each遍歷時的預設值

      var computed = iterator ? iterator.call(context, value, index, list) : value;

      // 如果比較值比較上一個值要大, 則將目前值放入result.value

      computed >= result.computed && ( result = {

        value : value,

        computed : computed

      });

    });

    // 返回最大值

    return result.value;

  };

  // 傳回集合中的最小值, 處理過程與max方法一致

  _.min = function(obj, iterator, context) {

    if(!iterator && _.isArray(obj) && obj[0] === obj[0])

      return Math.min.apply(Math, obj);

    if(!iterator && _.isEmpty(obj))

      return Infinity;

    var result = {

      computed : Infinity

    };

    each(obj, function(value, index, list) {

      var computed = iterator ? iterator.call(context, value, index, list) : value;

      computed 之間

      rand = Math.floor(Math.random() * (index 1));

      // 將已經隨機得到的元素放到shuffled陣列結尾

      shuffled[index] = shuffled[rand];

      // 在前面得到的隨機數的位置插入最新值

      shuffled[rand] = 值;

    });

    // 傳回一個陣列, 此陣列中儲存了經過隨機混排的集合元素

    return shuffled;

  };

  // 對集合中元素, 依照特定的欄位或值進行排列

  // 比較Array.prototype.sort方法, sortBy方法支援對物件排序

  _.sortBy = function(obj, val, context) {

    // val應該是物件的屬性, 或一個處理器函數, 如果是一個處理器, 則應該傳回需要進行比較的數據

    var iterator = _.isFunction(val) ? val : function(obj) {

      return obj[val];

    };

    // 呼叫順序: _.pluck(_.map().sort());

    // 呼叫_.map()方法遍歷集合, 並將集合中的元素放到value節點, 將元素中需要進行比較的資料放到criteria屬性中

    // 呼叫sort()方法將集合中的元素依照criteria屬性中的資料進行順序排序

    // 呼叫pluck取得排序後的物件集合並傳回

    return _.pluck(_.map(obj, function(value, index, list) {

      return {

        value : value,

        criteria : iterator.call(context, value, index, list)

      };

    }).sort(function(left, right) {

      var a = left.criteria, b = right.criteria;

      if(a ===

        void 0)

        return 1;

      if(b ===

        void 0)

        return -1;

      return a  b ? 1 : 0;

    }), 'value');

  };

  // 將集合中的元素, 按處理器傳回的key分成多個數組

  _.groupBy = function(obj, val) {

    var result = {};

    // val將轉換為進行分組的處理器函數, 如果val不是一個Function類型的資料, 則將被作為篩選元素時的key值

    var iterator = _.isFunction(val) ? val : function(obj) {

      return obj[val];

    };

    // 迭代集合中的元素

    each(obj, function(value, index) {

      // 將處理器的回傳值當作key, 並將相同的key元素放到一個新的陣列

      var key = iterator(value, index);

      (result[key] || (result[key] = [])).push(value);

    });

    // 傳回已分組的數據

    return result;

  };

  _.sortedIndex = function(array, obj, iterator) {

    iterator || ( iterator = _.identity);

    var low = 0, high = array.length;

    while(low > 1;

      iterator(array[mid]) = 0;

      });

    });

  };

  // 篩選並傳回目前數組中與指定資料不相等的差異數據

  // 此函數一般用於刪除數組中指定的資料, 並得到刪除後的新數組

  // 此方法的作用與without相等, without方法參數形式上不允許資料被包含在數組中, 而difference方法參數形式上建議是數組(也可以和without使用相同形式的參數)

  _.difference = function(array) {

    // 對第2個參數開始的所有參數, 作為一個陣列進行合併(僅合併第一層, 而非深層合併)

    // rest變數儲存驗證資料, 在本方法中用於與原始資料對比

    var rest = _.flatten(slice.call(arguments, 1), true);

    // 將合併後的陣列資料篩選, 篩選條件是目前陣列中不包含參數指定的驗證資料的內容

    // 將符合篩選條件的資料組合為一個新的陣列並傳回

    return _.filter(array, function(value) {

      return !_.include(rest, value);

    });

  };

  // 將每個數組的相同位置的資料作為一個新的二維數組返回, 返回的數組長度以傳入參數中最大的數組長度為準, 其它數組的空白位置使用undefined填充

  // zip方法應該包含多個參數, 且每個參數應該均為數組

  _.zip = function() {

    // 將參數轉換為數組, 此時args是二維數組

    var args = slice.call(arguments);

    // 計算每一個陣列的長度, 並傳回其中最大長度值

    var length = _.max(_.pluck(args, 'length'));

    // 依照最大長度值建立新的空數組, 此數組用於儲存處理結果

    var results = new Array(length);

    // 迴圈最大長度, 在每次迴圈將呼叫pluck方法取得每個陣列中相同位置的資料(依序從0到最後位置)

    // 將獲取到的資料儲存在一個新的陣列, 放入results並返回

    for(var i = 0; i = 0; i--) {

        args = [funcs[i].apply(this, args)];

      }

      // 傳回最後一次呼叫函數的回傳值

      return args[0];

    };

  };

  // 傳回函數, 此函數為呼叫計數器, 當函數被呼叫times次(或超過times次)後, func函數將被執行

  // after方法一般用作非同步的計數器, 例如在多個AJAX請求全部完成後需要執行一個函數, 則可以使用after在每個AJAX請求完成後調用

  _.after = function(times, func) {

    // 若沒有指定或指定無效次數, 則func直接被調用

    if(times  " '

  _.escape = function(string) {

    return ('' string).replace(/&/g, '&').replace(/, '/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(///g, '/');

  };

  // 指定一個物件的屬性, 傳回該屬性對應的值, 如果該屬性對應的是一個函數, 則會執行該函數並傳回結果

  _.result = function(object, property) {

    if(object == null)

      return null;

    // 取得物件的值

    var value = object[property];

    // 若值是函數, 則執行並傳回, 否則將直接傳回

    return _.isFunction(value) ? value.call(object) : value;

  };

  // 新增一系列自訂方法到Underscore物件中, 用於擴充Underscore插件

  _.mixin = function(obj) {

    // obj是一個集合一系列自訂方法的物件, 此處透過each遍歷物件的方法

    each(_.functions(obj), function(name) {

      // 透過addToWrapper函數將自訂方法加入Underscore建構的物件, 用於支援物件式調用

      // 同時將方法加入 _ 本身, 用於支援函數式調用

      addToWrapper(name, _[name] = obj[name]);

    });

  };

  // 取得一個全域唯一識別, 標識從0開始累加

  var idCounter = 0;

  // prefix表示標識的前綴, 如果沒有指定前綴則直接傳回標識, 一般用於給物件或DOM建立唯一ID

  _.uniqueId = function(prefix) {

    var id = idCounter ;

    return prefix ? prefix id : id;

  };

  // テンプレート メソッドで使用される、テンプレートの区切り記号を定義します

  _.templateSettings = {

    //JavaScript 実行可能コードの区切り文字

    評価: //g,

    // 変数の区切り文字を直接出力

    補間 : //g,

    //HTMLを文字列として出力する場合に必要な区切り文字(特殊記号を文字列形式に変換)

    エスケープ : //g

  };

 

  var noMatch = /.^/;

 

  // エスケープ オブジェクトは、相互に変換する必要がある特殊記号と文字列形式の間の対応を記録し、この 2 つが相互に変換されるときにインデックスとして使用されます。

  // まず文字列形式に従って特殊文字を定義します

  var エスケープ = {

    '\' : '\',

    "" : "",

    'r' : 'r'、

    「ん」:「ん」、

    't' : 't',

    'u2028' : 'u2028',

    'u2029' : 'u2029'

  };

  // すべての特殊文字列を走査し、特殊文字をキーとして使用して文字列形式を記録します

  for(エスケープ内の変数 p)

  エスケープ[エスケープ[p]] = p;

  // バックスラッシュ、一重引用符、キャリッジリターン、ラインフィード、タブ、行区切り文字、段落区切り文字など、テンプレート内で置換する必要がある特殊記号を定義します。

  // 文字列内の特殊記号を文字列形式に変換するときに使用されます

  var エスケープ = /\|'|r|n|t|u2028|u2029/g;

  // 文字列形式の特殊記号を反転(置換)するときに使用します

  var unescaper = /\(\|'|r|n|t|u2028|u2029)/g;

 

  //文字列内の特殊記号を反転します

  // テンプレート内で実行する必要がある JavaScript ソース コードは、特殊な記号を使用して反転する必要があります。そうしないと、HTML エンティティまたは文字列の形式で表示されると、構文エラーがスローされます。

  var unescape = 関数(コード) {

    return code.replace(unescaper, function(match,scape) {

      エスケープを返す[エスケープ];

    });

  };

  // テンプレート文字列にデータを埋めるために使用されるアンダースコア テンプレート解析メソッド

  // テンプレートの解析プロセス:

  // 1. テンプレート内の特殊記号を文字列に変換します

  // 2. エスケープフォームタグを解析し、コンテンツを HTML エンティティに解析します。

  // 3. 解析補間フォームタグと出力変数

  // 4. 評価フォームタグを解析し、実行可能な JavaScript コードを作成します

  // 5. データを取得した後にテンプレートに直接入力し、入力された文字列を返す処理関数を生成します

  // 6. パラメータに従って、埋められた文字列または処理関数のハンドルを返します。

  //----------------------

  //テンプレート本体では、引数を通じて 2 つのパラメータ、つまり塗りつぶしデータ (obj という名前) と Underscore オブジェクト (_ という名前) を取得できます。

  _.template = 関数(テキスト、データ、設定) {

    // テンプレート設定。設定項目が指定されていない場合は、templateSettings で指定された設定項目が使用されます。

    設定 = _.defaults(設定 || {}, _.templateSettings);

 

    // テンプレートを実行可能なソース コードに解析し始めます

    var source = "__p ='" text.replace(escaper, function(match) {

      //特殊記号を文字列形式に変換します

      return '\' エスケープ[一致];

    }).replace(settings.escape || noMatch, function(match, code) {

      // エスケープ フォーム タグ <%- %> を解析し、変数に含まれる HTML を _.escape 関数を通じて HTML エンティティに変換します

      return "' n_.escape(" unescape(code) ") n'";

    }).replace(settings.interpolate || noMatch, function(match, code) {

      // 補間フォームタグ <%= %> を解析し、テンプレートの内容を変数として他の文字列と接続すると、変数として出力されます

      return "' n(" unescape(code) ") n'";

    }).replace(settings.evaluate || noMatch, function(match, code) {

      // 評価フォーム タグ <% %> を解析します。実行する必要がある JavaScript コードは評価タグに格納されており、現在の文字列の結合はここで終了し、新しい行で JavaScript 構文として実行されます。が文字列の先頭として再度使用されるため、evaluate タグ内の JavaScript コードは正常に実行できます。

      return "';n" unescape(code) "n;__p ='";

    }) "';n";

    if(!設定.変数)

      ソース = 'with(obj||{}){n' ソース '}n';

    ソース = "var __p='';" "var print=function(){__p =Array.prototype.join.call(arguments, '')};n" ソース "return __p;n";

 

    // 関数を作成し、ソース コードを関数の実行本体として使用し、obj と Underscore をパラメータとして関数に渡します

    var render = new Function(settings.variable || 'obj', '_', ソース);

    // テンプレートのフィルデータが指定されている場合は、テンプレートの内容を置き換えて、置き換えた結果を返します

    if(データ)

      リターンレンダー(データ, _);

    // フィルデータが指定されていない場合は、受信したデータをテンプレートに置き換える関数を返します

    // プログラム内で同じテンプレートを複数回埋め込む場合は、最初の呼び出しでは埋め込みデータを指定せず、処理関数の参照を取得した後、直接呼び出すことをお勧めします。

    var template = 関数(データ) {

      return render.call(this, data, _);

    };

    // 作成したソース コード文字列を関数オブジェクトに追加します。通常はデバッグとテストに使用されます。

    template.source = 'function(' (settings.variable || 'obj') '){n' ソース '}';

    //充填データが指定されていない場合は、処理関数ハンドルを返す

    テンプレートを返す;

  };

  // Underscore オブジェクトのメソッドチェーン操作をサポートします。wrapper.prototype.chain を参照してください。

  _.chain = 関数(obj) {

    return _(obj).chain();

  };

  // アンダースコア オブジェクトは関連メソッドをカプセル化します

  // ---------------

 

  //生データをラップするラッパーを作成します

  // すべての undersocre オブジェクトは、ラッパー関数を通じて内部的に構築およびカプセル化されます。

  //アンダースコアとラッパーの内部関係:

  // - 変数 _ を内部的に定義し、アンダースコア関連のメソッドを _ に追加して、_.bind() などの関数呼び出しをサポートできるようにします。

  // - ラッパー クラスを内部で定義し、_ のプロトタイプ オブジェクトがラッパー クラスのプロトタイプを指すようにします。

  // -アンダースコア関連のメソッドをラッパー プロトタイプに追加すると、作成された _ オブジェクトにはアンダースコア メソッドが含まれます。

  // - Array.prototype 関連のメソッドをラッパー プロトタイプに追加すると、作成された _ オブジェクトには Array.prototype のメソッドが含まれます。

  // -new _() は、実際には、wrapper() オブジェクトを作成して返し、元の配列を _wrapped 変数に格納し、元の値を最初のパラメータとして対応するメソッドを呼び出します。

  var ラッパー = function(obj) {

    //元のデータはラップされたオブジェクトの _wrapped 属性に保存されます

    this._wraped = obj;

  };

  // Underscore のプロトタイプ オブジェクトがラッパーのプロトタイプを指すようにするため、ラッパー プロトタイプのようなメソッドを追加することで、Underscore オブジェクトも同じメソッドを持つようになります。

  _.prototype = ラッパー.プロトタイプ;

 

  // オブジェクトを返します。現在の Underscore がchain() メソッドを呼び出した場合 (つまり、_chain 属性が true の場合)、ラップされた Underscore オブジェクトが返され、それ以外の場合はオブジェクト自体が返されます。

  // 結果関数
登入後複製
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

edge瀏覽器附的翻譯網頁不見了怎麼辦? edge瀏覽器附的翻譯網頁不見了怎麼辦? Mar 14, 2024 pm 08:50 PM

edge瀏覽器自帶了翻譯功能讓用戶們可以隨時隨地的進行翻譯,為用戶們帶來了極大的便利,可也有不少的用戶們表示自帶的翻譯網頁不見了,那edge瀏覽器自帶的翻譯網頁不見了怎麼辦?下面就讓本站來介紹一下edge瀏覽器自備的翻譯網頁不見了怎麼恢復方法吧。  edge瀏覽器自帶的翻譯網頁不見了怎麼恢復方法  1、檢查是否啟用了翻譯功能:在Edge瀏覽器中,點擊右上角的三個點圖標,然後選擇「設定」選項。在設定頁面的左側,選擇“語言”選項。確保“翻譯&rd

看片不怕沒字幕!小米宣布小愛翻譯即時字幕上線日韓文翻譯 看片不怕沒字幕!小米宣布小愛翻譯即時字幕上線日韓文翻譯 Jul 22, 2024 pm 02:11 PM

7月22日消息,今日,小米澎湃OS官微宣布小愛翻譯迎來升級,實時字幕新增日韓語翻譯,無字幕視頻、直播會議實時轉錄翻譯。面對面同聲傳譯支持12種語言互譯,包括中文、英語、日語、韓語、俄語、葡萄牙語、西班牙語、義大利語、法語、德語、印尼語、印地語。以上功能目前僅支援以下三款新機:小米MIXFold4小米MIXFlipRedmiK70至尊版據悉,2021年,小愛同學AI字幕宣布加入日文、韓文翻譯。 AI字幕採用小米自研同聲傳譯技術,提供更快速、穩定且精準的字幕閱讀體驗。 1.官方稱,小愛翻譯不僅能在影音場

搜狗瀏覽器怎麼翻譯 搜狗瀏覽器怎麼翻譯 Feb 01, 2024 am 11:09 AM

搜狗瀏覽器怎麼翻譯?我們平常會用搜狗瀏覽器查閱資料的時候,會遇到一些全是英文的網站,因為看不懂英文對網站瀏覽起來就很困難,這樣也十分的不方便,遇到這種情況沒有關係!搜狗瀏覽器有內建翻譯按鈕,只要點擊一下,搜狗瀏覽器就會自動幫你翻譯整個網頁?如果你不會操作的話,小編整理搜狗瀏覽器怎麼翻譯的具體方法步驟,不會的話跟著我往下看吧!搜狗瀏覽器怎麼翻譯1、開啟搜狗瀏覽器,點選右上角的譯字圖示2、選擇翻譯文字類型,然後輸入需要翻譯的文字3、搜狗瀏覽器就會自動翻譯文字,至此操作完成以上搜狗瀏覽器怎麼翻譯的全部內

谷歌瀏覽器自備翻譯失效如何解決? 谷歌瀏覽器自備翻譯失效如何解決? Mar 13, 2024 pm 08:46 PM

  瀏覽器通常都會自備翻譯功能,這樣在瀏覽外文網站時就不用擔心看不懂啦!谷歌瀏覽器也不例外,但是有用戶發現自己打開谷歌瀏覽器的翻譯功能時沒有反應,失效了,這該如何處理?可以試試小編找到的最新解決方案。  操作教學:  點選右上角三個點,點選設定。  點擊新增語言,新增英文和中文,並為他們做出下面設置,英文設定詢問是否翻譯此語言網頁,中文設定以這種語言顯示網頁,並且中文要移至頂部,才能設定為預設語言。  如果你打開網頁沒有彈出是否翻譯選項,右鍵選擇翻譯中文,ok。

基於JavaScript建立即時翻譯工具 基於JavaScript建立即時翻譯工具 Aug 09, 2023 pm 07:22 PM

基於JavaScript建立即時翻譯工具引言隨著全球化的需求日益增長,跨國交流與交流的頻繁發生,即時翻譯工具成為了一種非常重要的應用。我們可以利用JavaScript和一些現有的API來建立一個簡單但實用的即時翻譯工具。本文將會介紹如何基於JavaScript來實現這個功能,並附有程式碼範例。實作步驟步驟1:建立HTML結構首先,我們需要建立一個簡單的HTML

谷歌瀏覽器翻譯不了中文怎麼回事 谷歌瀏覽器翻譯不了中文怎麼回事 Mar 11, 2024 pm 04:04 PM

谷歌瀏覽器翻譯不了中文怎麼回事?眾所周知Google瀏覽器是自備翻譯的瀏覽器之一,大家在這款瀏覽器裡瀏覽其他國家文字的頁面時,瀏覽器會自動將頁面翻譯成中文,最近有部分用戶表示,自己在瀏覽器網頁的時候無法進行中文翻譯,這個時候我們需要在設定裡進行修復。接下來小編就帶給大家谷歌瀏覽器翻譯不了中文解決辦法,有興趣的朋友快來看看。 Google瀏覽器翻譯不了中文解決方案1、修改本地的hosts文件hosts是一個沒有擴展名的系統文件,可以用記事本等工具打開,主要作用是定義IP地址和主機名的映射關係,是一個映射IP地址

如何解決搜狗瀏覽器無法翻譯網頁的問題 如何解決搜狗瀏覽器無法翻譯網頁的問題 Jan 29, 2024 pm 09:18 PM

搜狗瀏覽器無法翻譯此網頁怎麼辦?搜狗瀏覽器是一款非常好用的多功能瀏覽器,其中的網頁翻譯功能非常強大,能夠幫助我們解決學習工作中的大多數麻煩。不過有些小夥伴卻反應搜狗瀏覽器有著無法翻譯此網頁的問題,這可能是因為操作不當造成的,只需要正確的操作翻譯功能就能解決,下面就由小編為大家帶來搜狗瀏覽器無法翻譯此網頁解決方法。搜狗瀏覽器無法翻譯此網頁解決方法一:1、下載並安裝搜狗瀏覽器2、開啟搜狗瀏覽器3、任意開啟一個英文網站4、網站開啟後,點選右上角的譯字圖示5、選擇翻譯文字類型,然後按一下翻譯目前網頁6

iOS 17.2:如何使用 iPhone 的操作按鈕翻譯語音 iOS 17.2:如何使用 iPhone 的操作按鈕翻譯語音 Dec 15, 2023 pm 11:21 PM

在iOS17.2中,使用iPhone操作按鈕的新自訂翻譯選項克服溝通障礙。繼續閱讀以了解如何使用它。如果您的iPhone帶有操作按鈕,例如iPhone15Pro,Apple的iOS17.2軟體更新為該按鈕帶來了新的翻譯選項,可讓您將即時對話翻譯成多種語言。根據蘋果公司的說法,翻譯不僅準確,而且具有上下文感知能力,確保有效地捕捉細微差別和口語。該功能對於旅行者、學生和任何學習語言的人來說都應該是一個福音。在使用翻譯功能之前,請務必選擇要翻譯的語言。您可以透過Apple內建的翻譯應用程式執行此操作

See all articles