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

// 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
搜狗浏览器怎么翻译搜狗浏览器怎么翻译Feb 01, 2024 am 11:09 AM

搜狗浏览器怎么翻译?我们平时用搜狗浏览器查阅资料的时候,会遇到一些全是英文的网站,因为看不懂英语对网站浏览起来就很困难,这样也十分的不方便,遇到这种情况没有关系!搜狗浏览器有内置翻译按钮,只要点击一下,搜狗浏览器就会自动帮你翻译整个网页?如果你不会操作的话,小编整理搜狗浏览器怎么翻译的具体方法步骤,不会的话跟着我往下看吧!搜狗浏览器怎么翻译1、打开搜狗浏览器,单击右上角的译字图标2、选择翻译文字类型,然后输入需要翻译的文字3、搜狗浏览器就会自动翻译文字,至此操作完成以上搜狗浏览器怎么翻译的全部内

基于JavaScript构建实时翻译工具基于JavaScript构建实时翻译工具Aug 09, 2023 pm 07:22 PM

基于JavaScript构建实时翻译工具引言随着全球化的需求日益增长,跨国交流和交流的频繁发生,实时翻译工具成为了一种非常重要的应用。我们可以利用JavaScript和一些现有的API来构建一个简单但实用的实时翻译工具。本文将会介绍如何基于JavaScript来实现这个功能,并附有代码示例。实施步骤步骤1:创建HTML结构首先,我们需要创建一个简单的HTML

如何解决搜狗浏览器无法翻译网页的问题如何解决搜狗浏览器无法翻译网页的问题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内置的翻译应用程序执行此操作

Java百度翻译API实现中文与芬兰语互相翻译的技术突破Java百度翻译API实现中文与芬兰语互相翻译的技术突破Aug 05, 2023 am 08:25 AM

Java百度翻译API实现中文与芬兰语互相翻译的技术突破导语:随着全球化进程的不断加速,人们对语言翻译的需求也越来越大。在软件开发领域,实现多语言翻译也变得非常重要。本文将介绍如何使用Java编程语言以及百度翻译API实现中文与芬兰语之间的互相翻译,我们将展示如何通过此技术突破实现人工智能在多语言翻译方面的应用。准备工作:在正式开始实现之前,我们需要进行一些

如何使用PHP开发微信小程序的翻译功能?如何使用PHP开发微信小程序的翻译功能?Oct 26, 2023 am 09:00 AM

如何使用PHP开发微信小程序的翻译功能?随着互联网的发展,语言的交流和沟通变得越来越重要。微信小程序是当前最热门的应用之一,而且拥有全球庞大的用户群体。为了使小程序能够更好地适应多语种用户需求,开发者可以为其添加翻译功能。本文将介绍使用PHP开发微信小程序翻译功能的具体步骤,并提供代码示例。注册微信小程序开发者账号首先,您需要在微信开放平台注册一个开发者账号

PHP开发中如何处理多语言和国际化支持PHP开发中如何处理多语言和国际化支持Oct 09, 2023 pm 02:25 PM

PHP开发中如何处理多语言和国际化支持引言:在当前全球化的时代,为了满足不同语言和文化背景用户的需求,将应用程序进行多语言和国际化支持变得尤为重要。在PHP开发中,我们可以利用一些常见的方法来实现多语言和国际化支持,使得应用程序能够灵活地切换语言,提供更好的用户体验。本文将重点介绍如何在PHP中处理多语言和国际化支持,并提供具体的代码示例。一、使用特定函数和

python百度翻译API实现越南语翻译python百度翻译API实现越南语翻译Aug 08, 2023 pm 12:10 PM

Python百度翻译API实现越南语翻译引言:随着全球交流越来越紧密,语言翻译变得越来越重要。在计算机领域,有许多自动翻译工具可以帮助我们去理解和翻译不同的语言。百度翻译API是其中一种常用的自动翻译工具,它提供了丰富的语种支持。本文将介绍如何使用Python编程语言,结合百度翻译API实现越南语翻译。我们将通过获取百度翻译API的密钥,编写Python代码

See all articles

熱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尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Mac版

SublimeText3 Mac版

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

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器